I have implemented apple pay in my iOS application using Passkit framework. I did all of these things fully to set up apple pay. I am using sandbox account. I added cards in Wallet application and these cards are testing cards which I copied from this link. This code I am using:
print("\(((self.grandTotalLabel.text!).replacingOccurrences(of: "$", with: "")))")
let paymentNetworks = [PKPaymentNetwork.amex]
if PKPaymentAuthorizationViewController.canMakePayments(usingNetworks: paymentNetworks){
paymentRequest.supportedNetworks = paymentNetworks
paymentRequest.merchantCapabilities = .capability3DS
paymentRequest.requiredShippingAddressFields = [.all]
paymentRequest.paymentSummaryItems = self.itemToSell(shipping: 10.0)
let sameDayShipping = PKShippingMethod(label: "Same day divilery", amount: 12.99)
sameDayShipping.detail = "Same day divilery Detail"
sameDayShipping.identifier = "sameDay"
let twDaysShipping = PKShippingMethod(label: "Two days divilery", amount: 4.99)
twDaysShipping.detail = "Two days divilery Detail"
twDaysShipping.identifier = "twoDays"
let freeShipping = PKShippingMethod(label: "Free shipping divilery", amount: 0.0)
freeShipping.detail = "Free shipping divilery Detail"
freeShipping.identifier = "freeShipping"
// paymentRequest.shippingMethods = [sameDayShipping,twDaysShipping, freeShipping]
let applePayVC = PKPaymentAuthorizationViewController(paymentRequest: paymentRequest)
applePayVC?.delegate = self
self.present(applePayVC!, animated: true) {
print("ApplePayViewcontroller")
}
}
else{
print("Please set up for apple pay")
}
func itemToSell(shipping:Float) -> [PKPaymentSummaryItem]{
print(Double("\(((self.grandTotalLabel.text!).replacingOccurrences(of: "$", with: "")))") as Any)
let dishItems = PKPaymentSummaryItem(label: "FoodKonnect", amount: NSDecimalNumber(string: "21.00"))
let discount = PKPaymentSummaryItem(label: "Discount", amount: 1.0)
let shipping = PKPaymentSummaryItem(label: "Shipping", amount: NSDecimalNumber(string: "\(shipping)"))
let totalAmount = dishItems.amount.adding(discount.amount)
let totalPrice = PKPaymentSummaryItem(label: "FoodKonnect application", amount: totalAmount)
return [dishItems, discount,shipping, totalPrice]
}
These all delegates I am using of PKPaymentAuthorizationViewControllerDelegate
:
extension CartViewController:PKPaymentAuthorizationViewControllerDelegate{
func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {
controller.dismiss(animated: true, completion: nil)
}
// @available(iOS 11.0, *)
func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didSelectShippingContact contact: PKContact, completion: @escaping (PKPaymentAuthorizationStatus, [PKShippingMethod], [PKPaymentSummaryItem]) -> Void) {
print("\(#function)")
}
@available(iOS 11.0, *)
func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didSelect shippingMethod: PKShippingMethod, handler completion: @escaping (PKPaymentRequestShippingMethodUpdate) -> Void) {
print("\(#function)")
}
@available(iOS 11.0, *)
func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) {
print("\(#function)")
}
}
Apple pay viewcontroller is showing and this screen is showing with a processing circle view.
But after few seconds I got this error message:
I am not able to figure what exactly I am doing wrong.
In each implemented delegate function of PKPaymentAuthorizationViewControllerDelegate
that have completion
/handler
you must call that block with the appropriate parameters and most importantly with appropriate status.
On iOS 11 not calling the block within (approximately) 15-20s, the iOS is killing the Payment with the error you are seeing. On iOS 10, it will let you spin on Processing
indefinitely until the completion
blocks are called.
I had the same issue and it turned out that I was not calling the handler
block at all in one of the edge cases.
Recently I faced the same issue and I found a solution.
Everything is fine only we have to update the handler with the success or failure like this:
func paymentAuthorizationViewController(_ controller:
PKPaymentAuthorizationViewController, didAuthorizePayment payment:
PKPayment, handler completion: @escaping
(PKPaymentAuthorizationResult) -> Void) {
If the payment data are nil or not check for simulator always its nil :
do {
let jsonResponse = try JSONSerialization.jsonObject(with: paymentStatus.paymentData, options: .mutableContainers)
print(jsonResponse as! NSDictionary)
completion(PKPaymentAuthorizationResult(status: .success, errors: nil))
}
catch let error
{
print(error)
completion(PKPaymentAuthorizationResult(status: .failure, errors: nil))
}
It should solve the problem.
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