Web Integration


On this page

Check the availability

From your frontend code, you can check if Apple Pay JS is available and there some active cards.

if (window.ApplePaySession) {
   let merchantIdentifier = 'example.com.store';
   let promise = ApplePaySession.canMakePaymentsWithActiveCard(merchantIdentifier);

    promise.then(function (canMakePayments) {
        if (canMakePayments) {
            // Display Apple Pay Button
        }
    });
}

Alternativley, you can only check if the device supports Apple Pay as follows:

if (window.ApplePaySession && ApplePaySession.canMakePayments()) {
    // Display Apple Pay Button
}

Apple Pay is available on the following platforms:

  • Safari iOS 10 and later
  • Safari macOS 10.12 and later

Apple Pay Button

You can follow the detailed guide on how to display and customize your Apple Pay Button, but here is a quick version:

<div class="apple-pay-button"></div>

You need to style your button with the following CSS, but keep in mind this is only supported on Safari, so please follow the earlier step in verifying that ApplePaySession is supported and able to make payments before showing the button.

.apple-pay-button {
    display: inline-block;
    -webkit-appearance: -apple-pay-button;
    -apple-pay-button-type: plain;
    -apple-pay-button-style: black;
}

You need to add an event handler for click, keep in mind ApplePaySession can only be initiated with a user gesture, you may not create the session without a user initiated event like click.

const button = document.querySelector('.apple-pay-button');
button.addEventListener('click', function () {
    // Place your logic here
    // Follow in "Initiate Apple Pay Session"
});

Initiate Apple Pay Session

When the user clicks the button, we need to initiate an Apple Pay session and display the payment sheet. This can simply be done with the following:

const request = {
    currencyCode: 'SAR',
    countryCode: 'SA',
    supportedCountries: ['SA'],
    total: { label: "My Awesome Shop", amount: '1.00' },
    supportedNetworks: ['masterCard', 'visa', 'mada'],
    merchantCapabilities: ['supports3DS', 'supportsCredit', 'supportsDebit']
};

const session = new ApplePaySession(6, request);

session.onvalidatemerchant = event => {}; // See "Providing Merchant Validation"
session.onpaymentauthorized = event => {}; // See "Authorizing Payment"

session.begin();

Providing Merchant Validation

When the payment sheet shows up and before the user is asked to authenticate the payment (either by Face ID or Touch ID), Apple needs to verify the merchant identity, thus the event onvalidatemerchant is dispatched. Here is how we can provide merchant validation:

session.onvalidatemerchant = event => {
    let merchantBackendUrl = 'https://awesome-shop.com/apple-pay/merchant-validation';
    let body = {
        'validationUrl': event.validationURL
    };

    fetch(merchantBackendUrl, {
        method: 'post',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body)
    })
    .then(response => response.json())
    .then(merchantSession => session.completeMerchantValidation(merchantSession))
    .catch(error => console.error(error)); // We need to handle the error instead of just logging it to console.
};

Note: in .then(response => response.json()) we try to parse the response as JSON, and this will fail if the header 'Content-Type': 'application/json' is not returned from by the server.

To implement merchant validation in your backend, you first need to generate a “Merchant Identity Certificate” from your Apple Developer account then follow this guide in order to complete the process: Requesting an Apple Pay Payment Session.

Note: Apple’s response should be returned as is to the front-end code.

Authorizing Payment

Now after merchant validation is completed, the event onpaymentauthorized will be dispatched with an encrypted payment token. We need to send this payment token to Moyasar in order to complete the transaction.

We will be using Moyasar API for this.

session.onpaymentauthorized = event => {
    const token = event.payment.token;
    
    let body = {
        'amount': 100, // 100 Halalas == 1.00 SAR
        'description': 'My Awsome Order #1234',
        'publishable_api_key': 'pk_live_1234',
        'source': {
            'type': 'applepay',
            'token': token
        }
    };

    fetch('https://api.moyasar.com/v1/payments', {
        method: 'post',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body)
    })
    .then(response => response.json())
    .then(payment => {
        if (!payment.id) {
            // TODO: Handle validation or API authorization error
        }

        if (payment.status != 'paid') {
            session.completePayment({
                status: ApplePaySession.STATUS_FAILURE,
                errors: [
                    payment.source.message
                ]
            });

            return;
        }

        // TODO: Save payment to your backend and complete your business logic

        session.completePayment({
            status: ApplePaySession.STATUS_SUCCESS
        });
    })
    .catch(error => {
        session.completePayment({
            status: ApplePaySession.STATUS_FAILURE,
            errors: [
                error.toString()
            ]
        });
    });
};

Using Moyasar Form

Instead of manually implementing Apple Pay within your website, you can use Moyasar Form which will take care of all the previous details.

More Resources

For more resources on Apple Pay development, please visit Apple Developer Documentation.

Please visit the Acceptable Use Guidelines for more information about what Apple Pay may be used for and read through the Human Interface Guidelines.


Last Modified : Sep 2021