Using Swift 3 I'm implementing Apple Pay in my app and trying to send PKPaymentToken which I receive in paymentAuthorizationViewController
to bank's API to process payment but without success. The data which I send is always rejected.
Bank support suggests me to send the whole payment.token
instead of payment.token.PaymentData
but I don't how can I do that cause payment.token
is the instance of PKPaymentToken and as I know cannot be converted to string or encoded to base64.
What is the correct way to send the token?
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. bank service provided me an example in Objective C. I now try to reproduce it in Swift.
To decrypt the token, import the . pem files and create a new PaymentToken with the token from Apple Pay. Then decrypt using the keys. You can then use those decrypted values with your payment processor of choice (Stripe, Braintree, et al) to process payments from Apple Pay.
The payment processing certificate is used to encrypt the Apple Pay token. The payment processing certificate is valid for 25 months from activation. If you do not replace the CSR and activate the new certificate prior to the expiration date, all Apple Pay transactions will fail.
Ok there is now clear for me.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With