Apple Pay onboarding runbook
Step by step for getting a merchant live on Apple Pay with both an Adyen
and a Stripe certificate, so they can be switched between providers later
without shipping a new app version.
Each step is labelled [Merchant] or [Super].
What you end up with
| Merchant ID | Certificate from | Used when |
|---|---|---|
merchant.com.<app>.stripe | Stripe platform account | Card capability is STRIPE |
merchant.com.<app>.adyen | Adyen live Customer Area | Card capability is ADYEN, production |
merchant.com.<app>.adyen.test | Adyen test Customer Area | Card capability is ADYEN, testing |
Three identifiers, because Adyen requires separate ones for test and live while
Stripe uses one for both. All three go in the entitlement; only two are ever
referenced by the SDK at a time.
Phase 0 — Agree the names
[Super + Merchant] Settle the three identifiers before anyone clicks
anything. Renaming later means re-issuing certificates.
- Convention:
merchant.com.<reverse-domain>.<processor>, e.g.
merchant.com.acme.checkout.stripe. - Adyen's own convention appends
.testfor the test identifier. - [Super] Record them against the merchant in our systems — we need them
for debugging and certificate renewal.
Phase 1 — Apple setup
[Merchant]
-
Enrol in the Apple Developer Program
if not already. -
Register all three identifiers at
Apple Developer → Identifiers → Merchant IDs.
Registering an identifier is free and instant; leaving one without a
certificate is harmless. -
In Xcode: project settings → Signing & Capabilities → add the Apple
Pay capability → tick all three identifiers.This writes
com.apple.developer.in-app-paymentsas an array. Confirm it
lists all three:<key>com.apple.developer.in-app-payments</key> <array> <string>merchant.com.acme.checkout.stripe</string> <string>merchant.com.acme.checkout.adyen</string> <string>merchant.com.acme.checkout.adyen.test</string> </array> -
Tell Super the exact identifier strings.
Steps 2 and 3 are the only part that requires an app build. Everything after
this can be done without touching the app again.
Phase 2 — Stripe certificate
Run this if the merchant is launching on Stripe, or ahead of a switch to it.
-
[Super] iOS Certificate Settings
on the platform account → Add new application → follow the guide →
download the CSR. -
[Super] Send the CSR to the merchant, naming which identifier it is for.
-
[Merchant] At Apple, open
merchant.com.<app>.stripe→ Create
Certificate → upload Super's CSR.Do not generate your own CSR — Apple offers to, and it produces a
certificate Stripe cannot use. -
[Merchant] Download the resulting
.cerand send it to Super. -
[Super] Upload the
.cerin the Stripe dashboard.
One CSR issues exactly one certificate. If anything needs redoing, start again
from step 1 with a fresh CSR.
Phase 3 — Adyen certificate
Run this if the merchant is launching on Adyen, or ahead of a switch to it. Do
it twice — once against the live Customer Area for
merchant.com.<app>.adyen, once against test for ….adyen.test.
-
[Super] Customer Area → Developers > API credentials → select the
web service user that executes this merchant's transactions → Wallet
payment methods > Apple Pay → + Add → Use your own certificate →
enter the merchant identifier → Download CSR.Adyen ties the certificate to the API credential, unlike Stripe. Putting
it on the wrong web service user is a quiet failure — check this one. -
[Super] Send the CSR to the merchant, naming which identifier it is for.
-
[Merchant] At Apple, open the matching identifier → Create
Certificate → upload Super's CSR, skipping Apple's own CSR step. -
[Merchant] Download the
.cerand send it to Super. -
[Super] Upload the
.cerin the same Customer Area screen, then enable
Apple Pay as a payment method.
Phase 4 — App configuration
[Merchant] Pass every identifier that has a certificate:
<SuperPaymentsProvider
environment="production"
returnUrl="acmeapp://payment"
applePayMerchantId={{
stripe: 'merchant.com.acme.checkout.stripe',
adyen: {
test: 'merchant.com.acme.checkout.adyen.test',
live: 'merchant.com.acme.checkout.adyen',
},
}}
merchantName="Acme"
>
{children}
</SuperPaymentsProvider>- Each value must match the entitlement exactly.
- Supplying both providers is what makes a later switch release-free. The SDK
uses whichever matches the active card capability and ignores the other. adyentakes{ test, live }because Adyen requires separate identifiers;
the SDK picks one using theenvironmentprop, so there is nothing to swap
by hand when moving to production. A plain string is accepted when only one
environment is in play.merchantNameis what the sheet shows as "Pay Acme £10.00".
[Merchant] Ship a signed build. The entitlement does nothing in a
simulator or unsigned build.
Phase 5 — Verify
[Merchant], on a real device with a real card in Wallet:
- The Apple Pay button appears in the sheet.
- Tapping it opens the Apple Pay sheet — this is the real test. A button that
renders proves nothing; the entitlement is only checked at presentation. - A payment completes end to end.
Testing differs by provider:
- Stripe — real Apple ID, real card,
environment="test". Stripe detects
the test key and returns a test token without charging. Sandbox tester
accounts and Stripe test cards do not work. - Adyen — the SDK selects the
.testidentifier automatically for any
non-productionenvironment, and Apple sandbox tester accounts are
supported.
If the sheet fails to present, go to
Troubleshooting — it is nearly always a
mismatch between entitlement, prop and certificate.
Phase 6 — Switching provider later
Once both certificates exist and both identifiers are in the shipped app:
- [Super] Flip the merchant's card capability on the backend.
- [Merchant] Nothing. No release, no store review, no user update.
The SDK reads the new providerData.type and uses the matching merchant ID.
To roll back, flip the capability again.
If the incoming provider's certificate was never set up, do Phase 2 or 3 first
— it can be done entirely ahead of the switch, since an unused identifier with
a valid certificate sits idle until the capability flips.
If the second identifier never made it into the entitlement, the switch is
still possible without a release but becomes a hard cutover: revoke the old
certificate at Apple and issue a new one from the incoming processor's CSR
against the same identifier. Expect a window with Apple Pay failing, both
processors coordinated on one call, and no cheap rollback.
Handoff checklist
From merchant to Super
- All three Apple Merchant ID strings, exactly as registered
- Signed
.cerfor the Stripe identifier - Signed
.cerfor the Adyen live identifier - Signed
.cerfor the Adyen test identifier - Confirmation the entitlement lists all three
- App Store version the entitlement first shipped in
From Super to merchant
- Stripe CSR
- Adyen live CSR
- Adyen test CSR
- Confirmation each
.ceris uploaded and Apple Pay is enabled
Super's internal record, per merchant
- Merchant ID → provider mapping
- Certificate expiry dates (~25 months; they need re-issuing)
- Which Adyen web service user holds the certificate
- Which Stripe application entry corresponds to this merchant
Google Pay
Not part of this runbook — there is no merchant ID and no certificate for
either provider, so nothing is bound to the app binary and switching provider
needs no Google-side work.
Updated 2 days ago
