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 IDCertificate fromUsed when
merchant.com.<app>.stripeStripe platform accountCard capability is STRIPE
merchant.com.<app>.adyenAdyen live Customer AreaCard capability is ADYEN, production
merchant.com.<app>.adyen.testAdyen test Customer AreaCard 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 .test for 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]

  1. Enrol in the Apple Developer Program
    if not already.

  2. Register all three identifiers at
    Apple Developer → Identifiers → Merchant IDs.
    Registering an identifier is free and instant; leaving one without a
    certificate is harmless.

  3. In Xcode: project settings → Signing & Capabilities → add the Apple
    Pay
    capability → tick all three identifiers.

    This writes com.apple.developer.in-app-payments as 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>
  4. 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.

  1. [Super] iOS Certificate Settings
    on the platform account → Add new application → follow the guide →
    download the CSR.

  2. [Super] Send the CSR to the merchant, naming which identifier it is for.

  3. [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.

  4. [Merchant] Download the resulting .cer and send it to Super.

  5. [Super] Upload the .cer in 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.

  1. [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.

  2. [Super] Send the CSR to the merchant, naming which identifier it is for.

  3. [Merchant] At Apple, open the matching identifier → Create
    Certificate
    → upload Super's CSR, skipping Apple's own CSR step.

  4. [Merchant] Download the .cer and send it to Super.

  5. [Super] Upload the .cer in 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.
  • adyen takes { test, live } because Adyen requires separate identifiers;
    the SDK picks one using the environment prop, so there is nothing to swap
    by hand when moving to production. A plain string is accepted when only one
    environment is in play.
  • merchantName is 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:

  1. The Apple Pay button appears in the sheet.
  2. 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.
  3. 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 .test identifier automatically for any
    non-production environment, 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:

  1. [Super] Flip the merchant's card capability on the backend.
  2. [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 .cer for the Stripe identifier
  • Signed .cer for the Adyen live identifier
  • Signed .cer for 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 .cer is 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.


Did this page help you?