Apple Pay allows shoppers to pay with a credit or debit card using their Apple devices. Apple Pay is compatible with these devices.
Note: When returning the details of an order the actual credit or debit card is shown as payment method (e.g. "MAESTRO") instead of Apple Pay.
The used (sample) scripts can be downloaded from the sandbox environment:
For Apple Pay the following prerequisites need to be fulfilled:
Apple Pay is available in the menu if the prerequisites are fulfilled. No additional information is required in the create-request.
This rest of this page covers how to implement Apple Pay on your own checkout page.
Besides, implementing two additional requests (Initialize an Apple Pay session and Authorize an Apple Pay payment) to the Payment Service, the Apple Pay JS API has to be used.
Apple Pay can only be used on your own checkout page after you have been enrolled as merchant at Apple. Part of the enrollment is the verification of your domain by Apple. We handle setting up the required IDs and certificates.
Contact us for details on the Enrollment as Apple Pay Merchant.
Apple has described how to display the Apple Pay Button using CSS templates in Safari.
Apple has strict requirements on the look, size and placement on the Apple Pay button. See the Human Interface Guidelines > Apple Pay for more details.
The following diagram shows the payment flow when using Apple Pay on your checkout page.
An order has to be created before Apple Pay can be used. (See Create a new order.)
Before showing the Apple Pay button to the shopper the availability of Apple Pay needs to be checked.
For more details see: Checking for Apple Pay Availability
Example javascript:
function canMakePaymentsWithApplePay() {
if (window.ApplePaySession) {
try {
if (ApplePaySession.canMakePayments()) {
return true;
} else {
console.log("Can not make Apple Pay payments.");
}
}
catch (e) {
console.log("Starting an Apple Pay session requires an secure document.", e);
}
} else {
console.log("Apple Pay JS API is not available.");
}
return false;
}
After the shopper clicks on the Apple Pay button a session has to be created specifying the payment details.
The following payments details need to be provided in the request:
Field | Type | M | Description |
---|---|---|---|
countryCode | Country | M | The country of the merchant. |
currencyCode | Currency | M | The currency for the payment. |
supportedNetworks | String[] | M | The payment networks supported by the merchant. The supported values are 'visa', 'masterCard', 'maestro', 'vPay'. (Depending on the payment methods enabled on your account.) |
merchantCapabilities | String[] | M | The payment capabilities supported by the merchant. The only supported value is 'supports3DS'. |
total | Block | M | A line item representing the total for the payment. |
+ label | String(1, 128) | M | The name of the shop that is shown to the shopper. |
+ amount | float | M | The payment amount in major unit, i.e. including a decimal point. |
The supported networks can be determined using: List payment methods of an Order
For more details see: Creating an Apple Pay Session
Example javascript:
var request = {
countryCode: 'NL',
currencyCode: 'EUR',
supportedNetworks: ['visa', 'masterCard', 'maestro', 'vPay'],
merchantCapabilities: ['supports3DS'],
total: { label: 'My Shop', amount: '10.00' }
};
var session = new ApplePaySession(4, request);
After the session is created, call its begin method to show the payment sheet.
Example javascript:
session.begin()
Apple initiates the validation of the merchant when the payment sheet is shown using the On Validate Merchant event. The event parameter contains the validation URL attribute, which should be send to the Payment System in the Initialize an Apple Pay session request.
The returned response is the opaque Apple Pay merchant session in string format. This string needs to be converted to a JavaScript object before it can be passed to the Apple device.
If successful the returned merchant session must be used to complete the merchant validation. Otherwise, the session must be aborted.
Example javascript:
session.onvalidatemerchant = function(event) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState === 4) {
if (this.status === 201) {
session.completeMerchantValidation(JSON.parse(this.responseText));
} else {
session.abort();
}
}
};
xhttp.open("POST", baseUrl + "/initialize", true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.send('{ "validationUrl":"' + event.validationURL + '"' +
', "displayName": "' + merchantDisplayName + '"' +
', "domainName": "' + window.location.hostname + '"}');
};
Apple initiates the authorization of the payment when the shopper authenticates the payment with Touch ID or Face ID, using the On Payment Authorized event. The event parameter contains the payment attribute containing the encrypted card details. The payment attribute should be send as-is to the Payment System in the Authorize an Apple Pay payment request.
After the Payment System authorizes the payment the result must be used to complete the payment. This will show the result of the authorization on the payment sheet, and close the payment sheet after 2 minutes automatically.
Example javascript:
session.onpaymentauthorized = function(event) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState === 4) {
try {
if (this.status === 200) {
session.completePayment({status: ApplePaySession.STATUS_SUCCESS});
} else {
session.completePayment({status: ApplePaySession.STATUS_FAILURE});
}
}
catch (e) {
// Ignore, canceling during the authorization will invalidate the session object,
// resulting in an InvalidAccessError.
} finally {
setTimeout(function() { window.pollOrderStatus(); }, 2000);
}
}
};
xhttp.open("POST", baseUrl + "/authorize", true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.send(JSON.stringify(event.payment));
};
Note: The window.pollOrderStatus();
method is only available in the menu, and used to get the details of the order
and redirect the shopper back to the webshop if appropriate. For your own menu, you should implement a similar function.
The poll method is called after a 2000 ms delay. In our experience this is necessary to let the payment sheet close
automatically reliable. Without this delay the payment sheet did not close on all devices.
When the shopper dismisses the payment sheet instead of authenticating the payment, the On Cancel event is called by Apple.
Example javascript:
session.oncancel = function() {
window.pollOrderStatus();
};
The Payment System sends status change notifications to the customer service agent application during the authorization of the payment, which should be used to get the order details from the Payment System.
The order details should be used to determine if the shopper has paid the order or that another payment attempt can be made by the shopper.
Below is the full JavaScript that is used by the menu to support Apple Pay.
/**
* Check that the Apple Pay JS API is available in the browser,
* and that payments with Apple Pay are possible.
*
* @returns {boolean} true if Apple Pay payments are possible, false otherwise.
* @see <a href="https://developer.apple.com/documentation/apple_pay_on_the_web/apple_pay_js_api/checking_for_apple_pay_availability">Checking for Apple Pay Availability</a>
*/
function canMakePaymentsWithApplePay() {
if (window.ApplePaySession) {
try {
if (ApplePaySession.canMakePayments()) {
return true;
} else {
console.log("Can not make Apple Pay payments.");
}
}
catch (e) {
console.log("Starting an Apple Pay session requires an secure document.", e);
}
} else {
console.log("Apple Pay JS API is not available.");
}
return false;
}
/**
* Authorize an Apple Pay payment.
*
* @param merchantKey The merchant key.
* @param merchantDisplayName The name of the merchant to display.
* @param orderKey The order key.
* @param serverUrl The url of the ApplePayServer.
* @param request The <a href="https://developer.apple.com/documentation/apple_pay_on_the_web/applepaypaymentrequest">ApplePayPaymentRequest</a> as JSON
* @see <a href="https://developer.apple.com/documentation/apple_pay_on_the_web/apple_pay_js_api">Apple Pay JS API</a>
*/
function authorizeApplePayPayment(merchantKey, merchantDisplayName, orderKey, serverUrl, request) {
if (!canMakePaymentsWithApplePay()) return;
var baseUrl = serverUrl + "/mobile/applepay/merchants/" + merchantKey + "/payments/" + orderKey;
var session = new ApplePaySession(4, JSON.parse(request));
/**
* An event handler that is called when the payment sheet is displayed.
*
* @param event ApplePayValidateMerchantEvent, An event object that contains the validation URL (event.validationURL).
* @see <a href="https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778021-onvalidatemerchant">ApplePaySession.onvalidatemerchant</a>
*/
session.onvalidatemerchant = function(event) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState === 4) {
if (this.status === 201) {
session.completeMerchantValidation(JSON.parse(this.responseText));
} else {
session.abort();
}
}
};
xhttp.open("POST", baseUrl + "/initialize", true);
xhttp.setRequestHeader("Content-type", "application/json");
// Send the validation URL as received from the Apple device
// Send the text for on the pay button
// Send the current domain name of the website/shop
xhttp.send('{ "validationUrl":"' + event.validationURL + '"' +
', "displayName": "' + merchantDisplayName + '"' +
', "domainName": "' + window.location.hostname + '"}');
};
/**
* An event handler that is called when a new payment method is selected.
*
* Note: event.completePaymentMethodSelection() requires an ApplePayPaymentMethodUpdate instance as parameter with a newTotal.
*
* @param event ApplePayPaymentMethodSelectedEvent, An event object that contains the payment method (event.paymentMethod).
* @see <a href="https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778013-onpaymentmethodselected">ApplePaySession.onpaymentmethodselected</a>
*/
// session.onpaymentmethodselected = function(event) {
// var update = {newTotal_to_be_defined};
// event.completePaymentMethodSelection(update);
// };
/**
* An event handler that is called when a shipping method is selected.
*
* Note: event.completeShippingContactSelection() requires an ApplePayShippingMethodUpdate instance as parameter with a newTotal.
*
* @param event ApplePayShippingMethodSelectedEvent, An event object that contains the shipping method (event.shippingMethod).
* @see <a href="https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778028-onshippingmethodselected">ApplePaySession.onshippingmethodselected</a>
*/
// session.onshippingcontactselected = function(event) {
// var update = {newTotal_to_be_defined};
// event.completeShippingContactSelection(update);
// };
/**
* An event handler that is called when a shipping method is selected.
*
* Note: event.completeShippingMethodSelection() requires an ApplePayShippingMethodUpdate instance as parameter with a newTotal.
*
* @param event ApplePayShippingMethodSelectedEvent, An event object that contains the shipping method (event.shippingMethod).
* @see <a href="https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778028-onshippingmethodselected">ApplePaySession.onshippingmethodselected</a>
*/
// session.onshippingmethodselected = function(event) {
// var update = {newTotal_to_be_defined};
// event.completeShippingMethodSelection(null);
// };
/**
* event handler that is automatically called when the payment UI is dismissed.
*
* @see <a href="https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778029-oncancel">oncancel</a>
*/
session.oncancel = function() {
window.pollOrderStatus();
};
/**
* An event handler that is called when the user has authorized the Apple Pay payment with Touch ID, Face ID, or passcode.
*
* @param event ApplePayPaymentAuthorizedEvent, An event object that contains the token used to authorize a payment (event.payment).
* @see <a href="https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778020-onpaymentauthorized">ApplePaySession.onpaymentauthorized</a>
*/
session.onpaymentauthorized = function(event) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState === 4) {
try {
if (this.status === 200) {
session.completePayment({status: ApplePaySession.STATUS_SUCCESS});
} else {
session.completePayment({status: ApplePaySession.STATUS_FAILURE});
}
}
catch (e) {
// Ignore, canceling during the authorization will invalidate the session object,
// resulting in an InvalidAccessError.
} finally {
setTimeout(function() { window.pollOrderStatus(); }, 2000);
}
}
};
xhttp.open("POST", baseUrl + "/authorize", true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.send(JSON.stringify(event.payment));
};
session.begin();
}