Client-Side Implementation

This page shows you how to integrate Apple Pay into your website using the Braintree JavaScript v4 SDK, from checking device support through tokenizing a payment.

Our JavaScript v4 SDK is made to work in tandem with Safari's Apple Pay API Reference.

If you are using our Drop-in UI, follow the Drop-in guide for client-side integration instructions.

PrerequisitesAnchorIcon

Before you integrate Apple Pay, complete the following:

  • Generate a client token, or use a tokenization key, to authorize the Braintree JavaScript v4 SDK.
  • Enable Apple Pay for your merchant account and configure your supported card networks in the Braintree gateway.
  • Include the Braintree JavaScript v4 SDK and Apple Pay component script tags on your page.

Get the SDKAnchorIcon

See the client SDK setup guide for JavaScript v4.

If you are using script tags to load files, be sure to at least include:

  1. HTML
<script src="https://js.braintreegateway.com/web/4.0.0-alpha.0/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/4.0.0-alpha.0/js/apple-pay.min.js"></script>

Initialize Apple PayAnchorIcon

Before you can show the Apple Pay button, confirm that the browser and device support Apple Pay, then set up the button so a customer can start a payment.

Check browser and device capabilitiesAnchorIcon

Apple Pay on the web is supported on the following platforms:

  • iOS 10+. Apple Pay JavaScript is supported on all iOS devices with a Secure Element. It is supported both in Safari and in SFSafariViewController objects.
  • macOS 10.12+. Apple Pay JavaScript is supported in Safari. The user needs an iPhone or Apple Watch that can authorize the payment.

Check that the window.ApplePaySession class exists to confirm Apple Pay is supported and available in the browser. Then, call supportsVersion with the ApplePaySession that you'll use. Finally, call canMakePayments to confirm that the device can make Apple Pay payments:

  1. JavaScript
if (window.ApplePaySession && ApplePaySession.supportsVersion(3) && ApplePaySession.canMakePayments()) {
    // This device supports version 3 of Apple Pay.
}

If the condition passes, the browser supports version 3 of Apple Pay and the device can process payments.

Set up your Apple Pay buttonAnchorIcon

Before showing the Apple Pay button, make sure that an Apple Pay instance can be successfully created and the device can make an Apple Pay payment.

Use ApplePaySession.canMakePayments to confirm that the device can make Apple Pay payments.

  1. Async/Await
async function setupApplePay() {
    if (!window.ApplePaySession) {
        console.error('This device does not support Apple Pay');
    }
    if (!ApplePaySession.canMakePayments()) {
        console.error('This device is not capable of making Apple Pay payments');
    }
    try {
        const clientInstance = await braintree.client.create({
            authorization: 'CLIENT-AUTHORIZATION'
        });
        const applePayInstance = await braintree.applePay.create({
            client: clientInstance
        });
        // Set up your Apple Pay button here
    } catch (err) {
        // Handle error
    }
}

You can find more details on how to set up the Apple Pay button in Apple's developer documentation.

Integrate the JS Apple Pay componentAnchorIcon

Our Apple Pay component interacts with your JavaScript code in three areas:

  1. Creating an ApplePaySession
  2. Handling the onvalidatemerchant callback
  3. Handling the onpaymentauthorized callback

Create anApplePaySessionAnchorIcon

The ApplePaySession object manages the Apple Pay payment process on the web. Create a new ApplePaySession each time a payment is explicitly requested by a customer, such as inside an onclick event. Otherwise, it throws a JavaScript exception.

For each ApplePaySession, create a paymentRequest object, which includes information about payment processing capabilities, the payment amount, and shipping information.

The Braintree JS SDK v4 provides createPaymentRequest, a method for providing four of the properties required for the paymentRequest.

The Braintree gateway loads these values:

  • countryCode
  • currencyCode
  • merchantCapabilities
  • supportedNetworks

We recommend using this method rather than supplying these properties yourself.

Also, you'll need to pass in an object that includes the rest of the paymentRequest properties that you want to use. See the ApplePayPaymentRequest API reference for the properties available.

For example:

  1. JavaScript
const paymentRequest = applePayInstance.createPaymentRequest({
    total: {
        label: 'My Store',
        amount: '19.99'
    },
    // We recommend collecting billing address information, at minimum
    // billing postal code, and passing that billing postal code with
    // all Apple Pay transactions as a best practice.
    requiredBillingContactFields: ["postalAddress"],
    // Request shipping contact information to fulfill the order.
    // You can also request additional fields such as phone number or email.
    requiredShippingContactFields: ["postalAddress"]
});
console.log(paymentRequest.countryCode);
console.log(paymentRequest.currencyCode);
console.log(paymentRequest.merchantCapabilities);
console.log(paymentRequest.supportedNetworks);
const session = new ApplePaySession(3, paymentRequest);

The console output confirms the country code, currency code, merchant capabilities, and supported networks that the SDK loaded from your Braintree gateway configuration.

If you wish, you can still override any of the 4 provided properties by passing them in the argument to createPaymentRequest.

As stated earlier, a new ApplePaySession must be inside of a gesture handler, such as an onclick event or an addEventListener "click" handler.

Creating an ApplePaySession object throws a JavaScript exception if any of the following occur:

  • Any Apple Pay JavaScript API is called from an insecure page.
  • You pass a payment request that isn't valid. Payment requests aren't valid if they contain missing, unknown, or invalid properties, or if they have a negative total.

Set up recurring payments (transition to MPANs)AnchorIcon

See the examples below for setting up a recurring payment request using one of the structures noted below, then add it to the paymentRequest:

  1. recurringPaymentRequest
  2. automaticReloadPaymentRequest
  3. deferredPaymentRequest
const recurringPaymentRequest = {
    paymentDescription: "Payment description of basic recurring payment.",
    regularBilling: {
      label: 'The paymentLabel',
      amount: '10.99',
      'type': 'final',
      paymentTiming: 'recurring',
      recurringPaymentStartDate: "2025-12-31T00:00:00.000Z",
    },
    managementURL: "https://www.merchant.com/update-payment",
};
paymentRequest.recurringPaymentRequest = recurringPaymentRequest;

Additional details can be found in Apple's documentation:

Handle theonvalidatemerchantcallbackAnchorIcon

In the onvalidatemerchant callback, use applePayInstance.performValidation to create a validated Apple Pay session object:

  1. Async/Await
session.onvalidatemerchant = async function (event) {
    try {
        const merchantSession = await applePayInstance.performValidation({
            validationURL: event.validationURL,
            displayName: 'My Store'
        });
        session.completeMerchantValidation(merchantSession);
    } catch (validationErr) {
        // Show an error to the user, for example, 'Apple Pay failed to load.'
        console.error('Error validating merchant:', validationErr);
        session.abort();
    }
};

Handle theonpaymentauthorizedcallbackAnchorIcon

Safari calls the onpaymentauthorized callback with an event object. This object contains a token that you must send to Braintree to get a payment method nonce. It also contains objects representing shipping address (as shippingContact) and billing address (as billingContact), which you can use for your own needs.

Use applePayInstance.tokenize to send this Apple Pay token to Braintree and receive a payment method nonce in return:

  1. Async/Await
session.onpaymentauthorized = async function (event) {
    console.log('Your shipping address is:', event.payment.shippingContact);
    try {
        const payload = await applePayInstance.tokenize({
            token: event.payment.token
        });
        // Send payload.nonce to your server.
        console.log('nonce:', payload.nonce);
        // If requested, address information is accessible in event.payment
        // and may also be sent to your server.
        console.log('billingPostalCode:', event.payment.billingContact.postalCode);
        // After you have transacted with the payload.nonce,
        // call 'completePayment' to dismiss the Apple Pay sheet.
        session.completePayment(ApplePaySession.STATUS_SUCCESS);
    } catch (tokenizeErr) {
        console.error('Error tokenizing Apple Pay:', tokenizeErr);
        session.completePayment(ApplePaySession.STATUS_FAILURE);
    }
};

A successful tokenization logs the payment method nonce and, if requested, the billing postal code, to the console.

Show the payment sheetAnchorIcon

After you have created the session and added the callbacks, call the session's begin method to show the payment sheet. You can only call the begin method when a customer explicitly requests a payment, for example, inside an onclick event. If a customer doesn't explicitly request an action, the begin method throws a JavaScript exception.

  1. JavaScript
session.begin();

After payment is initiated in the browser, the customer authorizes the transaction on either an iPhone or Apple Watch.