|
|
Modern e-commerce success is measured not only by traffic and conversion, but increasingly by how quickly a customer can complete a purchase. Every additional step in the checkout — entering an address, selecting a shipping option, typing card details — directly contributes to cart abandonment, especially on mobile devices where typing is cumbersome. Apple Pay Express Checkout addresses this challenge by enabling customers to complete an entire purchase with a single tap directly from the product page, cart, or mini-cart — without ever navigating through a traditional checkout process. All required information (shipping address, billing address, contact details, and payment credentials) is securely retrieved from the customer's Apple Wallet. |
This guide assumes that the merchant has already implemented standard Apple Pay on the Payone platform (button rendering, merchant validation, payment authorization, and token forwarding to Payone's PSP endpoint). It focuses on the incremental changes required to enable the Express experience and to handle dynamic shipping, address, and contact updates.
| Aspect | Standard Apple Pay | Apple Pay Express |
| Trigger location | Final checkout page (after address & shipping selected) | Product page, cart page, or mini-cart |
| Address collection | Collected by merchant beforehand | Collected directly via Apple Pay sheet |
| Shipping methods | Pre-selected by merchant | Dynamically shown & updated inside the sheet |
| requiredShippingContactFields | Optional | Mandatory (postalAddress, name, email, phone) |
| requiredBillingContactFields | Optional | Recommended (postalAddress, name) |
| shippingMethods | Optional | Required — at least one method must be provided |
| Event handlers | onvalidatemerchant, onpaymentauthorized | Adds onshippingcontactselected & onshippingmethodselected |
| Total recalculation | Static at the time of authorization | Dynamic — recalculated on every address/shipping change |
| Payone PSP integration | Default flow with Payment Authorization | Unchanged — same flow |
| Merchant certificates / Apple Merchant ID | Required | Unchanged — no changes |
---end
---end
---end
---end

---end
---end
---end
---end
In order to retrieve address information that is needed for the express checkout, following configuration steps below.
const paymentRequest = {
...,
"requiredBillingContactFields": [
"postalAddress",
"name"
],
"requiredShippingContactFields": [
"postalAddress",
"name",
"phone",
"email"
],
};
| Field | Purpose |
| requiredBillingContactFields | Forces Apple Pay to return billing details with the token. Required for Payone authorization in most regions. |
| requiredShipp | Triggers the address selector inside the Apple Pay sheet, enabling Express. |
---end
---end
Apple Pay exposes the following event handlers for Express. They are activated automatically when the corresponding fields are set in the ApplePayPaymentRequest.
| Event Handler | Triggered By | Description | Requirement |
| onshippingcontactselected | User selects/changes a shipping address | Validate the address and update shipping methods, totals, and line items. | Required for Express |
| onshippingmethodselected | User picks a different shipping method | Recalculate the total and line items. | Required for Express |
| onpaymentauthorized | User confirms payment with Face/Touch ID | Receive the encrypted token, billing/shipping address, and contact info. | Mandatory for Apple Pay |
Both onshippingcontactselected and onshippingmethodselected are used to dynamically update shipping cost and totals :
const newShippingMethods = methods;
const selected = newShippingMethods[0];
const newLineItems = [
{ label: 'Subtotal', amount: '100.00' },
{ label: 'Shipping', amount: selected.amount },
{ label: 'Tax', amount: tax }
];
const newTotal = {
label: 'My Store',
amount: (100 + Number(selected.amount) + Number(tax)).toFixed(2)
};
Return the corresponding update object to Apple Pay:
session.completeShippingContactSelection({
newShippingMethods,
newTotal,
newLineItems
});
Provide the shippingMethods array in the initial ApplePayPaymentRequest to define the available shipping options.
Each shipping method has the fields:
The first method in the array is used as the default. The list can be updated dynamically inside onshippingcontactselected (e.g., based on the selected country).
"shippingMethods": [
{
"label": "Free Standard Shipping",
"amount": "0.00",
"detail": "Arrives in 5-7 days",
"identifier": "standardShipping",
"dateComponentsRange": {
"startDateComponents": {
"years": 2026,
"months": 4,
"days": 27,
"hours": 0
},
"endDateComponents": {
"years": 2026,
"months": 4,
"days": 29,
"hours": 0
}
}
},
{
"label": "Express Shipping",
"amount": "1.00",
"detail": "Arrives in 2-3 days",
"identifier": "expressShipping",
"dateComponentsRange": {
"startDateComponents": {
"years": 2026,
"months": 4,
"days": 24,
"hours": 0
},
"endDateComponents": {
"years": 2026,
"months": 4,
"days": 25,
"hours": 0
}
}
}
]
Optional. Customizes the label shown in the payment sheet.
Sample suggestion:
| Value | Sheet Label |
| shipping | "Shipping" |
| delivery | "Delivery" |
| storePickup | "Store Pickup" |
| servicePickup | "Service Pickup" |
---end
After the customer authenticates via Touch ID / Face ID, the onpaymentauthorized event fires and you receive an ApplePayPayment object containing:
This token.paymentData payload must be forwarded to the Payone API (same flow as the standard Apple Pay integration — typically via the authorization / preauthorization request with clearingtype=wlt and wallettype=APL).
The billingContact and shippingContact returned here are the authoritative addresses for the order — your backend must use them when creating the order record.
---end
{
"token": {
"paymentData": {
"version": "EC_v1",
"data": "3+f4oOTwPa6f1UZ6tG...CE=",
"signature": "MIAGCSqGSIb3DQ...AAAA==",
"header": {
"ephemeralPublicKey": "MFkwEK...Md==",
"publicKeyHash": "l0CnXdMv...D1I=",
"transactionId": "32b...4f3"
}
},
"paymentMethod": {
"displayName": "Visa 1234",
"network": "Visa",
"type": "debit"
},
"transactionIdentifier": "32b...4f3"
},
"billingContact": {
"addressLines": ["1 Street", ""],
"administrativeArea": "",
"country": "United Kingdom",
"countryCode": "GB",
"familyName": "Appleseed",
"givenName": "John",
"locality": "London",
"postalCode": "AB12 3CD",
"subAdministrativeArea": "",
"subLocality": ""
},
"shippingContact": {
"addressLines": ["1 Street", ""],
"...": "..."
}
}
---end
{
"countryCode": "US",
"currencyCode": "USD",
"merchantCapabilities": [
"supports3DS",
"supportsDebit",
"supportsCredit"
],
"shippingMethods": [
{
"label": "Free Standard Shipping",
"amount": "0.00",
"detail": "Arrives in 5-7 days",
"identifier": "standardShipping",
"dateComponentsRange": {
"startDateComponents": { "years": 2026, "months": 4, "days": 27, "hours": 0 },
"endDateComponents": { "years": 2026, "months": 4, "days": 29, "hours": 0 }
}
},
{
"label": "Express Shipping",
"amount": "1.00",
"detail": "Arrives in 2-3 days",
"identifier": "expressShipping",
"dateComponentsRange": {
"startDateComponents": { "years": 2026, "months": 4, "days": 24, "hours": 0 },
"endDateComponents": { "years": 2026, "months": 4, "days": 25, "hours": 0 }
}
}
],
"shippingType": "shipping",
"supportedNetworks": ["visa", "masterCard", "amex", "discover"],
"requiredBillingContactFields": ["postalAddress", "name"],
"requiredShippingContactFields": ["postalAddress", "name", "phone", "email"],
"lineItems": [
{ "label": "Sales Tax", "amount": "0.00" },
{ "label": "Shipping", "amount": "0.00" }
],
"total": {
"label": "Demo",
"amount": "1.99",
"type": "final"
}
}
---end
---end