7

Our application has had ApplePay implemented for a number of years. Just recently I hit the button to trigger it to only find out the pay sheet from PKPaymentAuthorizationViewController doesn't appear. It won't slide up in a sandbox (i.e. simulator or device connected to Xcode) environment, but putting a breakpoint shows that it is being created successfully. It's been awhile since I've tested this, but I am suspecting something change with Xcode11 or iOS 13.

My code is pretty standard Apple Pay, but posted below.

        let item = PKPaymentSummaryItem()
        item.label = "Our Label"
        let price = NSDecimalNumber(mantissa: UInt64(totalPrice), exponent: -2, isNegative: false)
        item.amount = price

        items.append(item)

        request.paymentSummaryItems = items

        if let applePayController = PKPaymentAuthorizationViewController(paymentRequest: request) {
            applePayController.delegate = self
            present(applePayController, animated: true)
        }
MarkPowell
  • 16,482
  • 7
  • 61
  • 77
  • 1
    I had the same problem. It seems to be a simulator bug - trying running it on an actual device. – LuLuGaGa Oct 26 '19 at 22:20
  • 1
    Unfortunately, I did do that. Went through the process of creating a sandbox tester, adding a sandbox credit card to device from Apple's list. But, still, even on the device no panel is displayed. Placing breakpoint at "present()" shows that it's being called with a non-nil object but nothing appears. – MarkPowell Oct 26 '19 at 22:39
  • I faced the same issue some what closer to this but i did it in objective c- , if u would like to see i can attach it below – Anjula Serasinghe Oct 29 '19 at 05:04
  • Try clearing your Derived Data folder and rebuild your app see if that helps. Set a breakpoint just before present(applePayController, animated: true) to see if it is getting called or drop a print statement to see if it is getting called. – AD Progress Oct 30 '19 at 11:10
  • Derived Data deleted. Breakpoint added confirmed that the present is getting called and that applePayController is not nil. – MarkPowell Oct 30 '19 at 15:14
  • 3
    It was a simulator bug on Xcode 11 + iOS 13. Just tested on Xcode 11.2 beta 2 and it's now working – Douglas Ferreira Oct 30 '19 at 17:26
  • That's it! Thank you Douglas, if you make that the answer, you'll get yourself 500 reputation points. – MarkPowell Oct 30 '19 at 19:10

3 Answers3

5

This will happen if the merchantID used by your PKPaymentRequest is not listed in mobile.entitlements. Or if the MerchantID is not enabled by your app's provisioning profile.

View Controller

  PKPaymentRequest *request = [[PKPaymentRequest alloc] init];
  
  request.merchantIdentifier = "com.your.app.merchandId"

mobile.entitlements

<dict>
    <key>com.apple.developer.in-app-payments</key>
    <array>
        <string>com.your.app.merchandId</string>
    </array>
</dict>
Lee Irvine
  • 3,057
  • 1
  • 15
  • 12
2

I was facing the same issue, where Apple Pay suddenly stopped working in our app. We've also been supporting this for at least halve a year now.

Using the latest Xcode (Xcode 11.2, Beta 2 (11B44)), it seems to work again.

I'm guessing it was a Xcode bug then. Even though it's not listed in Xcode's release notes for Xcode 11.1 or Xcode 11.2 beta 2.

Jeroen
  • 2,011
  • 2
  • 26
  • 50
1

I have pasted your snippet into my app, which uses ApplePay and I have run it on a test device which is sandboxed and has ApplePay enabled and the ApplePay button didn't work.

What I found it quite surprising.

When you look at the docs for PKPaymentSummaryItem it has only two initialisers:

init(label: String, amount: NSDecimalNumber)
init(label: String, amount: NSDecimalNumber, type:PKPaymentSummaryItemType)

And neither has default values, but you are initialising one with an empty initialiser. Surprisingly there are no errors or warnings and it even comes up in code completion. So I changed the initialiser:

let item = PKPaymentSummaryItem(label: "Our Label",
                                amount: NSDecimalNumber(mantissa: UInt64(totalPrice),
                                                        exponent: -2,
                                                        isNegative: false))
request.paymentSummaryItems = [items]

if let applePayController = PKPaymentAuthorizationViewController(paymentRequest: request) {
    applePayController.delegate = self
    present(applePayController, animated: true)
}

And it works (on device only - not simulator)!

That made my wonder so I just changed your item from let to var and it works as well. I would still go with the documented initialiser.

LuLuGaGa
  • 13,089
  • 6
  • 49
  • 57