Building an Apple Pay payment interface

You use the Apple® JavaScript API to build a web interface that restaurant guests can use to make Apple Pay payments. The Apple Pay JavaScript API implements functions that:

  • Determine whether a guest's ordering device supports Apple Pay payments and can display Apple Pay payment controls.

  • Handle the interface events that occur when a guest makes an Apple Pay payment on your ordering interface.

  • Generate a payment authorization token that your integration can present to the Toast platform to complete a guest payment.

Note

This developer documentation for the Toast Apple Pay API includes limited information about the functions and components of the Apple JavaScript API. Use the Apple Pay JS API developer documentation for comprehensive and detailed information about the Apple Pay API.

Displaying an Apple Pay button

In order to display an Apple Pay button on your web page, the following script must be included on the page.

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

The HTML tag to create the Apple Pay button is:

<apple-pay-button buttonstyle="black" type="buy" locale="en"></apple-pay-button>

In order to be compliant with Apple's branding, use the Apple Pay on the Web Interactive Demo to generate an Apple approved Apple Pay button.

Authorizing Apple Pay transactions

Once you have successfully registered as an Apple Pay web merchant under the Toast platform, integration developers can retrieve valid Apple Pay payment sessions through the Toast platform.

The Apple Pay session is needed to request Apple Pay Payment tokens used for financial transactions. The Apple Pay session is provided through the Apple Pay payment session API.

The following sections describe the steps you take to authorize Apple Pay transactions in your ordering and payment interface.

Determining if Apple Pay is available

To determine if Apple Pay is supported on a client's browser, the integration developer must check for two things:

  • Does the ApplePaySession exist on a browser window?

    if (window.ApplePaySession) {
       // The Apple Pay JS API is available.
    }
    
  • Does ApplePaySession.canMakePayments evaluate to true?

If both conditions are met, the Apple Pay button should be displayed.

For more information about how to display an Apple Pay button or creating an Apple Pay session, see Checking for Apple Pay Availability developer documentation.

Building the Apple Pay session object (from the web)

If Apple Pay is available on the browser, the browser can then validate the merchant, retrieve the payment session, and display the payment sheet for the guest to select. The payment sheet shows the credit or debit card linked to Apple Pay, purchase amount (including taxes and fees), shipping options, and contact information.

This requires the client to create an ApplePayPaymentRequest object to attach to the Apple Pay Session.

The following example shows an ApplePayPaymentRequest payment request.

var request = {
    "countryCode": "US",
    "currencyCode": "USD",
    "merchantCapabilities": [
        "supports3DS"
    ],
    "supportedNetworks": [
        "visa",
        "masterCard",
        "amex",
        "discover"
    ],
    "total": {
        "label": "Your Merchant Name",1
        "type": "final", 2
        "amount": "1.99"
    },
    “applicationData”: ewogICAgInB1aWQiOjg2YWNhZDIwLWJjZjQtNDk3MS1hNDkzLTAxYTNiYzNkZTgwZCAKfQ== 3
}

var session = new ApplePaySession(3, request)

1

The business name that appears on the Apple Pay payment sheet.

2

A value that indicates whether the line item is final or pending. The value must be final.

3

A value that the Toast platform uses to validate that the payment token from the Apple Pay Payment object for payment authorization matches the correct payment session. The value must be base-64 encoded, otherwise it will be ignored by Apple Pay servers.

The value encoded is the puid (paymentUuid) for payment authorization in JSON format. The puid is the UUID unique identifier for the credit card payment. You generate the UUID for the payment. You use the puid when you apply the credit card payment to a check.

The following example shows an unencoded applicationData value.

{
    "puid":86acad20-bcf4-4971-a493-01a3bc3de80d 
}

The following example shows a base-64 encoded applicationData value.

ewogICAgInB1aWQiOjg2YWNhZDIwLWJjZjQtNDk3MS1hNDkzLTAxYTNiYzNkZTgwZCAKfQ==
Defining the onvalidatemerchant handler

You must define an onvalidatemerchant method handler. The onvalidatemerchant is automatically invoked after an Apple Pay Session is begun (session.begin()). For more information, see onvalidatemerchant developer documentation.

Note

The onvalidatemerchant method should reach out to your server to communicate with the Toast Initiate Session API. The response from the Toast Initiate Session API must then be supplied to the session.completeMerchantValidation function, as shown below.

session.onvalidatemerchant = event => {
    // Call your own server to request a new merchant session from Toast.
    fetch(event.validationURL)
      .then(res => res.json()) // Parse response as JSON.
      .then(merchantSession => {
        session.completeMerchantValidation(merchantSession);
      })
      .catch(err => {
        console.error("Error fetching merchant session", err);
      });
};
Defining the onpaymentauthorized handler

The onpaymentauthorized event handler must also be defined. The onpaymentauthorized handler is responsible for processing the transaction. It is run after a guest authenticates the transaction via Apple Face ID, Touch ID or device passcode. For more information, see onpaymentauthorized developer documentation.

The handler accepts an event as an argument.

session.onpaymentauthorized = function(event) {}.

The event.payment parameter provides an ApplePayPayment object. This payment object contains data that comes from Apple and needs to be provided to Toast. You must base-64 encode the event.payment. For example, you can use the following code to base-64 encode the event.payment value.

encodeCardData: (payment) => {
const cardData = Buffer.from(JSON.stringify(payment)).toString("base64");
return cardData;
}

The encoded value is the APPLE PAY TOKEN BYTE ARRAY. Using the ApplePayPayment object retrieved from Apple Pay, you pass this payload to the Toast platform as the APPLE PAY TOKEN BYTE ARRAY in the encryptedCardData field when authorizing an Apple Pay payment.

The client code must reach out to your server to call CCPartner. You must complete the response by calling completePayment in 30 seconds before the automatic Apple Pay timeout.

session.onpaymentauthorized = event => {

    // Call your own server for an authorization request to Toast.
    fetch(event.authorizationURL, {
            method: "post",
            body: JSON.stringify({
                payment: _funcToConvertToByteArray(event.payment),
                total: "your total",
                puid: "your UUID"
                applicationData: {{base64 encoded data of { puid : “your UUID”}}},
            }),
            headers: {
                "Content-Type": "application/json",
            },
        })
        .then((res) => res.json()) // Parse response as JSON.
        .then((res) => {
            if (res.paymentState === "AUTHORIZED") this.completePayment("STATUS_SUCCESS");
            else this.completePayment({
                status: 1
            });
        })
        .catch((err) => {
            console.log(err)
            this.completePayment({
                status: 1,
            });
        });
}
Defining any other handlers needed

At this point, you might want to implement the optional event handlers (onShippingMethod to address PaymentSheet interactions found here through Apple’s documentation, but is not required.

Calling session.begin() to invoke the workflow

Once your request is built, you can call applePaySession.begin() with the Apple Pay JS API version you are using and the Apple Pay Payment Request.

Payment interface code example

The following example shows an implementation of a guest-facing payment interface, using the Apple Pay JavaScript API.

function initiateSession(event) {
  const puid = createUUID();
  const request = createRequest(puid);
  const session = new ApplePaySession(3, request);

  // add custom session values
  session.total = request.total;
  session.puid = puid;
  session.applicationData = request.applicationData;
  
  session.onvalidatemerchant = validateMerchant;
  session.onpaymentauthorized = completeAuthorization;
  session.begin();
}

function createRequest(puid) {
  let req = {
    countryCode: "US",
    ...
  };

  return req;
}

// Call backend to initiate session
function validateMerchant(event) {
  fetch("/mybackend/initiateSession")
    .then((res) => res.json()) // Parse response as JSON.
    .then((merchantSession) => this.completeMerchantValidation(merchantSession))
    .catch((err) => {
      console.error("Error fetching merchant session", err);
    });
}

function completeAuthorization(event) {
  // Call backend, which should call Toast Payment API
  fetch("/toast/authPayment", {
    method: "post",
    body: JSON.stringify({
      payment: event.payment,
      total: event.target.total,
      puid: event.target.puid,
      applicationData : event.target.applicationData,
    }),
    headers: {
      "Content-Type": "application/json",
    },
  })
    .then((res) => console.log(res))
    .catch((err) => console.error(err));

}