Digital Wallets for Web

How to implement Digital Wallets on the web through Merchant Warrior.

Apple Pay Prerequisites

Before implementing Apple Pay on the web, several prerequisites must be met.

To register a domain for use with Apple Pay, you must do

  1. Host the domain verification file on your server. You can download the sandbox verification file here. For production, please download it here instead.
  2. Host the file at /.well-known/apple-developer-merchantid-domain-association on your domain(s) that will display the Apple Pay button. Apple will perform the verification automatically. For example, if your domain is https://example.com.au, host the file at https://example.com.au/.well-known/apple-developer-merchantid-domain-association. Make sure the file is publicly accessible or exclusively accessible by Apple Servers listed in Whitelist Apple IP Addresses for Domain Verification.
Google Pay Prerequisites

Before implementing Google Pay™ on the web, several prerequisites must be met.

Merchant Warrior Web SDK

The easiest way to integrate Apple Pay and other wallets is to use the Merchant Warrior Web SDK.

  1. Include the Merchant Warrior Javascript in the head of your HTML document
<script src="https://securetest.merchantwarrior.com/sdk/merchantwarrior.min.js"></script>
  1. Configure your options
const merchantUUID = '12345abcde';
const apiKey = 'abc123';
const options = {
    environment: 'development', // Default value is 'production'
    middleware: '/.well-known/MerchantWarrior.php',
    xcsrfToken: '<Session Verification Data>',
}
  1. Configure your middleware. For security reasons, the JavaScript SDK does not make any calls directly to the Merchant Warrior servers. Rather, these requests are passed through a middleware option.

Any time a request must be made to Merchant Warrior, a POST request will be made to the URL that you have set as your middleware option. Your middleware needs to support the following Merchant Warrior methods by taking the input, inserting any appropriate missing information (such as hashes) and making a request to the Merchant Warrior API. Each method displayed below shows a sample of the data that is submitted via POST to your middleware, and a sample of the output that is returned back to the Web SDK.

getMerchantSession

Input

{
    "method": "getMerchantSession",
    "endpoint": " https://base.merchantwarrior.com/",
    "accessToken": " c82f7e5988fff6a439d0f43e6",
    "validationURL": "https://apple-pay-gateway-cert.apple.com/paymentservices/startSession",
    "domainName": "your.domain.com"
}

Output

{
    "responseCode": "0",
    "responseMessage": "Operation successful",
    "merchantSession": "{\"epochTimestamp\":1640236968964,\"expiresAt\":1640240568964,\"merchantSessionIdentifier\":\"SSHAE01E8377CFE46F2939FC7455BC491BF_916523AAED1343F5BC5815E12BEE9250AFFDC1A17C46B0DE5A943F0F94927C24\",\"nonce\":\"42635849\",\"merchantIdentifier\":\"2E93A3CD36CF5AF27A2A686C3AFE2EADCB0F74FBC3F1787D50CE51B40331C74F\",\"domainName\":\"your.domain.com\",\"displayName\":\"Widgets Pty Ltd\",\"signature\":\"<a very long string goes here>\",\"retries\":0}"
}

processCard

Input

{
    "method": "processCard",
    "endpoint": "https://base.merchantwarrior.com/",
    "accessToken": "c82f7e5988fff6a439d0f43e6",
    "transactionAmount": "13.00",
    "transactionCurrency": "AUD",
    "transactionProduct": "Basic Charge",
    "digitalWalletToken": "{\"data\":\"<a very long string goes here>\"},\"version\":\"EC_v1\"}",
    "customerName": "Jim Bob",
    "customerCountry": "US",
    "customerState": "QLD",
    "customerCity": "Brisbane",
    "customerAddress": "345 Ann Street",
    "customerPostCode": "4000",
    "customerPhone": "61412345678"
}

Output

{
    "responseCode": "0",
    "responseMessage": "Transaction approved",
    "transactionID": "1842-6ad84688-63b0-11ec-a43d-005056b2764e",
    "authCode": "7022993835",
    "receiptNo": "007022993835",
    "authMessage": "Honour with identification",
    "authResponseCode": "08",
    "authSettledDate": "2021-12-23",
    "transactionReferenceID": {},
    "custom1": {},
    "custom2": {},
    "custom3": {},
    "customHash": "1a3c3572c764e3f4b212e90a94419ea5",
    "paymentCardNumber": "520424XXXXXX6937",
    "transactionAmount": "13.00",
    "feeAmount": "0.00",
    "cardType": "mc",
    "cardExpiryMonth": "09",
    "cardExpiryYear": "22"
}

Alternatively, this value can be set to a Javascript function. This function accepts a single parameter, a JSON object containing a valid API request, and should return a promise containing a JSON object of the Merchant Warrior server response.

const options = {
    middleware: function(request) {
        return new Promise((resolve, reject) => {
            // Handle request
        });
    }
}
  1. Create the Merchant Warrior object. This can be done in one of two ways -

4A. The static MerchantWarrior.create() method will return a promise containing the object pre-populated with your merchant information.

MerchantWarrior.create(merchantUUID, apiKey, options).then((mwarrior) => {
    // Interact with the mwarrior object here
});

4B. The static MerchantWarrior.createWithToken() method can alternatively be used to to create the promise using an accessToken instead of your merchant credentials.

MerchantWarrior.createWithToken(accessToken, options).then((mwarrior) => {
    // Interact with the mwarrior object here
});
  1. Create a payment summary. If the customer details are currently unknown, they can be omitted and supplied later in the process. This summary also allows you to choose which wallets you would like to be made available to compatible devices. The options are googlepay, applepay, and basic-card. basic-card uses whatever interface the browser makes available, and uses card data (such as PAN) directly.

The applePay property is for specific Apple Pay options. It takes an object that has a single string property, buttonText. This property controls what text is displayed on the Apple Pay button. Available options include buy, donate, plain, set-up, book, check-out, subscribe, add-money, contribute, order, reload, rent, support, tip, or top-up.

const customer = {
    name: 'Jane Doe',
    country: 'AU',
    state: 'QLD',
    city: 'Brisbane',
    address: '345 Ann Street',
    postCode: '4000',
    phone: '61412345678'
}

const summary = {
    total: {
        amount: '25.00',
        label: 'A Product',
        pending: false
    },
    customer: customer, // Optional - can be supplied later
    style: 'dark', // Optional - default dark
    applePay: {
      buttonText: 'buy'
    },
    wallets: [
        'googlepay',
        'applepay',
    ],
}
  1. Create and mount a payment request
    mwarrior.paymentRequest(summary).then((element) => {
        element.mount('payment-buttons'); // This will attach the buttons to the HTML element with an id of 'payment-buttons'
    });
  1. Handle events.

The two primary events

  • payment-complete, which will trigger when the payment process has completed. It has 3 arguments, status which is a boolean value indicating whether the payment was successful, response which contains a JSON object detailing the response from the Merchant Warrior servers, and errors which contains any Javascript error details. Whether a payment is successful or not, the button that triggered it will still be reusable and should be manually removed when finished with.

  • request-customer, which will trigger near the start of the payment flow if a customer is not included in the initial payment summary. It has two parameters - resolve, and reject. These are connected to an internal promise. Calling the resolve parameter with a valid customer will allow the payment request to proceed, and calling the reject parameter will end the payment and trigger the payment-complete event.

    mwarrior.on('payment-complete', (status, response, errors) => {
        if (status) {
            document.getElementById('payment-buttons').innerHTML = '';
            // Payment successful!
        } else {
            // Payment failed
        }
    });

    mwarrior.on('request-customer', (resolve, reject) => {
        resolve(customer);
    });
  1. Put it all together. An example of this code in action can be found here
const merchantUUID = '12345abcde';
const apiKey = 'abc123';
const options = {
    environment: 'development', // Default value is 'production'
}

const summary = {
    total: {
        amount: '25.00',
        label: 'A Product',
        pending: false
    },
   // customer: customer, // Optional - can be supplied later
    style: 'dark', // Optional - default dark
    plePay: {
      buttonText: 'buy'
    },
    wallets: [
        'googlepay',
        'applepay',
    ],
}

MerchantWarrior.create(merchantUUID, apiKey, options).then((mwarrior) => {
    mwarrior.paymentRequest(summary).then((element) => {
        element.mount('payment-buttons'); // This will attach the buttons to the HTML element with an id of 'payment-buttons'
    });

    mwarrior.on('payment-complete', (status, response, errors) => {
        if (status) {
            document.getElementById('payment-buttons').innerHTML = '';
            // Payment successful!
        } else {
            // Payment failed
        }
    });

    mwarrior.on('request-customer', (resolve, reject) => {
        const customer = {
            name: 'Jane Doe',
            country: 'AU',
            state: 'QLD',
            city: 'Brisbane',
            address: '345 Ann Street',
            postCode: '4000',
            phone: '61412345678'
        }
        resolve(customer);
});
Manual Integration

To integrate manually, follow the instructions provided by Apple and Google, and include the final token in a Digital Wallet processCard request.