Apple Pay integration

For Apple Pay to function correctly, you must have a verified Viva Wallet account which is active and able to receive payments. You need also to do the following:

  1. Download the Apple Pay verification file containing the domain association key.
  2. Create a .well-known directory on your server.
  3. After removing its .txt file extension, upload the domain association verification file to the .well-known directory.

You should then visit our live chat and ask for Apple Pay to be enabled on your account. The information you need to give us is your Viva Wallet merchant ID and the fully qualified domain name where your Native Checkout v2 page will be hosted.

To use Apple Pay, customers need to have a payment method from a supported bank or payment card provider listed at the Apple Pay support page , and a compatible Apple device .

Before you start

To accept Apple Pay, you must ensure that each page of your website is served over SSL (HTTPS). You also need to be aware that Apple Pay works only in the Safari browser (iOS and macOS) on an Apple device with Bluetooth enabled. In all other browsers and operating systems the Pay with Apple Pay button will not be visible to customers. 

Setup instructions

In order to enable Apple Pay in your online store you need to complete the following steps: 

Step 1: Add the button to your page

<div id="ApplePay" class="apple-pay-button apple-pay-button-text-buy apple-pay-button-black-with-text" lang=en></div>

Step 2: Add the following style rules to your stylesheet

.apple-pay-button {
    width: 250px;
    height: 40px;
    display: inline-block;
    -webkit-appearance: -apple-pay-button;
    cursor: pointer;
}
.apple-pay-button-black-with-text {
    -apple-pay-button-style: black;
}
.apple-pay-button-text-buy {
    -apple-pay-button-type: buy;
}
@media only screen and (max-width: 600px) {
    .apple-pay-button {
        width: 90%;
        height: 50px;
    }

Step 3: Add the following script to your page

Make sure you replace [4-digit code of your payment source] below with your own source code, the same as the one you added for Native Checkout v2. Define backendValidateURL as the URL to the validate merchant endpoint on your backend. Define backendPayURL as the URL to the Viva Wallet transaction endpoint on your backend.

/**
 * Options related to the merchant's Viva Wallet account.
 */
let vivaWalletOptions = {
    sourceCode: '[4-digit code of your payment source]',
    providerId: 'applepay'
}

/**
 * The following object hides/shows the Apple Pay button depending on whether the customer is using an Apple Pay compatible device/browser.
 */
let applePayButtonDisplayController = (function () {
    return {
        appleButtonId: 'ApplePay',
        displayApplePayButton: function () {
            document.getElementById(applePayButtonDisplayController.appleButtonId).style.display = 'block'
        },
        hideApplePayButton: function () {
            document.getElementById(applePayButtonDisplayController.appleButtonId).style.display = 'none'
        }
    }
})();

/**
 * The following object contains all the Apple Pay related logic and implements the merchant validation and the processing of the payment transaction.
 */
let applePayController = (function (btnDisplayController) {

    let backendValidateURL = 'The URL to the validate merchant endpoint on your backend';
    let backendPayURL = 'The URL to the Viva Wallet transaction endpoint on your backend';


    //// High level payment configuration options.
    let paymentDetails = {
        total: {
            "label": "COMPANY, INC.",
            "type": "final",
            "amount": "16.06"
        },
        countryCode: "BE",
        currencyCode: "EUR",
        merchantCapabilities: ["supports3DS"],
        supportedNetworks: ["amex", "masterCard", "visa", "jcb"]
    };

    /**
     * Checks if Apple Pay is available in the current environment.
     * @return {boolean} Boolean to check if Apple Pay is available
     */
    let isApplePayAvailable = function () {
        return window.ApplePaySession && ApplePaySession.canMakePayments()
    }

    /**
     * Starts the Apple Pay session using the paymentDetails options configured above.
     */
    let startApplePaySession = function (paymentDetails) {
        let applePaySession = new ApplePaySession(6, paymentDetails);
        handleApplePayEvents(applePaySession);
        applePaySession.begin()
    }

    /**
 * This method calls your backend server with the Apple Pay validation URL.
 * On the backend, a POST request will be done to this URL with the Apple Pay certificates
 * and the outcome will be returned
 *
 * @param {string} appleUrl The Apple Pay validation URL generated by Apple
 * @param {function} callback Callback function used to return the server call outcome
 *
 * @return {object} The session payload
 *
 */
    let validateApplePaySession = function (appleUrl, callback) {

        let payload = {
            providerId: vivaWalletOptions.providerId,
            sourceCode: vivaWalletOptions.sourceCode,
            validationUrl: appleUrl
        };

        // We're using jQuery to do a POST request to the backend but any HTTP client can be used
        $.ajax({
            url: backendValidateURL,
            type: "POST",
            data: JSON.stringify(payload),
            contentType: "text/plain"
        }).done(function (response) {
            callback(true, response)
        }).fail(function (response) {
            callback(false, response)
        });

    }

    // here we talk to our backend to send the Apple Pay payload and return the transaction outcome
    let performApplePayTransaction = function (paymentDetails, callback) {
        // We're using jQuery to do a POST request to the backend but any HTTP client can be used

        let customerData = {
            email: "applepaydemo@vivawallet.com",
            phone: "+1230203202",
            fullname: "Apple Demo",
            requestLang: "en",
            countryCode: "BE"
        }

        let payload = {
            customer: customerData,
            currencyCode: 978, //ISO 4217 code for Euro.
            customerTrns: "Apple Pay Transaction Demo",
            merchantTrns: "This transaction is an Apple Pay transaction",
            installments: 1,
            chargeToken: JSON.stringify(paymentDetails.token),
            sourceCode: vivaWalletOptions.sourceCode,
            tipAmount: 0,
            amount: 1606
        }

        $.ajax({
            url: backendPayURL,
            type: "POST",
            data: JSON.stringify(payload),
            contentType: "text/plain"
        }).done(function (response) {
            callback(true, response)
        }).fail(function (response) {
            callback(false, response)
        });

    }

    /**
     * This is the main method of the script, since here we handle all the Apple Pay
     * events. Here you are able to handle any interactions that the user has with the Apple Pay popup.
     *
     * @param {object} Apple Pay Session (the one generated on the button click)
     *
     */
    var handleApplePayEvents = function (appleSession) {
        /** This is the first event that Apple triggers. Here you need to validate the Apple Pay Session from your backend.
        * Your server receives the merchant session object when it calls the Payment Session endpoint as described in Providing Merchant Validation.
        * You must pass the valid merchant session object to the completeMerchantValidation method to enable the user to authorize a transaction.
        * The guidelines for working with a merchant session are:
        * Request a new merchant session object for each transaction. You can only use a merchant session object a single time.
        * The merchant session object expires five minutes after it is created.
        * Never request the merchant session from the client. The request must be sent from your server.
        */
        appleSession.onvalidatemerchant = function (event) {

            validateApplePaySession(event.validationURL, function (success, merchantSessionJSON){
                if (success) {
                    let merchantSession = JSON.parse(merchantSessionJSON);
                    appleSession.completeMerchantValidation(JSON.parse(merchantSession.chargeToken));
              }
              else {
                    //handle error code here
                    console.log("error in validating apple pay session");
              }

            })

            /** This method is triggered after the user has confirmed the transaction with Touch ID or Face ID.
             * Besides getting all the details about the customer (email, address ...) you also receive the Apple Pay payload
             * needed to perform a payment.
             */
            appleSession.onpaymentauthorized = function (event) {
                performApplePayTransaction(event.payment, function (success, outcome) {
                    if (success) {
                        appleSession.completePayment(ApplePaySession.STATUS_SUCCESS)
                    } else {
                        appleSession.completePayment(ApplePaySession.STATUS_FAILURE)
                    }
                })
            }
        }
    }

        /**
         * Sets a onClick listener on the Apple Pay button. When clicked it will
         * begin the Apple Pay session with your configuration
         */
        let setAppleButtonClickListener = function () {
            document
                .getElementById(applePayButtonDisplayController.appleButtonId)
                .addEventListener('click', function () {
                    startApplePaySession(paymentDetails)
                })
        }

        return {

            init: function () {
                // Show or hide the Apple Pay button depending on if Apple Pay is available on this device/browser.
                if (isApplePayAvailable()) {
                    btnDisplayController.displayApplePayButton()
                } else {
                    btnDisplayController.hideApplePayButton()
                }

                // Set the onClick listener on the Apple Pay button
                setAppleButtonClickListener()
            }
        }
})(applePayButtonDisplayController); //passing the UI controller as a parameter.

// Initialize the Apple Pay controller.
applePayController.init()

Step 4: Create two methods in your backend channel

These are used to post two requests to Viva Wallet’s API. Below are the two calls in C#.

Make sure you define demoVivaAccessToken as the value of the access token you obtained during the OAuth 2 token generation procedure outlined on our Authentication page.

API call 1

/// <summary>
/// This method sends a POST request to the Viva Wallet API to get the merchant validated using the ValidationURL ApplePay provided.
/// </summary>
/// <returns>An opaque merchant session object, MerchantSession returned by Apple Pay. This object is required to authorize the transaction.</returns>
[HttpPost]
public async Task<IActionResult> Validate()
{

    //This URL needs to change to https://api.vivapayments.com for your production environment.
    var demoVivaWalletAPI = "https://demo-api.vivapayments.com";
    var endPointApplePayToken = "/nativecheckout/v2/chargetokens:digitize";

    //Your Viva Wallet OAuth2 Token. More info on how to generate one
    //can be found here: https://developer.vivawallet.com/web-api-integration/authentication/#oauth-2-token-generation
    var demoVivaAccessToken = "YOUR VIVA WALLET BEARER TOKEN";

    var httpClient = new HttpClient
    {
        BaseAddress = new Uri(demoVivaWalletAPI)
    };

    httpClient.DefaultRequestHeaders.Authorization =
        new AuthenticationHeaderValue("Bearer", demoVivaAccessToken);
    httpClient.DefaultRequestHeaders
          .Accept
          .Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json));

    using (var reader = new StreamReader(Request.Body))
    {
        /// A JSON object containing the redirect URL provided by ApplePay, the merchant's VivaWallet source code and a providerId.</param>
        var payload = await reader.ReadToEndAsync();

        var content = new StringContent(payload, Encoding.UTF8, MediaTypeNames.Application.Json);

        var response = await httpClient.PostAsync(endPointApplePayToken, content);

        return Ok(response.Content.ReadAsStringAsync().GetAwaiter().GetResult());

    }
}

API call 2

/// <summary>
/// This method sends a POST request to the Viva Wallet API to create a transaction using the customer's ApplePay token.
/// More details: https://developer.vivawallet.com/online-checkouts/native-checkout-v2/#step-5-make-the-actual-charge
/// </summary>
/// <returns>The successful charge's transactionId, if all the requirements were met.</returns>
[HttpPost]
public async Task<IActionResult> PayWithApplePay()
{

    //This URL needs to change to https://api.vivapayments.com for your production environment.
    var demoVivaWalletAPI = "https://demo-api.vivapayments.com";
    var endPointApplePayToken = "/nativecheckout/v2/transactions";

    //Your Viva Wallet OAuth2 Token. More info on how to generate one
    //can be found here: https://developer.vivawallet.com/web-api-integration/authentication/#oauth-2-token-generation
    var demoVivaAccessToken = "YOUR VIVA WALLET BEARER TOKEN";

    var httpClient = new HttpClient
    {
        BaseAddress = new Uri(demoVivaWalletAPI)
    };

    httpClient.DefaultRequestHeaders.Authorization =
        new AuthenticationHeaderValue("Bearer", demoVivaAccessToken);
    httpClient.DefaultRequestHeaders
          .Accept
          .Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json));

    using (var reader = new StreamReader(Request.Body))
    {

        ///The transaction details (which include the ApplePay token) required by Viva Wallet's API
        var payload = await reader.ReadToEndAsync();
        var content = new StringContent(payload, Encoding.UTF8, MediaTypeNames.Application.Json);

        var response = await httpClient.PostAsync(endPointApplePayToken, content);

        return Ok(response.Content.ReadAsStringAsync().GetAwaiter().GetResult());

    }
}

Further reading