# JavaScript Native Payments SDK Reference

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](/products/hosted-checkout/docs/sdk-integration/sdk-reference): 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](/products/hosted-checkout/docs/referral-integration/javascript-sdk), which only builds referral URLs. This SDK creates orders and embeds checkout.


Why 'Native Payments' in the name?
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.

## Installation

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

The `@primer-io/primer-js` peer dependency is only needed for the native payment sheet, which is a Banxa Native feature (see [Native payment sheet](#native-payment-sheet-primer) below). For a Hosted Checkout iframe integration you do not need it.

## Entry points

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.

## Creating an API client

```typescript
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

| 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.

## Buy

### createOrder

Create a buy order. The response includes a `checkoutUrl` to load in the iframe.

```typescript
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](/products/hosted-checkout/docs/reference/faq).

### getOrder

Retrieve a single order by its Banxa order ID.

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

Maps to `GET /{partner}/v2/orders/{orderId}`.

## Hosted checkout component

The `<banxa-hosted-checkout>` web component embeds the Banxa checkout (`order.checkoutUrl`) in an iframe and detects return navigation for you.

```html
<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>
```

### Attributes

| 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. |


### Events

| 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](/products/hosted-checkout/docs/checkout-experience/iframe/webview-mobile).

## Eligibility-aware buy flow

`runBuyCheckoutFlow` creates the order and mounts the right component automatically. For a Hosted Checkout integration this resolves to the `<banxa-hosted-checkout>` iframe.

```typescript
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.

## Quotes

```typescript
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.

## Payment methods, currencies, and countries

```typescript
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();
```

## Error handling

API failures throw `BanxaApiError`.

```typescript
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

| 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](/products/hosted-checkout/docs/reference/error-codes).

## Native payment sheet (Primer)

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](https://banxa-enterprise.redocly.app/enterprise-api/v0-beta). Talk to Banxa if you'd like to discuss whether this is relevant for your integration.

## Not available in the SDK

For the following capabilities, use the [Banxa API](/products/hosted-checkout/docs/api-integration/api-integration-overview) directly:

| Capability | Reason | Alternative |
|  --- | --- | --- |
| KYC data sharing (Sumsub token share) | Requires HMAC authentication, which the SDK does not use | [KYC Sharing](/products/hosted-checkout/docs/identity-compliance/kyc-sharing) |
| Full order list (all orders across all customers) | Not exposed in the SDK | `GET /{partner}/v2/orders` |


## TypeScript support

The SDK is written in TypeScript and ships with type definitions for both entry points.

```typescript
import { BanxaApiClient } from '@banxa-official/javascript-native-payments-sdk';
import type { CreateOrderRequest, Order, Quote } from '@banxa-official/javascript-native-payments-sdk';
```

## Environment URLs

| Environment | Base URL |
|  --- | --- |
| Sandbox | `https://api.banxa-sandbox.com/{partner}/v2` |
| Production | `https://api.banxa.com/{partner}/v2` |


## Next steps

- [JS Native Payments SDK Integration Guide (Web)](/products/hosted-checkout/docs/sdk-integration/javascript-native-payments-sdk-guide): end-to-end walkthrough with code.
- [SDK Integration Overview](/products/hosted-checkout/docs/sdk-integration/overview): how the SDKs compare.
- [Banxa API Reference](/products/hosted-checkout/docs/api-integration/api-integration-overview): for capabilities not in the SDK.