Apple Pay 和 Swift 如何将 PKPaymentToken 发送到服务器
Apple Pay and Swift how do I send PKPaymentToken to server
使用 Swift 3 我正在我的应用程序中实施 Apple Pay 并尝试将我在 paymentAuthorizationViewController
中收到的 PKPaymentToken 发送到银行的 API 以处理付款但没有成功。我发送的数据总是被拒绝
银行支持建议我发送整个 payment.token
而不是 payment.token.PaymentData
但我不知道我该怎么做 因为 payment.token
是 的实例PKPaymentToken 并且据我所知无法转换为字符串或编码为 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()
}
更新
银行服务在 Objective C 中为我提供了示例。
我现在尝试在 Swift.
中重现它
好的,现在我明白了。
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)
使用 Swift 3 我正在我的应用程序中实施 Apple Pay 并尝试将我在 paymentAuthorizationViewController
中收到的 PKPaymentToken 发送到银行的 API 以处理付款但没有成功。我发送的数据总是被拒绝
银行支持建议我发送整个 payment.token
而不是 payment.token.PaymentData
但我不知道我该怎么做 因为 payment.token
是 的实例PKPaymentToken 并且据我所知无法转换为字符串或编码为 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()
}
更新 银行服务在 Objective C 中为我提供了示例。 我现在尝试在 Swift.
中重现它好的,现在我明白了。
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)