Markdown

Apple Pay

Fetch Apple Pay configuration from the gateway, run the Apple Pay JS session on your payment page, and authorize the resulting token with CCAUTHCAP.

Apple Pay overview

This section covers sending credit card transactions to the gateway using Apple Pay.

To accept Apple Pay, the web pages that host your payment forms must have their domains registered with Apple. See the Apple Pay Registration Process document for details. The Processor and Merchant Account you use must also support Apple Pay; contact your gateway support representative to confirm this.

Customers using Apple devices (iPhone, iPad, MacBook, etc.) with an Apple browser (Safari) are able to use Apple Pay to make purchases. The rest of this page describes how to set up an Apple Pay purchase on your hosted payment page and send the resulting authorization to the gateway API.

Real cards required for production testing

Test cards will not work when testing Apple Pay in a production environment. Real cards must be used.

Integration flow

This is the order in which you set up Apple Pay processing:

  1. Fetch the Apple Pay configuration data from the gateway.
  2. Update the configuration with the specific payment/order details.
  3. Present the Apple Pay button.
  4. Add the Apple Pay library to the payment page.
  5. Create a JS function to validate your domain.
  6. Create and start the Apple Pay session.
  7. Get the authorized payment information from the customer's browser.
  8. Send the transaction to the gateway.

Each step is discussed below with example code. The example code is illustrative only and does not represent code that can be used as-is in a production environment.

Fetching your Apple Pay configuration

You need configuration data from the gateway to set up the Apple Pay session when the customer clicks the Apple Pay button.

POSThttps://api.inoviopay.com/payment/applepay.cfm

Requests must be made in JSON format.

Request parameters

Field Name Description
REQ_USERNAME Required API credential username.
REQ_PASSWORD Required API credential password.
DOMAIN_NAME Required Domain name where the payment page is hosted/served from.
CLIENT_ID Required Client ID.
REQUEST_ACTION Required APPLEPAYCONFIG. Used to instruct the endpoint to provide the Apple Pay configuration.

All parameters are required.

Response

The response is a JSON-formatted string:

{
    "APPLEPAY_CLI_CONF_ID": xx, // internal unique id; do not change
    "REQ_ID": 11111111111, // trace ID, used for troubleshooting
    "CLIENT_ID": 1111111, // your gateway api client_id
    "INITIATIVE": "web", // identifies e-commerce transaction
    "DISPLAY_NAME": "xxxxxxx", // Short, localized description of the merchant.
    "PARTNER_MERCH_NAME": "xxxxxx", // name of the merchant
    "PARTNER_INTERNAL_MERCH_ID": "xxxxxxxxxxxxx", // identifies the merchant to apple
    "ENCRYPT_TO": "xxxxxxxxxxxxxxxxxxxx", // merchant ID to Apple
    "DOMAIN_LIST": [ // domain registered in Inovio portal serving this page
      {
        "DOMAIN_NAME": "paymentpagedomain.com",
        "DOMAIN_STATUS": "ACTIVE"
      }
    ],
    "paymentRequest": {
      "countryCode": "US",
      "currencyCode": "USD",
      "merchantCapabilities": [
        "supports3DS"
      ],
      "supportedNetworks": [
        "visa",
        "masterCard"
      ],
      "requiredBillingContactFields": [
        "postalAddress",
        "name",
        "phoneticName",
        "phone",
        "email"
      ],
      "total": {
        "label": "", // required; a short, localized description of the line item
        "type": "final", // do not change
        "amount": 0 // must be greater than or equal to zero
      }
    },
    "fetchUrl": "https://api.inoviopay.com/apple-pay-services/api/session/create"
}

Provide this response on your payment page as the merchantConfig parameter:

<script>
 this.merchantConfig = {
    "APPLEPAY_CLI_CONF_ID": 11,
    "REQ_ID": 11111111111,
    "CLIENT_ID": 1111111,
    "INITIATIVE": "web",
    "DISPLAY_NAME": "xxxxxxx",
    "PARTNER_MERCH_NAME": "xxxxxx",
    "PARTNER_INTERNAL_MERCH_ID": "xxxxxxxxxxxxx",
    "ENCRYPT_TO": "xxxxxxxxxxxxxxxxxxxx",
    "DOMAIN_LIST": [
      {
        "DOMAIN_NAME": "paymentpagedomain.com",
        "DOMAIN_STATUS": "ACTIVE"
      }
    ],
    "paymentRequest": {
      "countryCode": "US",
      "currencyCode": "USD",
      "merchantCapabilities": [
        "supports3DS"
      ],
      "supportedNetworks": [
        "visa",
        "masterCard"
      ],
      "requiredBillingContactFields": [
        "postalAddress",
        "name",
        "phoneticName",
        "phone",
        "email"
      ],
      "total": {
        "label": "",
        "type": "final",
        "amount": 0
      }
    },
    "fetchUrl": "https://api.inoviopay.com/apple-pay-services/api/session/create"
 }
</script>

Updating the configuration with order details

Once merchantConfig is stored on your payment page, update the fields that are specific to the current purchase:

<script>
  merchantConfig.total.label = "Some purchase description total";
  merchantConfig.total.amount = 49.95
</script>

Adding the Apple Pay library

Add the Apple Pay library to your payment page so it can call the Apple Pay API. Source the library script in the page's HTML:

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

This library also validates that the user's browser and device are eligible for Apple Pay.

Validating your domain

The Apple Pay JS API library calls a function you define to validate the domain where your payment page is hosted. This must load directly from your servers on that domain; no proxies or iframes.

<script>
 function validateMerchant(merchantConfig) {
  console.log("validateMerchant: ", merchantConfig.DOMAIN_LIST)
  const data={
   method: "POST",
   headers: {
           "Content-type": "application/json",
           "Accept": "*/*"
         },
         body: JSON.stringify({
           "merchantIdentifier": merchantConfig.PARTNER_INTERNAL_MERCH_ID,
           "displayName": merchantConfig.DISPLAYNAME,
           "initiative": merchantConfig.INITIATIVE,
           "initiativeContext": merchantConfig.DOMAIN_LIST[0].DOMAIN_NAME
          })
        };
        return fetch(merchantConfig.fetchUrl,data);
    }
</script>

Presenting the Apple Pay button

Once the Apple Pay library is added, add an HTML element for the button. The element must be named 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>

Creating and starting the Apple Pay session

After presenting the button, add an action to it that starts the session, which triggers the browser to display a dialog where the user selects their card and approves the transaction. Add an onClick event to the Apple Pay button. paymentRequest here refers to the paymentRequest object returned by APPLEPAYCONFIG.

Handling the authorized payment

After the customer authorizes the payment in the Apple Pay overlay, Safari returns an object (the Apple Pay token) with the data needed to authorize the payment with the gateway API. Create a session.onpaymentauthorized method to receive this token object.

Handling a canceled payment or error

Handle the case where the customer does not authorize the payment, or where an error is thrown, with session.oncancel.

The full example, combining the button click handler, merchant validation, payment authorization, and cancel handling:

async function onApplePayClick() {
  // Check for valid ApplePay session
  if(!ApplePaySession){
    return;
  }
  // Get the paymentRequest data from the merchantConfig object
  const paymentRequest = this.merchantConfig.paymentRequest;
  // Validate the merchant.
  // Note that this.merchantConfig is defined in Step 3
  const session = new ApplePaySession(3, paymentRequest);
  session.onvalidatemerchant = async (event) => {
    const merchantSession = await
      this.validateMerchant(this.merchantConfig).then(res=>res.json());
    session.completeMerchantValidation(merchantSession);
  };
  // Handle the authorized payment
  // Note, this must come inside the onApplePayClick() function, and
  // before session.begin
  session.onpaymentauthorized = async (event) => {
    // Define ApplePayPaymentAuthorizationResult
    const result = {
      status: ApplePaySession.STATUS_SUCCESS,
    };
    var applePaymentToken = event.payment;
    var tokenEncoded = btoa(JSON.stringify(applePaymentToken));
    // Now that the payment is authorized in Apple Pay, you can
    // initiate a service call to the gateway passing the
    // applePaymentToken into the gateway API parameter: PMT_WALLET_CRYPTOGRAM
    //
    // Do that here, through your server

    // If the payment is declined at the processor, then you should
    // put an appropriate message in place to the customer
    // result.status = ApplePaySession.STATUS_FAILURE

    // Now we can gracefully complete the Apple Pay browser interaction
    session.completePayment(result);
  };
  // In case the customer cancels or in case of an unexpected error
  // Note, this must come inside the onApplePayClick() function, and
  // before session.begin
  session.oncancel = (event) => {
    // Payment canceled by WebKit
    // error handling
    console.log("Payment canceled by WebKit: "+JSON.stringify(event.error))
  }
  // now the user will interact to approve the purchase
  // Note, this must come at the END of the onApplePayClick()
  session.begin();
}

Sending the authorized payment to the gateway

Once Apple Pay returns the authorized payment token, send it to the gateway as a normal CCAUTHCAP request, passing the token in PMT_WALLET_CRYPTOGRAM:

https://api.inoviopay.com/payment/pmt_service.cfm?request_action=CCAUTHCAP&li_count_1=1&li_prod_id_1=111&li_value_1=49.95&req_username=GATEWAY_USER&req_password=GATEWAY_PASS&site_id=11111&request_response_format=JSON&request_api_version=4.14&request_currency=USD&PMT_WALLET=applepay&PMT_WALLET_CRYPTOGRAM=xxxxxxx

Important requirements for Apple Pay authorization requests

You must not include any of the following parameters; doing so will cause the gateway to reject the request:

  • PMT_NUMB
  • PMT_KEY
  • PMT_EXPIRY
  • TOKEN_GUID
  • PMT_ID
  • PMT_LAST4
  • PMT_ID_XTL
  • PMT_NUMB_COF
  • REQUEST_INITIATOR

Other gateway parameters can be included, but they must match the values used in the Apple Pay session:

  • li_value_1 must match the value of paymentRequest.total in the merchantConfig data.
  • request_currency must match the value of paymentRequest.currencyCode in the merchantConfig data.
The PDF gives no further Apple Pay field table beyond this

Section 21.11 of the source spec lists only the excluded-parameter list and the two must-match rules above; it does not provide a separate table of additional required PMT_WALLET_* fields, so none is invented here.

Rebilling and card on file

The gateway response returns a CUST_ID and PMT_ID on a successful Apple Pay authorization, the same as it does for normal transactions. To authorize against the generated Apple Pay payment record, pass the same CUST_ID and PMT_ID on all subsequent rebills or unscheduled merchant-initiated card-on-file transaction requests.

Not in the SDKs yet

Apple Pay is not implemented in any of the four SDKs. A WalletToken variant (walletType: 'applepay' | 'googlepay') is declared in each language's type system, but PaymentMethods only constructs card, token and savedCard in v1, there is no constructor that produces a wallet payment method, so sale()/authorize() cannot be handed a PMT_WALLET_CRYPTOGRAM token today. Send the authorization as a raw HTTP request per the example above, or see the SDKs. Rebilling against the resulting CUST_ID/PMT_ID does work through the SDK once you have them, using the same SavedCard path as Card on File.