Apple Pay merchant tokens
An Apple Pay merchant token (MPAN) ties together a payment card, a business, and a customer, and enables the wallet holder to manage access to a card stored in their Apple wallet. Merchant Tokens allow for continuity across multiple devices enabling recurring payments independent of a device. For example, if someone upgrades to a new iPhone, their payment information is managed through a merchant token and remains active if they remove a card from their old device.
Merchant Tokens also come with lifecycle management features to monitor changes to a token or to see if a token has been revoked.
Merchant token types
You can use Apple Pay to request an MPAN in three ways:
- RecurringPaymentRequest
- AutomaticReloadPaymentRequest
- DeferredPaymentRequest
Each type of request has different parameters that affect how the user is presented with Apple Wallet. Almost all request types provide the option to supply a managementURL, which routes customers to a webpage to manage their payment methods. Requests also have the option to provide a tokenNotificationURL, which acts like a webhook endpoint that includes lifecycle events.
At this time, all three request types are available in iOS. iOS Merchant Tokens are only available on Xcode 14 and iOS Version 16.0 or later. However, DeferredPaymentRequest isn’t yet available for Apple Pay on the Web and is only available on Xcode 14.3 and iOS version 16.4 or later.
Recurring
PKRecurringPaymentRequest issues an MPAN in the context of a recurring payment like a subscription. Available on Apple Pay on the Web and iOS > v16.0.
Automatic reload
A PKAutomaticReloadPaymentRequest issues an MPAN for store card top-ups or a prepaid accounts. You can use parameters such as automaticReloadBilling to show billing details when the wallet holder sees Apple Pay as the payment method. Available on Apple Pay on the Web and iOS 16.0 or higher.
Deferred payment
PKDeferredPaymentRequest will issue an MPAN when utilized. This request type provides parameters relevant to the travel industry like freeCancelationDate and billingAgreement, which will appear when Apple Pay is presented to the user.
DeferredPaymentRequests, released in XCode version 14.3, aren’t yet available on Apple Pay on the Web, and are only compatible with devices running iOS 16.4 or higher.
Add Apple Pay merchant tokens
Express Checkout Element
After setting up your Express Checkout Element integration, you must adopt merchant tokens by setting the recurringPaymentRequest.
Implement an event handler for the click
event on the Express Checkout Element. You can then pass the applePay.recurringPaymentRequest
object.
element.on("click", (e) => { const options = { applePay: { recurringPaymentRequest: { paymentDescription: "Standard Subscription", regularBilling: { amount: 1000, label: "Standard Package", recurringPaymentStartDate: new Date("2023-03-31"), recurringPaymentEndDate: new Date("2024-03-31"), recurringPaymentIntervalUnit: "year", recurringPaymentIntervalCount: 1, }, billingAgreement: "billing agreement", managementURL: "https://stripe.com", }, }, }; e.resolve(options); });
Mobile Payment Element
When you enable and add Apple Pay, follow the instructions for setting up recurring payments. You must adopt merchant tokens by setting the recurringPaymentRequest or automaticReloadPaymentRequest properties on the PKPaymentRequest.
Merchant token auth rate monitoring
For Sigma users, the charges
table contains a card_token_type
enum field to indicate the charge is using an mpan
or dpan
card. The following Sigma query example calculates the MPAN auth rate:
-- deduplicated MPAN auth rate select 100.0 * count( case when charge_outcome in ('authorized', 'manual_review') then 1 end ) / count(*) as deduplicated_auth_rate_pct, count(*) as n_attempts from authentication_report_attempts a join charges c on c.id = a.charge_id where c.created >= date('2021-01-01') and c.card_tokenization_method = 'apple_pay' -- The new field added to charges table. and c.card_token_type = 'mpan' -- deduplicate multiple manual retries to a single representative charge and is_final_attempt