Skip to content
Last updated

JavaScript Native Payments SDK Reference

The Banxa JavaScript Native Payments SDK is the payment execution layer of Banxa Native for web. It's the web counterpart to the React Native SDK: used alongside the Native API to present native card and wallet payments in the browser, the payment methods that can't be handled through the API alone due to PCI requirements.

Bank transfers are handled directly by the Native API and don't involve the SDK. For the end-to-end integration walkthrough, see the Integration Guide.

Which parts are relevant for Banxa Native? In a Banxa Native integration, your backend handles pricing, identity, and eligibility via the Native API. The SDK's role is limited to payment execution: the <banxa-primer-checkout> web component renders the native payment sheet in your page, gated on the eligibility paymentReady flag.

The full API surface is documented below for completeness.

Installation

npm install @banxa-official/javascript-native-payments-sdk

For native payment checkout, install the Primer peer dependency:

npm install @primer-io/primer-js

@primer-io/primer-js is an optional peer dependency, required only for the native checkout web component.

Entry points

The SDK ships dual module output (ESM + CJS) with separate server and browser entry points, so backend code never pulls in DOM or web component code.

ImportEnvironmentExports
@banxa-official/javascript-native-payments-sdkNode / serverBanxaApiClient, BanxaApiError, API types
@banxa-official/javascript-native-payments-sdk/apiNode / serverSame as above
@banxa-official/javascript-native-payments-sdk/webBrowserregisterBanxaCheckout, registerBanxaPrimerCheckout, registerBanxaHostedCheckout, runBuyCheckoutFlow, checkout and Primer types

The web entry does not auto-register custom elements. Call registerBanxaCheckout() (or register components individually) before using them.

Creating an API client

The BanxaApiClient is Node-safe and handles all Banxa API requests from your backend.

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'
});

Configuration options

OptionTypeRequiredDescription
apiKeystringYesYour Banxa API key from the Partner Dashboard.
partnerstringYesYour partner identifier.
environment'sandbox' | 'production'YesSelects the environment base URL.

Requests use x-api-key authentication. Keep the API key server-side, never in browser or client-side code.

Backend: create an order

Create a buy order from your backend, then return the payment token to your frontend.

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',
  paymentMethodId: 'debit-credit-card', // optional
  blockchain: 'TRON', // optional
});

// Native payments: pass this token to the checkout web component
const nativeToken = order.nativeToken;

createOrder maps to POST /v2/buy.

CreateOrderRequest

FieldRequiredDescription
externalCustomerIdYesYour customer reference. Use the same value across identity and eligibility flows.
fiatYesFiat currency code (for example AUD, USD).
cryptoYesCrypto currency code (for example USDT, BTC).
walletAddressYesCustomer wallet address.
redirectUrlYesURL the customer returns to after checkout completes, fails, or is cancelled.
fiatAmountOne ofFiat amount to buy.
cryptoAmountOne ofCrypto amount to buy.
paymentMethodIdNoPre-select a payment method (for example debit-credit-card).
blockchainNoBlockchain network for the crypto token.
walletAddressTagNoMemo or tag for wallets that require it.
externalOrderIdNoYour order reference.
discountCodeNoPromotion or discount code.
emailNoPre-fill the customer email.
metadataNoOpaque string returned on order lookup.
subPartnerIdNoChannel identifier (exchange, wallet, web, and so on).

Provide either fiatAmount or cryptoAmount. If both are set, Banxa uses cryptoAmount.

Pricing is indicative. The SDK does not accept a locked quoteId, so re-quote close to order creation to minimise rate drift.

Order response

FieldDescription
idBanxa order ID.
nativeTokenPrimer client token for <banxa-primer-checkout> (native payments).
checkoutUrlHosted checkout URL, used for the fallback flow when native payments are not available.
fiat, fiatAmount, crypto, cryptoAmount, blockchainOrder amounts and assets.
externalCustomerId, externalIdCustomer and external references.

Backend: check eligibility

Check whether an order can proceed before presenting the native payment sheet. The response's paymentReady field determines whether to render native Primer checkout or fall back to hosted checkout.

const eligibility = await client.checkOrderEligibility({
  externalCustomerId: 'user-123',
  fiat: 'AUD',
  crypto: 'USDT',
  fiatAmount: '100',
  walletAddress: '0x1234567890abcdef...',
  redirectUrl: 'https://yoursite.com/order-complete',
}, 'buy');

if (eligibility.paymentReady) {
  // safe to render native Primer checkout
}

checkOrderEligibility maps to POST /eligibility and takes the same body as createOrder plus the order type.

FieldDescription
eligibleWhether the order context is eligible.
paymentReadyWhen true, the customer can use native Primer checkout.
requirementsOutstanding KYC or compliance requirements when not payment-ready.
messageOptional human-readable detail.

Use paymentReady to choose between native Primer checkout and the hosted fallback. Do not rely on other fields for gating.

Frontend: native payment checkout

The <banxa-primer-checkout> web component renders the native payment sheet in your page. No redirect, no Banxa-hosted screen.

<script type="module">
  import { registerBanxaPrimerCheckout } from '@banxa-official/javascript-native-payments-sdk/web';

  registerBanxaPrimerCheckout();
</script>

<banxa-primer-checkout id="checkout" locale="en"></banxa-primer-checkout>

<script type="module">
  const response = await fetch('/api/create-order', { method: 'POST' });
  const { nativeToken } = await response.json();

  const checkout = document.getElementById('checkout');
  checkout.clientToken = nativeToken;

  checkout.addEventListener('banxa:payment-success', (event) => {
    console.log('Payment successful', event.detail);
  });

  checkout.addEventListener('banxa:payment-failure', (event) => {
    console.error('Payment failed', event.detail);
  });
</script>

Set the token via the clientToken property (or client-token attribute) after your backend returns nativeToken from createOrder.

Attributes

AttributeDescription
client-tokenRequired. Primer client token (order.nativeToken from createOrder).
localeLocale string (for example en).
layout-modepreset (default), auto, or custom.
payment-methodsComma-separated Primer types for preset mode (for example PAYMENT_CARD,APPLE_PAY).
loader-disabledDisable the loading placeholder.
custom-stylesCSS string injected into the component shadow root.

Properties

PropertyDescription
clientTokenGet or set the client-token attribute.
localeGet or set the locale.
layoutModeGet or set the layout mode.
paymentMethodsGet or set the preset payment methods.
checkoutLayoutProgrammatic CheckoutLayoutConfig, merged with attributes.
checkoutTemplateRaw HTML for custom layout mode.
loaderDisabledGet or set the loading placeholder.
customStylesGet or set custom CSS.

Methods

MethodDescription
refreshSession()Delegates to the Primer refreshSession() when available.

Events

Primer events are re-emitted on the host element with a banxa: prefix. Use native addEventListener.

EventDescription
banxa:readyCheckout ready.
banxa:payment-startPayment started.
banxa:payment-successPayment succeeded.
banxa:payment-failurePayment failed.
banxa:payment-cancelPayment cancelled.
banxa:state-changePrimer SDK state changed.
banxa:methods-updateAvailable payment methods updated.
banxa:card-success, banxa:card-errorCard validation events.
banxa:bin-data-available, banxa:bin-data-loading-changeCard BIN lookup events.
checkout-errorThe SDK failed to load or initialise (not prefixed).

Event detail objects are sanitised for JSON serialisation: DOM nodes and circular references are replaced with string placeholders.

Layout modes

ModeBehaviour
preset (default)Builds markup from paymentMethods (default: card plus Apple Pay). Card payments use a standalone Primer card form with slotted fields.
autoOmits the payments slot so Primer renders all session payment methods.
customUses checkoutTemplate, checkoutLayout.mainHtml, or a <template slot="checkout-layout"> child for full control.

Custom card forms must use Primer hosted input components only. Raw HTML inputs cannot host PCI card data. In preset mode a custom cardFormHtml is ignored with a console warning; use custom layout mode or the checkout-layout slot instead.

import { registerBanxaPrimerCheckout, PrimerPaymentMethodTypes } from '@banxa-official/javascript-native-payments-sdk/web';

registerBanxaPrimerCheckout();

const checkout = document.querySelector('banxa-primer-checkout');
checkout.checkoutLayout = {
  mode: 'preset',
  paymentMethods: [
    { type: PrimerPaymentMethodTypes.PAYMENT_CARD },
    { type: PrimerPaymentMethodTypes.APPLE_PAY },
  ],
};

Eligibility-aware buy flow

runBuyCheckoutFlow checks eligibility, creates the order, and selects the right UI automatically: native Primer checkout when paymentReady is true, or the hosted fallback when it isn't.

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`,
    paymentMethodId: 'debit-credit-card',
  },
  container,
});

if (mode === 'primer') {
  element.addEventListener('banxa:payment-success', () => { /* ... */ });
} else {
  element.addEventListener('banxa:checkout-success', () => { /* hosted fallback completed */ });
}
paymentReadynativeTokenResult
truepresent<banxa-primer-checkout> (native payment sheet)
false or no tokencheckoutUrl present<banxa-hosted-checkout> (hosted fallback iframe)
OptionDescription
skipEligibilityCheckSkip the eligibility call and assume payment-ready.
primerCheckoutOptionsPass-through for locale, layoutMode, checkoutLayout, checkoutTemplate, loaderDisabled, customStyles.

Use the same redirectUrl on your checkout page origin so the fallback iframe can detect return navigation after payment.

Quotes

Retrieve indicative pricing.

const quote = await client.getQuote({
  fiat: 'AUD',
  crypto: 'USDT',
  blockchain: 'TRON',
  paymentMethodId: 'debit-credit-card',
  fiatAmount: '100',
}, 'buy');

getQuote maps to GET /quotes/{orderType}. Either fiatAmount or cryptoAmount is required, along with fiat, crypto, blockchain, and paymentMethodId.

Payment methods, currencies, and countries

// Payment methods, optionally filtered by source, target, and country
const paymentMethods = await client.getPaymentMethods('AUD', 'USDT', 'AU');

// Currencies (default order type is 'buy')
const currencies = await client.getCurrencies('buy');
const fiats = await client.getFiatCurrencies('buy');
const crypto = await client.getCryptoCurrencies('buy');

// Countries
const countries = await client.getCountries();

Retrieve an order

const orderDetails = await client.getOrder(order.id);

getOrder maps to GET /orders/{orderId}.

Error handling

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);
  }
}

BanxaApiError properties

PropertyDescription
statusCodeHTTP status code from the API response.
responseBodyOptional raw response body.
errorsOptional array of BanxaApiErrorItem with per-field detail.

Show user-facing messages only from validated error fields. Do not expose raw error strings that may include internal detail.

TypeScript support

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 URLs

EnvironmentBase URL
Sandboxhttps://api.banxa-sandbox.com/{partner}/v2
Productionhttps://api.banxa.com/{partner}/v2