Skip to content
Last updated

Apple Pay lets users pay with a card already saved to their device — no card entry, no redirect. The payment sheet is native, authenticated by Face ID or Touch ID, and dismisses back into your app once the transaction is confirmed.

Identity creation, KYC, eligibility, and OTP must be completed before reaching the payment step. See the Integration Guide if you haven't done this yet. This guide picks up from paymentReady: true.

Choose your approach

ApproachBest for
React Native SDKReact Native mobile apps
Embedded Payment ButtonWeb apps (Vanilla JS, React, Vue)
JS SDKWeb apps — coming soon

React Native SDK

iOS platform setup

Before writing any code, complete the following steps in your Apple Developer account.

You will need:

Coordinate with your Banxa integration contact before starting. They will provide the Certificate Signing Request (CSR) file required in Step 2.

Step 1 — Create a merchant identifier

A merchant identifier uniquely identifies your app to Apple Pay. It lives under your Apple Developer account, not Banxa's.

  1. Go to Certificates, Identifiers & Profiles
  2. Click Identifiers in the sidebar, then +
  3. Select Merchant IDs, then click Continue
  4. Enter a description and an identifier — it must start with merchant. (e.g. merchant.com.yourcompany.yourapp)
  5. Click Continue, review, then Register

If you already have a merchant identifier for your app, you can reuse it — you do not need to create a new one.

Step 2 — Create a payment processing certificate

The payment processing certificate encrypts payment tokens. It must be created using a CSR provided by Banxa — do not generate your own CSR for this step.

Once you have the CSR file from your Banxa integration contact:

  1. Go to Certificates, Identifiers & Profiles
  2. Click Identifiers, filter by Merchant IDs, and select the one you created in Step 1
  3. Under Apple Pay Payment Processing Certificate, click Create Certificate
  4. Upload the .certSigningRequest file Banxa provided
  5. Click Continue, then Download to save the .cer file
  6. Send the .cer file back to your Banxa integration contact

Banxa will upload the certificate on their side. Wait for confirmation before proceeding. Do not move to Step 3 until you receive it.

Certificate expiry

Payment processing certificates expire every 25 months. When yours approaches expiry, repeat this step — Banxa will provide a fresh CSR.

Step 3 — Configure Xcode

  1. Open your project in Xcode and select your app target
  2. Go to the Signing & Capabilities tab
  3. Click + Capability and select Apple Pay
  4. Under the Apple Pay capability, click + and add the merchant identifier from Step 1

The merchant identifier you add here must exactly match the one registered with Banxa. A mismatch is the most common cause of Apple Pay failures at runtime.


Execute payment

After your backend confirms paymentReady: true from eligibility, call createOrderAndShowPrimerCheckout with paymentMethod: 'applePay':

import {
  isPrimerCheckoutWebViewResult,
} from '@banxa-official/react-native-sdk';

const result = await banxa.buy.createOrderAndShowPrimerCheckout(orderRequest, {
  paymentMethod: 'applePay',
  callbacks: {
    onCheckoutComplete: () => {
      // Apple Pay confirmed — transaction is in progress
    },
    onError: (error) => {
      // Apple Pay unavailable or failed — see error handling below
    },
    onDismiss: () => {
      // User dismissed the payment sheet without completing
    },
  },
});

if (isPrimerCheckoutWebViewResult(result)) {
  // Apple Pay unavailable for this session — SDK fell back to hosted WebView
  render(<CheckoutWebView {...result.webViewProps} />);
}

The orderRequest must include externalCustomerId — pass the same identityReference you used for eligibility.

Error handling

onError is called when Apple Pay is unavailable for the current session. Common causes:

  • User hasn't set up Apple Pay on their device
  • No cards added to Wallet
  • None of the user's cards match supported networks

Do not display an Apple Pay button until you've confirmed Apple Pay is available for the session.

Testing requires a real device

Apple Pay cannot be tested on the iOS simulator. The simulator will reach the payment sheet but fail at payment. Test on a real device with at least one card added to Wallet.

Testing

Use the sandbox environment and Banxa test credentials during development:

const banxa = new Banxa({
  environment: 'sandbox',
  // ...
});

Apple Pay testing requires a real iOS device with Apple Pay configured and at least one card added to Wallet.

Troubleshooting

The error codes below are Primer errors surfaced through the SDK.

Apple Pay button does not appear / [unable-to-present-payment-method]

Apple Pay is not available for the current user or session. Common reasons:

  • User has not set up Apple Pay on their device
  • No cards added to Wallet
  • None of the user's cards match supported networks
  • Device doesn't support Apple Pay

The SDK filters Apple Pay from available payment methods in these cases. Only show an Apple Pay option when the SDK confirms it's available.

[unable-to-make-payments-on-provided-networks]

  • Apple Pay capability not enabled in Xcode — check Signing & Capabilities
  • No valid card in Wallet
  • Card network not supported
  • Device restrictions (e.g. parental controls) enabled

Try on a different real device with a different card.

"Apple Pay Is Not Available in [App Name]" system error

The merchant identifier in Xcode does not match the one associated with the payment processing certificate. Verify:

  • The merchant identifier in your Xcode Apple Pay capability exactly matches the one registered with Banxa
  • Your Banxa integration contact has confirmed the certificate is active

[payment-cancelled] or payment sheet not presenting

The merchant identifier is incorrect or does not match what is configured in Xcode. Verify both are identical.

[server-error] 404: No Matching ProcessingCertificate

Entitlements are correct, but the certificate uploaded to Banxa's system doesn't match your Xcode project. Contact your Banxa integration contact to verify the certificate.

Going live

Ensure you are using production credentials and that your Banxa integration contact has confirmed the certificate is active in the production environment before releasing to the App Store.


Embedded Payment Button

The Embedded Payment Button renders Apple Pay inside a web component — no SDK install required. It is a web integration for Vanilla JS, React, and Vue apps.

Before you start: Contact your Banxa integration contact to get provisioned. Two things must be set up on Banxa's side: the button-only setting on your environment, and Apple Pay domain registration (covered below). Neither can be self-served. Two certificates are required per merchant for Apple Pay — Banxa creates these as part of provisioning.

Apple Pay is Apple devices only

Apple Pay only works on Apple devices. Do not show the Apple Pay button on Android or other devices — if a user on a non-Apple device triggers the payment sheet, the payment will fail. Detect the device and render only the appropriate payment method.

Environment-level setting

The button-only configuration applies to your entire environment. If it is enabled, the standard full checkout widget will no longer render for that environment. If you need both — for example, the button on one surface and full checkout on another — you will need a separate environment provisioned by Banxa.

Apple Pay domain setup

Apple Pay on web requires your domain to be registered with Apple. Banxa handles the Apple Developer console steps — your part is to provide your domain and host a verification file.

Step 1 — Share your domain with Banxa

Send your integration contact the domain that will host the iframe, for example app.yourcompany.com. Banxa will register it in Apple's system. If the button will be served from a subdomain, provide that specific subdomain — domain registration applies at the exact domain level and subdomains must be registered separately.

One Apple Merchant ID per domain

A domain can only be registered with one Apple Merchant ID. If your domain is already registered with another Apple Pay provider (for example, Coinbase Onramp), it cannot also be registered with Banxa. Partners using multiple Apple Pay providers must use separate domains or subdomains for each.

Step 2 — Host the domain association file

Once Banxa has registered your domain, they will send you an apple-developer-merchantid-domain-association file. Host it at both paths — some configurations require the .txt extension:

https://app.yourcompany.com/.well-known/apple-developer-merchantid-domain-association
https://app.yourcompany.com/.well-known/apple-developer-merchantid-domain-association.txt

The file must be publicly accessible before Banxa can verify the domain.

Step 3 — Confirmation

Once the file is live, let your Banxa integration contact know. They will verify the domain and confirm when Apple Pay is active for your environment.

Do not re-download the file from Apple

If the domain association file is downloaded again from Apple's developer console, the file contents change and your hosted copy becomes invalid. If this happens, Banxa will send you an updated file to re-host.

Install the web component

npm install @banxa-official/embedded-checkout-web-component

Import the package once to register the custom element:

import '@banxa-official/embedded-checkout-web-component';

Create an order

Once your backend confirms paymentReady: true from eligibility, create an order. This returns a checkoutUrl which you pass to the web component.

POST /{partner}/v2/buy
Content-Type: application/json
x-api-key: YOUR_API_KEY

{
  "externalCustomerId": "user-123",
  "fiat": "AUD",
  "crypto": "BTC",
  "walletAddress": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
  "fiatAmount": "500.00",
  "redirectUrl": "https://app.yourcompany.com/complete"
}

Embed the component

Pass the checkoutUrl as the source attribute:

<banxa-checkout source="https://checkout.banxa.com/..."></banxa-checkout>

The component stays hidden until the checkout page signals it is ready — at that point it resizes to fit the payment button and becomes visible.

Lifecycle callbacks

Assign functions to these properties on the element instance:

PropertyWhen called
onLoadingCheckout is loading
onReadyComponent is ready and visible
onPaymentPendingPayment initiated, awaiting confirmation
onCompletePayment completed successfully
onErrorAn error occurred

Each callback receives a detail object, not a DOM event.

Framework examples

<script type="module">
  import '@banxa-official/embedded-checkout-web-component';
</script>

<banxa-checkout id="checkout" source="https://checkout.banxa.com/..."></banxa-checkout>

<script>
  const el = document.getElementById('checkout');
  el.onLoading = (detail) => console.log('loading', detail);
  el.onReady = (detail) => console.log('ready', detail);
  el.onPaymentPending = (detail) => console.log('payment pending', detail);
  el.onComplete = (detail) => console.log('complete', detail);
  el.onError = (detail) => console.log('error', detail);
</script>

Going live

Before releasing to production:

  • Confirm with your Banxa integration contact that your environment is provisioned for the Embedded Payment Button
  • Confirm Apple Pay domain verification is complete for your production domain
  • Switch to production credentials for order creation