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.
| Approach | Best for |
|---|---|
| React Native SDK | React Native mobile apps |
| Embedded Payment Button | Web apps (Vanilla JS, React, Vue) |
| JS SDK | Web apps — coming soon |
Before writing any code, complete the following steps in your Apple Developer account.
You will need:
- An active Apple Developer Program membership
- Access to Apple's Certificates, Identifiers & Profiles
- Xcode
Coordinate with your Banxa integration contact before starting. They will provide the Certificate Signing Request (CSR) file required in Step 2.
A merchant identifier uniquely identifies your app to Apple Pay. It lives under your Apple Developer account, not Banxa's.
- Go to Certificates, Identifiers & Profiles
- Click Identifiers in the sidebar, then +
- Select Merchant IDs, then click Continue
- Enter a description and an identifier — it must start with
merchant.(e.g.merchant.com.yourcompany.yourapp) - 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.
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:
- Go to Certificates, Identifiers & Profiles
- Click Identifiers, filter by Merchant IDs, and select the one you created in Step 1
- Under Apple Pay Payment Processing Certificate, click Create Certificate
- Upload the
.certSigningRequestfile Banxa provided - Click Continue, then Download to save the
.cerfile - Send the
.cerfile 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.
Payment processing certificates expire every 25 months. When yours approaches expiry, repeat this step — Banxa will provide a fresh CSR.
- Open your project in Xcode and select your app target
- Go to the Signing & Capabilities tab
- Click + Capability and select Apple Pay
- 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.
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.
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.
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.
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.
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.
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.
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 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.
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 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.
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.txtThe 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.
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.
npm install @banxa-official/embedded-checkout-web-componentImport the package once to register the custom element:
import '@banxa-official/embedded-checkout-web-component';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"
}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:
| Property | When called |
|---|---|
onLoading | Checkout is loading |
onReady | Component is ready and visible |
onPaymentPending | Payment initiated, awaiting confirmation |
onComplete | Payment completed successfully |
onError | An error occurred |
Each callback receives a detail object, not a DOM event.
<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>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