Every Banxa Native integration shares the same core steps: establish an identity, get a price, check eligibility, then execute payment. The payment method guides — bank transfer, Apple Pay, Google Pay, cards — each pick up from where this page leaves off.
Read this page once. Then follow the guide for your payment method.
Before you begin:
- HMAC API credentials — API key and secret from the Merchant Dashboard. Required for all server-to-server calls.
- A backend — all Native API calls use server-to-server HMAC authentication. Client-side API calls are not supported.
- An
identityReferencestrategy — a stable per-user identifier that you own. See Choosing an identityReference before proceeding. - The Banxa React Native SDK — required for card, Apple Pay, and Google Pay payments. Not required for bank transfers.
Install the SDK and its peer dependencies:
npm install @banxa-official/react-native-sdk @primer-io/react-native react-native-webview
cd ios && pod installInitialise the SDK once at app startup:
import { Banxa } from '@banxa-official/react-native-sdk';
const banxa = new Banxa({
apiKey: 'YOUR_API_KEY',
partner: 'your-partner-id',
environment: 'sandbox', // or 'production'
});For full SDK configuration options, see the React Native SDK Reference.
Before diving into the steps below, decide how much of the flow you want to own. This guide documents the full control approach — steps 1–4 below apply to that path.
Your backend handles identity, pricing, and eligibility before payment is invoked. You call the SDK only at the payment step. Any screens for collecting KYC requirements are yours — your design, your brand, your UX.
This is the recommended approach for most Banxa Native integrations.
Call createOrderAndShowPrimerCheckout without running eligibility first. The SDK creates the order and Banxa routes the user automatically: verified users go directly to the native payment sheet; users who need KYC are routed to a Banxa-hosted WebView where Banxa handles verification.
const result = await banxa.buy.createOrderAndShowPrimerCheckout(orderRequest, {
paymentMethod: 'applePay', // 'card' | 'applePay' | 'googlePay'
callbacks: {
onCheckoutComplete: () => { /* payment succeeded */ },
onError: (error) => { /* payment failed or unavailable */ },
onDismiss: () => { /* user dismissed */ },
},
});
if (isPrimerCheckoutWebViewResult(result)) {
// Banxa routed to hosted WebView (KYC required or payment method unavailable natively)
// render <CheckoutWebView {...result.webViewProps} />
}The trade-off: Banxa runs eligibility internally and you don't see the result. If the user needs KYC, it happens in Banxa's WebView — outside your product.
Use quick start when you want the simplest possible path to a working integration — for example, during early development — or when you're explicitly comfortable with Banxa handling KYC for users who need it. It is available for the React Native SDK only. If you choose this path, skip steps 3 and 4 below.
Create an identity record for the user before checking eligibility. The minimum required field is identityReference — include any personal details you already have, as they reduce the likelihood of requirements being returned at eligibility.
POST /eapi/v0/identities/basic
Content-Type: application/json
{
"identityReference": "partner-abc123",
"email": "[email protected]",
"dateOfBirth": "1990-01-15"
}For returning users, reuse the existing identityReference. If you don't have it stored, see Choosing an identityReference for retrieval options and all new-user flow variants.
If you attempt to create an identity for an email that already exists in Banxa, you will receive a 422 with code 81: "This identity exists for this reference or email address." Do not retry the creation. Instead, retrieve the existing identity using GET /eapi/v0/identities/{identityReference}[email protected] — Banxa returns the actual identityReference linked to that email, regardless of what value you supply in the path parameter.
If you verify users with Sumsub, share the verification token at this point. Token sharing satisfies NAME, DOB, SELFIE, and DOCUMENT requirements upfront so eligibility is more likely to return paymentReady: true on the first check. See KYC Token Sharing.
There are two pricing endpoints:
| Endpoint | Rate locked? | Expiry to manage? |
|---|---|---|
GET /eapi/v0/price | No | No |
GET /eapi/v0/quote | Yes — quoteId with 3-minute TTL | Yes |
This guide uses indicative pricing. It can be called at any point in the flow and has no expiry to handle. The trade-off is that the rate is not locked — if you display a price and then create the ramp without refreshing, the rate may have moved and the user receives a different amount than shown. Refresh the price close to ramp creation to minimise the gap.
The locked quote (GET /eapi/v0/quote) eliminates this risk but is only supported for bank transfer ramp creation — the React Native SDK and Embedded Payment Button do not accept a quoteId.
GET /eapi/v0/price?fiat=AUD&crypto=USDT&blockchain=TRON&method=payid-bank-transfer&transactionType=ONRAMP&fiatAmount=500Pass fiatAmount or cryptoAmount — not both. If you're building a bank transfer integration and want to lock the rate shown on the confirmation screen, see Pricing & Quote ID.
Before every transaction, confirm the user is cleared to proceed. Eligibility evaluates the user's identity state against the transaction context — amount, payment method, and jurisdiction.
POST /eapi/v0/identities/transactions/eligibility
Content-Type: application/json
{
"identityReference": "partner-abc123",
"method": "payid-bank-transfer",
"transactionType": "ONRAMP",
"fiat": "AUD",
"crypto": "USDT",
"blockchain": "TRON",
"fiatAmount": "500"
}Response: cleared to proceed
{
"paymentReady": true,
"requirements": []
}Response: additional information required
{
"paymentReady": false,
"requirements": ["OCCUPATION", "SOURCE_FUNDS"]
}Do not create a ramp or invoke the SDK when paymentReady is false. See Interpreting Eligibility for the full requirements dictionary.
When eligibility returns requirements, collect the missing information in your UX and submit it before re-checking.
For structured fields (NAME, DOB, ADDRESS, OCCUPATION, SOURCE_FUNDS, PURPOSE_OF_TX, TIN, DOCUMENT, POA):
PATCH /eapi/v0/identities
Content-Type: application/json
{
"identityReference": "partner-abc123",
"email": "[email protected]",
"occupationIndustry": "Consulting, IT, or business services",
"occupation": "IT developer",
"sourceOfFunds": "Salary"
}email is required on every PATCH request. Partial updates are supported — include only the fields you're updating.
For SELFIE — complete KYC provider token sharing first. Token sharing may satisfy multiple requirements in a single call. Then submit any remaining structured fields via PATCH. See KYC Token Sharing.
After submitting, re-run eligibility. Repeat until paymentReady: true.
Once paymentReady: true is confirmed, proceed to your payment method guide for the execution step:
Bank Transfer
Fully API-driven. No SDK required. Banxa returns funding instructions for the user to complete the transfer.
Apple Pay
Native payment sheet via React Native SDK, or Embedded Payment Button for web apps. Requires platform setup.
Google Pay
Native payment sheet via React Native SDK, or Embedded Payment Button for web apps. Requires app-level approval for the SDK path.
Cards
Primer card input drawer via React Native SDK. Requires 3DS SDK setup.
Transactions are asynchronous. Configure a webhook endpoint to receive status updates:
{
"order_id": "b7f1ffbb2f1bd7a5e2ba152b4049d234",
"status": "COMPLETED",
"status_date": "2026-04-17 03:45:00",
"external_reason": "...",
"fiat_currency": "AUD",
"fiat_amount": "500.00",
"crypto_coin": "USDT",
"crypto_amount": "324.51",
"transaction_hash": "0x..."
}Acknowledge every webhook with a 200 response immediately, then process asynchronously. You can also poll directly using GET /eapi/v0/ramps/{id}. See Webhooks for the full payload schema and status values.