Skip to main content

Payment flow with Apple Pay

Last updated: 04-Mar-2022
Rate this article:

Overview

The following payment method is specific to Apple devices.

Availability

Available for all 2Checkout merchants (2Sell, 2Subscribe, 2Monetize & 4Enterprise) using all or any of our ordering engines (hosted shopping cart, ConvertPlus, and InLine).

For more information on availability, please see the main documentation page for Apple Pay here.

Requirements

Shoppers can use any device that supports Apple Pay and is located in one of the selected list of countries.

For more information on requirements, please see the main documentation page for Apple Pay here.

Activation

For activation, you need to have Apple Pay enabled on your 2Checkout account. Please contact the Merchant Support team in order to enable this. After 2Checkout sets up our domain, we will provide you with a domain verification file.

Host your domain verification file at the following path on our server: https://[DOMAIN_NAME]/.well-known/apple-developer-merchantid-domain-association.

Setting up the backend API calls

Step 1 - Initiate an Apple Pay session

Create an endpoint on your server to call to initiate an Apple Pay session. In order for a valid Apple Pay session to be created, an API call to the 2Checkout API needs to be sent, with the validationURL set to the ApplePay payment service. 

Protocol

Endpoint

REST POST https://api.2checkout.com/rest/6/payments/startapplepaysession
JSON-RPC
startApplePaySession
SOAP
startApplePaySession

 

{

   "validationURL":"https://apple-pay-gateway.apple.com/paymentservices/startSession"

}

Step 2 - Decrypt the Apple Pay token

Once the token is received from the frontend component, it has to be sent to the decryptApplePayData endpoint in the 2Checkout API. This will return a data response from Apple Pay that needs to be used in the placeOrder call.

Protocol

Endpoint

REST https://api.2checkout.com/rest/6/payments/decryptapplepaydata
JSON-RPC
decryptApplePayData
SOAP
decryptApplePayData

BODY: (ApplePayData property value should be the event.payment.token from the onpaymentauthorized event )

[
   "ApplePayData""=>""543a07601ed9f8b8ee226e9630a24e2a91da8fdb08e6786fa02bf628f395bb91"
]

Step 3 - Place the order

Once the Apple Pay data is received from 2Checkout, this needs to be used in the Payment Method object of the Payment Details object in the API call to place an order.

Protocol

Endpoint

REST POST https://api.2checkout.com/rest/6/orders/re
JSON-RPC placeOrder
SOAP placeOrder

 

{
   "Items":[
      {
         "Code":"5DCB30C6B0",
         "Quantity":1
      }
   ],
   "BillingDetails":{
      "Email":"example@email.com",
      "FirstName":"Customer First Name",
      "LastName":"Customer Last Name",
      "CountryCode":"US",
      "State":"California",
      "City":"San Francisco",
      "Address1":"Example Street",
      "Zip":"90210"
   },
   "PaymentDetails":{
      "Type":"APPLE_PAY",
      "Currency":"USD",
      "CustomerIP":"10.10.10.10",
      "PaymentMethod":{
         "ApplePayToken":"ApplePayDataToken"
      }
   },
   "Language":"en",
   "Country":"US",
   "CustomerIP":"10.10.10.10",
   "Source":"Website",
   "ExternalCustomerReference":"externalCustomerId",
   "Currency":"USD",
   "MachineId":"123456789"
}

Setting up the frontend component

In order to set up an Apple Pay session in the shopper's browser, the following steps are needed: 

Step 1 - Include the Apple Pay library and create a instance

First include the Apple Pay library

<script src="https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js"></script>

Step 2 - Add the Apple Pay button

<style>
apple-pay-button {
  --apple-pay-button-width: 150px;
  --apple-pay-button-height: 30px;
  --apple-pay-button-border-radius: 3px;
  --apple-pay-button-padding: 0px 0px;
  --apple-pay-button-box-sizing: border-box;
}
</style>
<apple-pay-button buttonstyle="black" type="plain" locale="en" onclick="onApplePayButtonClicked()"></apple-pay-button>

Step 3 - Set up your Apple Pay function

function onApplePayButtonClicked() { 
    // Ensure browser supports Apple Pay
    if (!ApplePaySession) {
        return;
    }

    // Define ApplePayPaymentRequest
   /* Define the country code and currency being sent to the library, as well as 
   the list of supported networks and the descriptor and amount of the transaction.*/
    const request = {
        "countryCode": "US",
        "currencyCode": "USD",
        "merchantCapabilities": [
            "supports3DS"
        ],
        "supportedNetworks": [
            "visa",
            "masterCard",
            "amex",
            "discover"
        ],
        "total": {
            "label": "Example Transaction",
            "type": "final",
            "amount": "0.01"
        }
    };

    // Create ApplePaySession
    const session = new ApplePaySession(3, request);

    session.onvalidatemerchant = async event => {
        // Call your own server to request a new merchant session.
        fetch("/startApplePay.php")
            .then(res => res.json()) // Parse response as JSON.
            .then(merchantSession => {
                response = JSON.parse(merchantSession.ApplePaySessionData.response);
                merchantSession.ApplePaySessionData.response = response;
                session.completeMerchantValidation(response);
            })
            .catch(err => {
              console.error("Error fetching merchant session", err);
            });
    };

    session.onpaymentmethodselected = event => {
        // Define ApplePayPaymentMethodUpdate based on the selected payment method.
        // No updates or errors are needed, pass an empty object.
        const update = {
            newTotal: {
                label: "Demo (Card is not charged)",
                type: "final",
                amount: "0.01"
            }
        }
        session.completePaymentMethodSelection(update);
    };

    session.onshippingmethodselected = event => {
        // Define ApplePayShippingMethodUpdate based on the selected shipping method.
        // No updates or errors are needed, pass an empty object. 
        const update = {
            newTotal: {
                label: "Demo (Card is not charged)",
                type: "final",
                amount: "0.01"
            }
        }
        session.completeShippingMethodSelection(update);
    };

    session.onshippingcontactselected = event => {
        // Define ApplePayShippingContactUpdate based on the selected shipping contact.
        const update = {
            newTotal: {
                label: "Demo (Card is not charged)",
                type: "final",
                amount: "0.01"
            }
        }
        session.completeShippingContactSelection(update);
    };

    session.onpaymentauthorized = event => {
        // Define ApplePayPaymentAuthorizationResult
        payload = {
            token: event.payment.token,
        };
        fetch("/finishApplePay.php", {
            method: "POST",
            headers: {"Content-Type": "application/json"},
            body: JSON.stringify(payload),
        }).then((res) => res.json())
            .then((res) => {
                if (res.Status.includes('AUTHRECEIVED', 'COMPLETE')) {
                  session.completePayment(event.STATUS_SUCCESS);
                }
                console.log("INFO - RECEIVED ECOM RESPONSE: ", res.Status);
                })
                .catch((err) => console.log(err));
    };

    session.oncancel = event => {
        // Payment cancelled by WebKit
    };
    session.begin();
}

 

Rate this article:
Logo of Verifone