2017-06-16 66 views
1

使用Swift 3我在我的应用中实施Apple Pay,并尝试将我在paymentAuthorizationViewController中收到的PKPaymentToken发送到银行的API来处理付款,但没有成功。我发送的数据总是被拒绝。Apple Pay和Swift如何发送PKPaymentToken到服务器

银行支持建议我送全payment.token代替payment.token.PaymentData但我不我怎么能做到这一点的原因是payment.tokenPKPaymentToken的实例,因为我知道能不能转换为字符串或编码为base64。

发送令牌的正确方法是什么?

func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, completion: @escaping ((PKPaymentAuthorizationStatus) -> Void)) { 
     self.processPayment(payment: payment, completion: completion) 
    } 

    func processPayment(payment: PKPayment, completion: @escaping ((PKPaymentAuthorizationStatus) -> Void)) { 

     print("Payment token: \(payment.token)") 

     let paymentData=String(data: payment.token.paymentData.base64EncodedData(), encoding: .utf8) 

     var request = URLRequest(url: URL(string: "https://bankapi.com/method")!) 
     request.httpMethod = "POST" 
     let postString = "orderid=\(orderid)&token=\(String(describing: paymentData))&amount=\(price)" 
     print("POST: \(postString)") 
     request.httpBody = postString.data(using: .utf8) 

     let task = URLSession.shared.dataTask(with: request) { data, response, error in 
      guard let data = data, error == nil else {             // check for fundamental networking error 
       print("error=\(String(describing: error))") 
       return 
      } 

      if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {   // check for http errors 
       print("statusCode should be 200, but is \(httpStatus.statusCode)") 
       print("response = \(String(describing: response))") 
      } 

      let responseString = String(data: data, encoding: .utf8) 
      print("responseString = \(String(describing: responseString))") 
      //@TODO check response is failure or success 
      //completion(PKPaymentAuthorizationStatus.failure) 
     } 
     task.resume() 
    } 

upd。 银行服务为我提供了一个Objective C中的例子。 我现在试着在Swift中重现它。

+0

您正在使用哪个支付网关? –

回答

0

好的,现在对我来说很清楚。

 let paymentDataDictionary: [AnyHashable: Any]? = try? JSONSerialization.jsonObject(with: payment.token.paymentData, options: .mutableContainers) as! [AnyHashable : Any] 
       var paymentType: String = "debit" 

       var paymentMethodDictionary: [AnyHashable: Any] = ["network": "", "type": paymentType, "displayName": ""] 

       if #available(iOS 9.0, *) { 
        paymentMethodDictionary = ["network": payment.token.paymentMethod.network ?? "", "type": paymentType, "displayName": payment.token.paymentMethod.displayName ?? ""] 

        switch payment.token.paymentMethod.type { 
         case .debit: 
          paymentType = "debit" 
         case .credit: 
          paymentType = "credit" 
         case .store: 
          paymentType = "store" 
         case .prepaid: 
          paymentType = "prepaid" 
         default: 
          paymentType = "unknown" 
         } 
       } 

    let cryptogramDictionary: [AnyHashable: Any] = ["paymentData": paymentDataDictionary ?? "", "transactionIdentifier": payment.token.transactionIdentifier, "paymentMethod": paymentMethodDictionary] 
    let cardCryptogramPacketDictionary: [AnyHashable: Any] = cryptogramDictionary 
    let cardCryptogramPacketData: Data? = try? JSONSerialization.data(withJSONObject: cardCryptogramPacketDictionary, options: []) 

// in cardCryptogramPacketString we now have all necessary data which demand most of bank gateways to process the payment 

    let cardCryptogramPacketString = String(describing: cardCryptogramPacketData)