Apple Pay JS completeMerchantValidation results in oncancel event

Hello, I am trying to implement Apple Pay for web on our site and seeing some odd behavior.

I see onvalidatemerchant and completeMerchantValidation being called, but a fairly opaque oncancel event immediately follows.

  • I am able to load the Apple Pay JS script and instantiate an ApplePaySession on the client.
  • my server seems to be communicating effectively with the client, and returns a payment session from https://apple-pay-gateway-cert.apple.com/paymentservices/paymentSession.
  • I have checked the hash of the merchantIdentifier and it matches what is returned in the payment session
  • I have implemented all of the ApplePaySession event handler methods (onvalidatemerchant, onpaymentauthorized, onpaymentmethodselected, etc.) -- only onvalidatemerchant and oncancel are called
  • I have registered both <subdomain>.<mydomain>.com and <mydomain>.com, where the code is deployed
  • I have created a sandbox tester Apple account and added a test card to it, and am running the test from an iPad that is logged into the sandbox tester account
  • the data being passed to completeMerchantValidation is a JS object, not JSON, which threw a TypeError

Here is the deployed code.

applePaySession = new ApplePaySession(3, request);

applePaySession.onvalidatemerchant = async function (event) {
  try {
    const { data } = await getApplePayPaymentSession();
    applePaySession.completeMerchantValidation(data);
  } catch (e) {
    console.log(e);
  }
};

applePaySession.onpaymentauthorized = function(event) {
  const result = {
    "status": ApplePaySession.STATUS_SUCCESS
  };
  applePaySession.completePayment(result);
  applePaySession = null;
};

applePaySession.onpaymentmethodselected = event => {
  // No updates or errors are needed, pass an empty object.
  const update = {};
  applePaySession.completePaymentMethodSelection(update);
};

applePaySession.onshippingmethodselected = event => {
  // No updates or errors are needed, pass an empty object.
  const update = {};
  applePaySession.completeShippingMethodSelection(update);
};
applePaySession.onshippingcontactselected = event => {
  const update = {};
  applePaySession.completeShippingContactSelection(update);
};

applePaySession.oncancel = function(event) {
  console.log('oncancel', event);
};

applePaySession.begin();

Any guidance would be highly appreciated!

I see onvalidatemerchant and completeMerchantValidation being called, but a fairly opaque oncancel event immediately follows. I have registered both ..com and .com, where the code is deployed

If you are receiving what looks like a valid JSON Merchant Session then I would take a look at what domain your code is running on as opposed to what domain is passed to the Apple Pay servers in the Merchant Session request and also what domain is registered against your Merchant ID in the Developer Portal. If they do not match then this could be causing the issue you are seeing. Even if you are using www.yourdomain.com and you registered yourdomain.com this can cause an issue.

For more information on debugging this issues, checkout the Apple Pay on the Web Debugging Guide as it has a lot of information of how to debug each part of this issue.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

I had the same issue where the payment sheet would display then go away without a chance to authorize the transaction. I made sure the domain was verified, the certificate was valid, and that I was actually receiving a response back from the server side request to Apple. Sorting through the process of elimination I came across certain interesting observations:

*If the payment sheet disappeared immediately, it was usually due to a configuration issue with the server side request payload (for example, the "initiativeContext" is the domain with the "www" part when I was not actually using "www" in the web browser). *If the payment sheet disappeared after several seconds, it was usually due to a syntax issue or error in the client side JavaScript. In my case, I was not doing session.onpaymentmethodselected and session.completepaymentmethodselection correctly. So I removed all other Apple specific JS functions except for session.onvalidatemerchant and a subsequent call to session.completeMerchantValidation passing the Apple response from the server side request. It then worked. *If the Apple response from the server side request was in any way (even just the casing) changed from what Apple originally sent it would not work (for instance, "epochtimestamp":1668095263534," vs "epochTimestamp":1668095263534,").

Hope that helps.

Apple Pay JS completeMerchantValidation results in oncancel event
 
 
Q