The Banxa JavaScript Native Payments SDK is a TypeScript-first interface to Banxa for web apps. It's the web counterpart to the React Native SDK: a Node-safe API client plus browser web components. For Banxa Hosted Checkout, it wraps the API in typed methods and provides a <banxa-hosted-checkout> web component that embeds the checkout in an iframe, so you don't have to wire up the iframe by hand.
Authentication uses the same x-api-key header as the API. Keep your API key server-side.
This is a different package from the referral JavaScript SDK, which only builds referral URLs. This SDK creates orders and embeds checkout.
The package name refers to its Banxa Native payment sheet capability, a separate feature for partners who run their own KYC. For Hosted Checkout, you're using it to create orders and embed the hosted checkout iframe, not the native payment sheet. Ignore the "Native Payments" framing unless you later move to Banxa Native.
npm install @banxa-official/javascript-native-payments-sdkThe @primer-io/primer-js peer dependency is only needed for the native payment sheet, which is a Banxa Native feature (see Native payment sheet below). For a Hosted Checkout iframe integration you do not need it.
Dual module output (ESM + CJS) with separate server and browser entry points, so backend code never pulls in DOM or web component code.
| Import | Environment | Exports |
|---|---|---|
@banxa-official/javascript-native-payments-sdk | Node / server | BanxaApiClient, BanxaApiError, API types |
@banxa-official/javascript-native-payments-sdk/api | Node / server | Same as above |
@banxa-official/javascript-native-payments-sdk/web | Browser | registerBanxaCheckout, registerBanxaHostedCheckout, runBuyCheckoutFlow, checkout types |
The web entry does not auto-register custom elements. Call registerBanxaCheckout() (or register components individually) before using them.
import { BanxaApiClient } from '@banxa-official/javascript-native-payments-sdk';
const client = new BanxaApiClient({
apiKey: process.env.BANXA_API_KEY,
partner: process.env.BANXA_PARTNER,
environment: 'sandbox', // or 'production'
});| Option | Type | Required | Description |
|---|---|---|---|
apiKey | string | Yes | Your v2 API key from the merchant dashboard. |
partner | string | Yes | Your partner identifier. |
environment | 'sandbox' | 'production' | Yes | Selects the environment base URL. |
Requests use x-api-key authentication. Keep the API key server-side, never in browser or client-side code.
Create a buy order. The response includes a checkoutUrl to load in the iframe.
const order = await client.createOrder({
externalCustomerId: 'user-123',
fiat: 'AUD',
crypto: 'USDT',
fiatAmount: '100', // or cryptoAmount, at least one is required
walletAddress: '0x1234567890abcdef...',
redirectUrl: 'https://yoursite.com/order-complete',
});Maps to POST /{partner}/v2/buy.
externalCustomerId is required. Use one stable identifier per customer, not per order. Provide either fiatAmount or cryptoAmount; if both are set, Banxa uses cryptoAmount. Pricing is indicative, the SDK does not accept a locked quoteId.
The checkoutUrl is valid for 1 minute from order creation and must be loaded within that window. Once loaded it does not expire. Create the order when the customer confirms and load it immediately. See FAQ.
Retrieve a single order by its Banxa order ID.
const orderDetails = await client.getOrder(order.id);Maps to GET /{partner}/v2/orders/{orderId}.
The <banxa-hosted-checkout> web component embeds the Banxa checkout (order.checkoutUrl) in an iframe and detects return navigation for you.
<script type="module">
import { registerBanxaHostedCheckout } from '@banxa-official/javascript-native-payments-sdk/web';
registerBanxaHostedCheckout();
</script>
<banxa-hosted-checkout id="checkout"></banxa-hosted-checkout>
<script type="module">
const response = await fetch('/api/create-order', { method: 'POST' });
const { checkoutUrl } = await response.json();
const checkout = document.getElementById('checkout');
checkout.setAttribute('checkout-url', checkoutUrl);
checkout.setAttribute('return-url', `${window.location.origin}/checkout/return`);
checkout.addEventListener('banxa:checkout-success', () => { /* completed */ });
checkout.addEventListener('banxa:checkout-failure', () => { /* failed */ });
checkout.addEventListener('banxa:checkout-cancelled', () => { /* cancelled */ });
</script>| Attribute | Description |
|---|---|
checkout-url | Required. Hosted checkout URL from createOrder. |
return-url | Redirect URL base used to detect success, failure, and cancel navigation. |
return-url-success | Optional override for success detection. |
return-url-failure | Optional override for failure detection. |
return-url-cancelled | Optional override for cancel detection. |
iframe-title | Accessible iframe title (default: Banxa checkout). |
custom-styles | CSS injected into the shadow root. |
| Event | Description |
|---|---|
banxa:checkout-success | The iframe navigated to the return success URL. |
banxa:checkout-failure | The iframe navigated to the return failure URL. |
banxa:checkout-cancelled | The iframe navigated to the return cancel URL. |
For camera permissions during KYC, the embedding page must grant camera and microphone. See Embedded Checkout, Mobile.
runBuyCheckoutFlow creates the order and mounts the right component automatically. For a Hosted Checkout integration this resolves to the <banxa-hosted-checkout> iframe.
import { BanxaApiClient } from '@banxa-official/javascript-native-payments-sdk';
import { runBuyCheckoutFlow } from '@banxa-official/javascript-native-payments-sdk/web';
const client = new BanxaApiClient({ apiKey, partner, environment: 'sandbox' });
const container = document.getElementById('checkout');
const { mode, order, element } = await runBuyCheckoutFlow({
client,
request: {
externalCustomerId: 'user-123',
fiat: 'AUD',
crypto: 'USDT',
fiatAmount: '100',
walletAddress: '0xabc',
redirectUrl: `${window.location.origin}/checkout/return`,
},
container,
});
element.addEventListener('banxa:checkout-success', () => { /* hosted iframe completed */ });Use the same redirectUrl on your checkout page origin so the iframe can detect return navigation when Banxa redirects after KYC or payment.
const quote = await client.getQuote({
fiat: 'AUD',
crypto: 'USDT',
blockchain: 'TRON',
paymentMethodId: 'debit-credit-card',
fiatAmount: '100',
}, 'buy');Maps to GET /{partner}/v2/quotes/{orderType}. Either fiatAmount or cryptoAmount is required, along with fiat, crypto, blockchain, and paymentMethodId. Quotes are indicative and carry no quote ID.
const paymentMethods = await client.getPaymentMethods('AUD', 'USDT', 'AU');
const currencies = await client.getCurrencies('buy');
const fiats = await client.getFiatCurrencies('buy');
const crypto = await client.getCryptoCurrencies('buy');
const countries = await client.getCountries();API failures throw BanxaApiError.
import { BanxaApiClient, BanxaApiError } from '@banxa-official/javascript-native-payments-sdk';
try {
const order = await client.createOrder({ /* ... */ });
} catch (error) {
if (error instanceof BanxaApiError) {
console.error('Status code:', error.statusCode);
console.error('Response body:', error.responseBody);
console.error('Errors:', error.errors);
} else {
console.error('Unknown error:', error);
}
}| Property | Description |
|---|---|
statusCode | HTTP status code from the API response. |
responseBody | Optional raw response body. |
errors | Optional array of BanxaApiErrorItem with per-field detail. |
For error codes and their meanings, see Error Codes.
The SDK also provides a <banxa-primer-checkout> web component that renders a native payment sheet for card, Apple Pay, and Google Pay directly in your page, with no iframe. This is a Banxa Native feature for partners who verify their own users and run their own KYC. See Banxa Native. Talk to Banxa if you'd like to discuss whether this is relevant for your integration.
For the following capabilities, use the Banxa API directly:
| Capability | Reason | Alternative |
|---|---|---|
| KYC data sharing (Sumsub token share) | Requires HMAC authentication, which the SDK does not use | KYC Sharing |
| Full order list (all orders across all customers) | Not exposed in the SDK | GET /{partner}/v2/orders |
The SDK is written in TypeScript and ships with type definitions for both entry points.
import { BanxaApiClient } from '@banxa-official/javascript-native-payments-sdk';
import type { CreateOrderRequest, Order, Quote } from '@banxa-official/javascript-native-payments-sdk';| Environment | Base URL |
|---|---|
| Sandbox | https://api.banxa-sandbox.com/{partner}/v2 |
| Production | https://api.banxa.com/{partner}/v2 |
- JS Native Payments SDK Integration Guide (Web): end-to-end walkthrough with code.
- SDK Integration Overview: how the SDKs compare.
- Banxa API Reference: for capabilities not in the SDK.