javascriptapplepaypayment-request-apiapplepay-web

TypeError when trying to create PaymentRequest with Apple Pay


We're trying to enable Apple Pay on the Web for a web application of ours.

Following examples on the web including the official Apple Pay Demo for the Payment Request API, the following HTML is how we've defined the Apple Pay button:

<script async crossorigin
        src="https://applepay.cdn-apple.com/jsapi/v1.1.0/apple-pay-sdk.js"
        ></script>
...
        <apple-pay-button buttonstyle="black" type="plain" locale="en-US" onclick="startApplePay();"></apple-pay-button>

I have an iPad connected to a Sandbox account with a test card added. I'm serving up my application from a verified domain over SSL with a trusted certificate, and the button does appear on Safari on this device, where it did not before all that criteria was met.

The code called by onclick for that button is this:

    async function startApplePay() {
        alert("startApplePay: " + window.ApplePaySession + ": " + ApplePaySession.canMakePayments());

        if (!window.PaymentRequest) {
            alert("PaymentRequest not available");
            return;
        }

        alert("window.PaymentRequest");

        const applePayMethod = {
            supportedMethods: "https://apple.com/apple-pay",
            data: {
                version: 10,
                merchantIdentifier: "merchant.gov.azmvdnow.payment",
                merchantCapabilities: [
                    "supports3DS"
                ],
                supportedNetworks: [
                    "amex",
                    "discover",
                    "masterCard",
                    "visa"
                ],
                countryCode: "US"
            }
        };

        alert(JSON.stringify(applePayMethod));

        const paymentDetails = {
            total: {
                label: "Demo (Card is not charged)",
                amount: { value: "27.50", currency: "USD" }
            },
            displayItems: [{
                label: "Item 1",
                amount: { value: "27.50", currency: "USD" }
            }]
        };

        alert(JSON.stringify(paymentDetails));

        try {
            const request = new PaymentRequest(applePayMethod, paymentDetails);
        }

        catch (e) {
            alert(e + ": " + e.stack + ": " + e.cause);
        }
    }

(I've tried different version values as well, back to version 3 that the linked example uses.)

The alerts indicate we're in the path where the capabilities exist:

startApplePay: function ApplePaySession() { [native code] }: true

Then:

window:PaymentRequest

Then two sets of:

{ ... JSON matching what was set }

indicating 'JSON.stringify()' had no problems.

Just creating the request object, without yet trying to perform the next steps with it, the catch fires with the following:

TypeError: Type error: PaymentRequest@[native code] startApplePay@https:-myurl-:319:47 onclick@https://-myurl-:606:14:undefined

I'm brand new to this, so I figure I'm missing some basic initial step, but I can't find anything searching on this error. And since I don't yet have access to Mac, I can't do any more sophisticated browser debugging/troubleshooting.

Edit: I now have a Mac that I can debug in the browser with, but so far I'm not seeing anything that helps me figure this out.


Solution

  • The annoyingly tiny answer was that the first argument to the PaymentRequest constructor is supposed to be an array.

                const request = new PaymentRequest([ applePayMethod ], paymentDetails);
    

    (Or, make the variable an array from the start. The two linked examples use both approaches, I missed the array brackets in following the first one.)