Apple Pay iFrame Guide

 
Out Of Scope

Apple Pay with WePay does not currently support Nonprofits.

The Apple Pay iFrame allows your platform to offer a digital wallets solution to merchants. The iFrame is an embeddable component that can be hosted on the checkout page for merchants. Merchants' customers can choose Apple Pay as a contactless alternate method of payment.

Requirements

  1. Once you have set up your Apple Developer Account, the WePay integration team will need to grant permission and set configs for your AppId
  2. Set up the domain verification file
  3. Apple Pay tokenized bundle is received from the iFrame, which is is then processed by WePay in a POST /payment_methods request
  4. Ensure that email and notification functionality is available through the triggers
    • payments.created
    • payments.updated
    • payments.completed
    • payments.failed
Domain Verification

Apple requires additional verification of the domains that will host/contain the Apple Pay button. Before payments can be accepted via Apple Pay, the platform or the merchant must register all domains that will host the Apple Pay button.

Domain verification steps:

  1. Download the verification file that Apple provides. This file will be the same for all WePay merchants:

  2. Host the domain verification file in the following format: https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association.
  3. In your codebase or the merchant's codebase, make sure the verification file is in a folder called .well-known.
  4. Register the domain using either the API or Partner Center UI.
  5. Apple will make a request to https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association (no filename extension) and verify the file.
  6. Apple will check that the file is hosted at the provided URL to verify the domain.
Required

Every merchant must have each one of their domains registered with Apple.

Who does the registration?
We handle the domain registration through the endpoint: POST /accounts/{id}/payment_methods/apple_pay/register with the request body:
Copy
Copied
	{
		"domain_names": ["https://example.com", "https://example2.com", "https://example3.com", "...etc"],
		"merchant_url": "http://merchantdomain.com",
		"partner_merchant_name": "Merchant Selling a Product or Service, Inc."
	}

merchant_url is optional.

The POST /accounts/{id}/payment_methods/apple_pay/register endpoint allows you to unregister a domain.
Copy
Copied
	{
		"domain_names": ["https://example.com", "https://example2.com", "https://example3.com", "...etc"],
		"reason": "Changed domain"
	}
The endpoint GET /accounts/{id}/payment_methods/apple_pay retrieves all Apple Merchant details with regard to your Apple Pay registration.

If the you are hosting the merchant's domain for them, then you would register all their merchant's domains and host the verification file either via Partner Center or via an API interaction.

If the merchant has a sub-domain within your domain or if they have their own e-commerce website, they can register their domains themselves using Merchant Center.

Response Schema

VerbAPI EndpointDescription
POST/accounts/{id}/method_of_payments/apple_pay/registerRegister merchant domains as an Apple Pay web merchant using WePay
POST/accounts/{id}/method_of_payments/apple_pay/unregisterUnregister merchant domains as an Apple Pay web merchant using WePay
GET/accounts/{id}/method_of_payments/apple_payGet all domains and related info that have been registered with Apple via WePay
The Response Codes
DescriptionResponse Code to PartnerDescription
Ok200Ok / Return GetMerchantInfo Response body
Bad Request400The input is invalid (malformed request or domain is not ready to accept Apple Pay Payments)
Unauthorized. WePay's Merchant ID is not registered with Apple500 Internal Server Error (WePay's credentials might need to be remade due to expiration or other possible error with the merchant ID/Domain configuration)
Expectation Failed. WePay's Merchant ID is not configured correctly to handle ApplePay payments500
Internal Server Error500Issue Connecting to Apple Pay

Response Body
The response body for GET /accounts/{id}/payment_methods/apple_pay will be in the following form:
Copy
Copied
{
	"domain_names": ["https://example.com", "https://example2.com", "https://example3.com", "...etc"],
	"merchant_url": "http://merchantdomain.com",
	"partner_merchant_name": "Merchant Selling a Product or Service, Inc."
}

Implementing an Apple Pay iFrame

Once requirements and domain verification are completed, you are ready to create an Apple Pay iFrame button instance.

Configure the Helper JS script

Make sure to create a script tag for Helper JS

info
For a staging AppId use src="https://stage-cdn.wepay.com/wepay.min.js"
For a production AppId use src="https://cdn.wepay.com/wepay.min.js"
Copy
Copied
<script src="https://cdn.wepay.com/wepay.min.js"></script>

Create a container for the iFrame

Copy
Copied
const apple_pay_container_id = "apple_pay";

Set up iFrame configuration options

The Helper JS requires some configuration options to create the iFrame:

  • button_configs
  • on_success
  • on_error
  • on_update_payment_data
  • on_cancel
In this step you create a variable, such as apple_pay_configs which will hold these assignments
info

You can customize the button style, button type CTA (Call to Action), language, width, height and corner radius. Font size is not a supported parameter. Because we are using CSS, all of the styling configs that Apple allows will not be supported. Some of the new CTAs like “addMoney”, “continue” , “set up”, “top up” are not supported with CSS.

You can pass the following CSS using the cssVariables property to the button_configs property:
  • borderRadius
  • padding
  • width
  • height
You can also pass a language selection using the locale property.

Properties not supported by Apple will be ignored.

More info about Apple's CSS options can be found at Displaying Apple Pay Buttons Using CSS, ApplePayButtonType and ApplePayButtonStyle.

Apple Pay Button Configs Example
Copy
Copied
const apple_pay_configs = {
	button_configs: {
		accountId: accountId, <-- This is the merchant account id passed as a variable
        cssVariables: {
            borderRadius: "3px",
            ApplePayButtonType: "continue",            
            ApplePayButtonStyle: "white-outline"
        },
        locale: "fr",        
        merchantDisplayName: 'Business Service International, Inc.',
        paymentRequest: {
            countryCode: "US",
            currencyCode: "USD",
            merchantCapabilities: [
                "supports3DS",
                "supportsDebit",
                "supportsCredit"
            ],
            shippingMethods: [
                {
                    label: "Standard Shipping",
                    detail: "Arrives in 5-7 days",
                    identifier: "standard",
                    amount: "0.00"
                },
                {
                    label: "Express Shipping",
                    detail: "Arrives in 2-3 days",
                    identifier: "express",
                    amount: "15.99"
                },
                {
                    label: "Next Day Shipping",
                    detail: "Arrives in 1 day",
                    identifier: "nextDay",
                    amount: "79.99"
                }
            ],
            shippingType: "shipping",
            supportedNetworks: [
                "visa",
                "masterCard",
                "amex",
                "discover"
            ],
            requiredBillingContactFields: [
                "postalAddress",
                "name",
            ],
            requiredShippingContactFields: [
                "postalAddress",
                "name",
                "phone",
                "email"
            ],
            lineItems: [
                { label: '20x Primo Mop', amount: '300.00' },
                { label: "Tax", amount: '0' },
            ],
            total: {
                label: "Total",
                amount: "300.00"
            },
            supportsCouponCode: true,
        }
	},
	on_success: function(data) {},
	on_error: function(data) {},
	on_update_payment_data: function(data) {},
	on_cancel: function(data) {}	
}
The on_success, on_error, on_update_payment_data and on_cancel functions can be determined according to your application requirements.

For example, this use case simply returns the token generated by the Apple Pay button.

Copy
Copied
    on_success: function (data) {
        console.log(data);
        document.getElementById('token').innerHTML = `<pre>${data.applePayToken}</pre>`;
    },
    on_error: function (error) {
        console.log("partner on_error: ", error);
        document.getElementById('token').innerHTML = `<pre>${error}</pre>`;
    },
    on_update_payment_data: function (intermediatePaymentData) {
        console.log("on_update_payment_data");
        return getNewPaymentMethodData(intermediatePaymentData);
    },
    on_cancel: function (data) {
        console.log("on cancel: ", data);
    }

Generate the iFrame

Once the configuration options have been assigned, and the DOM (Document Object Model) container has been set, you can call the Helper JS function to establish the iFrame by passing apple_pay_container_id and apple_pay_configs to the iFrame generating function.
Copy
Copied
WePay.createApplePayIframe(apple_pay_container_id, apple_pay_configs);
From this point, the Apple Pay button will generate a token which you then pass to the WePay API POST /payment_methods endpoint to complete the payment flow.

Completing Payment Flow

Use the token provided by the Apple Pay API by sending a POST /payment_methods call to WePay.
Token TTL

It is recommended that the payment token be processed within 24 hours. The token provided by the Apple Pay API has a time-to-live (TTL) of 24 hours.

jsoncurl
Copy
Copied
{
	"type": "apple_pay",
	"apple_pay": {
		"payment_method_data": "[THE_TOKEN_FROM_THE_APPLE_PAY_IFRAME]",
		"card_holder": {
			"holder_name": "Card Holder Name",
			"email": "carholder@emailserver.com",
			"address": {
				"country": "US",
				"postal_code": "00100"
			}
		}
	}
}
Copy
Copied
curl --location --request POST 'https://stage-api.wepay.com/payment_methods' \
--header 'Content-Type: application/json'
--header 'Api-Version: 3.1.rc.1.1' \
--header 'App-Id: {APP_ID}' \
--header 'App-Token: {APP_TOKEN}' \
--header 'Unique-Key: {GUID}' \
--data-raw '{
	"type": "apple_pay",
	"apple_pay": {
		"payment_method_data": "[THE_TOKEN_FROM_THE_APPLE_PAY_IFRAME]",
		"card_holder": {
			"holder_name": "Card Holder Name",
			"email": "carholder@emailserver.com",
			"address": {
				"country": "US",
				"postal_code": "00100"
			}
		}
	}
}'
Below is the sample response data from the call above. Retrieve the payment_method_id from the response.
jsoncurl
Copy
Copied
{
	"amount": 32775,
	"currency": "USD",
	"account_id": "",
	"payment_method": {
		"type": "payment_method_id",
		"payment_method_id": "<The response.payment_methods_id from POST /payment_methods>"
	}
}
Copy
Copied
curl --location --request POST 'https://stage-api.wepay.com/payments' \
--header 'Content-Type: application/json'
--header 'Api-Version: 3.1.rc.1.1' \
--header 'App-Id: {APP_ID}' \
--header 'App-Token: {APP_TOKEN}' \
--header 'Unique-Key: {GUID}' \
--raw-data '{
	"amount": 32775,
	"currency": "USD",
	"account_id": "",
	"payment_method": {
		"type": "payment_method_id",
		"payment_method_id": "<The response.payment_methods_id from POST /payment_methods>"
	}
}'

At this point the payment should be listed in the Merchant Center.