# React Native SDK Reference

The Banxa React Native SDK is the payment execution layer of Banxa Native. It's used alongside the Native API to present native payment sheets for cards, Apple Pay, and Google Pay — 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](/products/native-api/docs/guides/foundations).

> **Which SDK modules 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 — specifically `banxa.buy` and `createOrderAndShowPrimerCheckout` for card and wallet payments.
The full module reference is documented below for completeness.


## Installation


```bash
npm install @banxa-official/react-native-sdk @primer-io/react-native react-native-webview
```

`@primer-io/react-native` and `react-native-webview` are peer dependencies. For iOS, run `pod install` after installing.

## Creating a Banxa client


```typescript
import { Banxa } from '@banxa-official/react-native-sdk';

const banxa = new Banxa({
  apiKey: 'YOUR_API_KEY',
  partner: 'your-partner-id',
  environment: 'sandbox', // or 'production'
});
```

### Configuration options

| Option | Type | Required | Description |
|  --- | --- | --- | --- |
| `apiKey` | string | Yes | Your Banxa API key from the Partner Dashboard. |
| `partner` | string | Yes | Your partner identifier. |
| `environment` | `'sandbox'` | `'production'` | No | Defaults to `'production'`. |
| `baseUrl` | string | No | Custom base URL — overrides the environment-derived URL. |
| `primerCallbacks` | object | No | Primer checkout callbacks: `onCheckoutComplete`, `onError`, `onDismiss`. Defaults to `console.log`. |
| `primerSettings` | `Partial<PrimerSettings>` | No | Primer base settings (UI options, payment method options) merged into all Primer flows. |


## Primer customisation

Checkout UI for card, Apple Pay, and Google Pay is provided by `@primer-io/react-native`. Pass `primerSettings` on the `Banxa` constructor — the SDK merges them into Primer's `configure()` for checkout flows. The TypeScript type is `PrimerSettings` from `@primer-io/react-native` (typically passed as `Partial<PrimerSettings>`).

### Theme

`primerSettings.uiOptions.theme` accepts optional `colors` and `darkModeColors`. Each is a color set with the same optional keys. Every color uses the `IRgbaColor` shape: `{ red, green, blue, alpha }` with values from 0–255.

| Key | Role |
|  --- | --- |
| `mainColor` | Primary brand / accent. |
| `contrastingColor` | Contrasting surface to `mainColor`. |
| `background` | Screen / sheet background color. |
| `text` | Primary text color. |
| `contrastingText` | Text color on strong colored surfaces. |
| `borders` | Borders and dividers color. |
| `disabled` | Disabled controls color. |
| `error` | Error state emphasis color. |


### Example — theme and UI flags


```typescript
const banxa = new Banxa({
  apiKey: 'YOUR_API_KEY',
  partner: 'your-partner-id',
  environment: 'sandbox',
  primerSettings: {
    uiOptions: {
      appearanceMode: 'SYSTEM', // or 'LIGHT' / 'DARK'
      theme: {
        colors: {
          mainColor: { red: 7, green: 138, blue: 88, alpha: 255 },
          contrastingColor: { red: 255, green: 255, blue: 255, alpha: 255 },
          background: { red: 216, green: 242, blue: 240, alpha: 255 },
          text: { red: 7, green: 138, blue: 88, alpha: 255 },
          contrastingText: { red: 255, green: 255, blue: 255, alpha: 255 },
          borders: { red: 209, green: 96, blue: 209, alpha: 255 },
          disabled: { red: 100, green: 100, blue: 100, alpha: 255 },
          error: { red: 235, green: 126, blue: 16, alpha: 255 },
        },
        darkModeColors: {
          mainColor: { red: 1, green: 255, blue: 1, alpha: 255 },
          background: { red: 255, green: 1, blue: 255, alpha: 255 },
        },
      },
    },
  },
});
```

## Buy

The `banxa.buy` module handles buy orders (fiat → crypto). Endpoints use the `/buy` path.

### createOrder

Create a new buy order.


```typescript
const order = await banxa.buy.createOrder({
  externalCustomerId: 'user-123',
  fiat: 'USD',
  crypto: 'BTC',
  fiatAmount: '100',
  paymentMethodId: '1',
  walletAddress: '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa',
  redirectUrl: 'https://yourapp.com/success',
});

console.log('Order created:', order.id);
console.log('Checkout URL:', order.checkoutUrl);
```

### checkEligibility

Check whether an order can proceed before creating it. The response's `paymentReady` field determines whether to use the Primer native sheet or fall back to the WebView.


```typescript
const orderRequest = {
  externalCustomerId: 'user-123',
  fiat: 'USD',
  crypto: 'BTC',
  fiatAmount: '100',
  paymentMethodId: '1',
  walletAddress: '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa',
  redirectUrl: 'https://yourapp.com/success',
};

const eligibility = await banxa.buy.checkEligibility(orderRequest);

if (eligibility.paymentReady) {
  const checkoutResult = await banxa.buy.createOrderAndShowPrimerCheckout(orderRequest);
  // Primer shown; see createOrderAndShowPrimerCheckout below for the result shape
} else {
  const order = await banxa.buy.createOrder(orderRequest);
  const webViewProps = banxa.buy.initializeCheckoutWebView(order, { /* ... */ });
  // render <CheckoutWebView {...webViewProps} />
}
```

> Use `paymentReady` from the eligibility response to choose between Primer and WebView. Do not rely on other fields for gating.


### createOrderAndShowPrimerCheckout

Create an order and present the Primer native payment sheet in a single call. Falls back to a WebView result if the created order lacks a `nativeToken`.


```typescript
import {
  isPrimerCheckoutWebViewResult,
  type PrimerCheckoutPaymentMethod,
} from '@banxa-official/react-native-sdk';

const result = await banxa.buy.createOrderAndShowPrimerCheckout(orderRequest);

if (isPrimerCheckoutWebViewResult(result)) {
  // No nativeToken; checkoutUrl returned instead
  const { order, webViewProps } = result;
  // render <CheckoutWebView {...webViewProps} />
} else {
  // Primer was shown; result is the Order
  const order = result;
}
```

You can also pick the Primer flow explicitly:


```typescript
const method: PrimerCheckoutPaymentMethod = 'applePay'; // 'card' | 'applePay' | 'googlePay' | 'universal'

await banxa.buy.createOrderAndShowPrimerCheckout(orderRequest, {
  paymentMethod: method,
  callbacks: {
    onCheckoutComplete: () => { /* ... */ },
    onError: () => { /* ... */ },
    onDismiss: () => { /* ... */ },
  },
  // WebView fallback options, used only if nativeToken is missing
  webViewProps: {
    returnUrlOnSuccess: 'https://yourapp.com/success',
    onClose: () => { /* ... */ },
  },
});
```

If the order has neither `nativeToken` nor `checkoutUrl`, the method throws.

### getOrder

Retrieve a single buy order.


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

### getOrdersByAccount

Retrieve buy orders associated with a specific `externalCustomerId`.


```typescript
const userBuyOrders = await banxa.buy.getOrdersByAccount('user-123');
```

### initializeCheckoutWebView

Configure props for the `CheckoutWebView` component when falling back to the hosted checkout flow.


```typescript
import { CheckoutWebView } from '@banxa-official/react-native-sdk';
import { useState } from 'react';

const [showCheckout, setShowCheckout] = useState(false);

const webViewProps = banxa.buy.initializeCheckoutWebView(order, {
  onClose: () => setShowCheckout(false),
  onSuccess: (url) => {
    console.log('Payment successful', url);
    setShowCheckout(false);
  },
  onFailure: (url) => {
    console.log('Payment failed', url);
    setShowCheckout(false);
  },
  returnUrlOnSuccess: 'https://yourapp.com/success',
  returnUrlOnFailure: 'https://yourapp.com/failure',
});

// In your component render:
{showCheckout && <CheckoutWebView {...webViewProps} />}
```

## Prices

The `banxa.prices` module retrieves live quotes. Maps to `GET /quotes/{orderType}`. Either `fiatAmount` or `cryptoAmount` must be provided; `paymentMethodId` and `blockchain` are also required.

### getQuote

Retrieve a quote for a specific order type (`'buy'` or `'sell'`).


```typescript
const quote = await banxa.prices.getQuote('buy', {
  fiat: 'USD',
  crypto: 'BTC',
  fiatAmount: '100',
  paymentMethodId: '1',
  blockchain: 'bitcoin',
});

console.log('Crypto amount:', quote.cryptoAmount);
console.log('Fiat amount:', quote.fiatAmount);
console.log('Processing fee:', quote.processingFee);
console.log('Network fee:', quote.networkFee);
```

### getBuyQuote

Convenience method for buy quotes.


```typescript
const buyQuote = await banxa.prices.getBuyQuote({
  fiat: 'USD',
  crypto: 'BTC',
  fiatAmount: '100',
  paymentMethodId: '1',
  blockchain: 'bitcoin',
});
```

## Payment Methods

The `banxa.paymentMethods` module retrieves supported payment methods.


```typescript
// All payment methods
const paymentMethods = await banxa.paymentMethods.getPaymentMethods();

// Filtered by currency pair
const methods = await banxa.paymentMethods.getPaymentMethods('USD', 'BTC');

// Single payment method by ID
const method = await banxa.paymentMethods.getPaymentMethod(1);
```

## Countries

The `banxa.countries` module retrieves supported countries.


```typescript
const countries = await banxa.countries.getCountries();
const country = await banxa.countries.getCountry('US');
```

## Currencies

The `banxa.currencies` module retrieves supported fiat and crypto currencies. Fiat and crypto come from separate endpoints (`GET /fiats/{orderType}` and `GET /crypto/{orderType}`) — availability can differ between buy and sell flows.


```typescript
// Defaults to order type 'buy'
const fiatCurrencies = await banxa.currencies.getFiatCurrencies();
const cryptoCurrencies = await banxa.currencies.getCryptoCurrencies();

// Explicit order type — use 'sell' for sell flows
const sellFiats = await banxa.currencies.getFiats('sell');
const sellCrypto = await banxa.currencies.getCrypto('sell');

// No single-currency endpoint — look up from the list
const btc = cryptoCurrencies.find((c) => c.id === 'BTC');
```

## CheckoutWebView component

`CheckoutWebView` renders the hosted checkout when the native payment sheet isn't used.


```typescript
import { CheckoutWebView } from '@banxa-official/react-native-sdk';

<CheckoutWebView {...webViewProps} />
```

Use `banxa.buy.initializeCheckoutWebView(order, options)` to generate the props. The component detects navigation to your return URLs and triggers the appropriate callback.

## Error handling

The SDK throws `BanxaSDKError` for API and network failures.


```typescript
import { Banxa, BanxaSDKError } from '@banxa-official/react-native-sdk';

try {
  const order = await banxa.buy.createOrder({ /* ... */ });
} catch (error) {
  if (error instanceof BanxaSDKError) {
    console.error('Banxa API Error:', error.message);
    console.error('Error Code:', error.code);
    console.error('Status Code:', error.statusCode);
  } else {
    console.error('Unknown error:', error);
  }
}
```

### BanxaSDKError properties

| Property | Description |
|  --- | --- |
| `message` | Human-readable error description. |
| `code` | Banxa error code. |
| `statusCode` | HTTP status code from the API response. |


## TypeScript support

The SDK is written in TypeScript and ships with type definitions.


```typescript
import { Banxa, Order, Quote, PaymentMethod } from '@banxa-official/react-native-sdk';

const banxa = new Banxa({ /* ... */ });

const order: Order = await banxa.buy.createOrder({ /* ... */ });
const quote: Quote = await banxa.prices.getBuyQuote({ /* ... */ });
```

## React Native compatibility

- Uses the standard `fetch` API (available in React Native).
- `react-native-webview` and `@primer-io/react-native` are required peer dependencies.
- For iOS: run `cd ios && pod install` after installing.