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:
In each implemented delegate function of
PKPaymentAuthorizationViewControllerDelegate
that havecompletion
/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 thecompletion
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.