` in your application:
```html
```
Replace `CHECKOUT_URL` with the `checkoutUrl` from your order creation response, or your constructed referral URL.
---
## Required iframe attributes
| Attribute | Value | Purpose |
|---|---|---|
| `allow` | `payment; camera; microphone; encrypted-media` | Permits camera access for KYC, payment APIs, and encrypted media |
| `sandbox` | `allow-scripts allow-same-origin allow-forms allow-popups` | Allows the checkout to function correctly within the sandboxed context |
---
## When the checkout redirects out of the iFrame
In some scenarios the checkout will force a full redirect to the Banxa site rather than staying inside the iFrame:
- **KYC required** — if a customer needs to complete identity verification, they are redirected to Banxa to complete KYC (due to camera access limitations inside iFrames). On their next order, the checkout runs inside the iFrame as normal.
- **Apple Pay** — Apple Pay requires merchant certificate and domain configuration to work inside an iFrame. Contact your Banxa account manager to ensure Apple Pay is correctly set up for your integration.
- **iDEAL, Klarna, PayPal** — these payment methods redirect the customer out of the iFrame to complete their payment. Afterwards, the customer is returned to the Banxa order status page and can then return to your site.
- **Safari / browsers without third-party cookie support** — if the customer's browser blocks third-party cookies (default in Safari), the checkout cannot maintain its state in an iFrame and will redirect to the Banxa site to complete the order.
---
## Permissions Policy
If your page sets a `Permissions-Policy` or `Feature-Policy` header, ensure it does not restrict `camera` or `microphone` for the iframe origin.
**Example CSP that allows Banxa:**
```
Permissions-Policy: camera=("https://checkout.banxa.com"), microphone=("https://checkout.banxa.com")
```
---
## Detecting checkout completion
Monitor navigation by watching for your `redirectUrl` in the iframe `src`. You can also listen for `postMessage` events from the checkout — validate the origin before processing any message.
```javascript
// Validate origin before processing any postMessage from the checkout
window.addEventListener('message', (event) => {
if (event.origin !== 'https://checkout.banxa.com') return;
// Handle event.data as appropriate for your integration
});
```
---
## Sizing
The Banxa checkout is responsive. Minimum recommended dimensions:
- Width: `375px`
- Height: `600px`
For mobile breakpoints, consider showing the checkout as a full-screen modal overlay rather than an inline iframe.
---
## Content Security Policy
If your app uses a CSP, add Banxa to the `frame-src` directive:
```
Content-Security-Policy: frame-src https://checkout.banxa.com https://checkout.banxa-sandbox.com;
```
---
Source: https://docs.banxa.com/products/hosted-checkout/docs/checkout-experience/iframe/webview-mobile.md
---
title: "Embedded Checkout: Mobile WebView Setup | Banxa Docs"
description: "Configure Android WebView and iOS WKWebView for Banxa embedded checkout. Camera access, video playback, KYC liveness, and React Native/Flutter WebView examples."
---
# Embedded Checkout (iFrame) — Mobile Implementation
Loading the Banxa checkout in a mobile WebView requires specific configuration to support camera access, payment methods, and KYC flows.
---
## Android
### Use Custom Chrome Tabs (recommended)
If your integration includes Google Pay, use **Custom Chrome Tabs** instead of a standard WebView. Standard WebView does not support GPAY or ACH.
```kotlin
import androidx.browser.customtabs.CustomTabsIntent
val customTabsIntent = CustomTabsIntent.Builder().build()
customTabsIntent.launchUrl(context, Uri.parse(checkoutUrl))
```
### WebView (for integrations without Google Pay)
If you are not using Google Pay, you can use a WebView with the following configuration:
```kotlin
webView.settings.apply {
javaScriptEnabled = true
domStorageEnabled = true // Required: enables local storage
mediaPlaybackRequiresUserGesture = false // Required: enables video instructions
allowFileAccess = true
setSupportZoom(false)
}
// Enable camera access
webView.webChromeClient = object : WebChromeClient() {
override fun onPermissionRequest(request: PermissionRequest) {
request.grant(request.resources) // Grant camera/microphone
}
// Required for HTML5 video playback
override fun onShowCustomView(view: View, callback: CustomViewCallback) {
// Handle fullscreen video
}
}
```
Declare permissions in `AndroidManifest.xml`:
```xml
```
---
## iOS
### SFSafariViewController (recommended)
Use `SFSafariViewController` when your integration includes KYC liveness checks (Sumsub). Liveness checks cannot complete in a standard `WKWebView`.
```swift
import SafariServices
let safariVC = SFSafariViewController(url: URL(string: checkoutUrl)!)
present(safariVC, animated: true)
```
### WKWebView
If liveness checks are not required, `WKWebView` can be used with the following configuration:
```swift
import WebKit
let config = WKWebViewConfiguration()
config.allowsInlineMediaPlayback = true // Required
config.mediaTypesRequiringUserActionForPlayback = [] // Required: allow autoplay for video instructions
let webView = WKWebView(frame: .zero, configuration: config)
// Request camera permission
webView.uiDelegate = self // Implement WKUIDelegate
```
Implement `WKUIDelegate` to handle permission requests:
```swift
func webView(_ webView: WKWebView,
requestMediaCapturePermissionFor origin: WKSecurityOrigin,
initiatedByFrame frame: WKFrameInfo,
type: WKMediaCaptureType,
decisionHandler: @escaping (WKPermissionDecision) -> Void) {
decisionHandler(.grant)
}
```
Add to `Info.plist`:
```xml
NSCameraUsageDescription
Required for identity verification
NSMicrophoneUsageDescription
Required for identity verification
```
---
## React Native
Use `react-native-webview` with the following props:
```jsx
import { WebView } from 'react-native-webview';
{
// Detect redirect to your redirectUrl
if (navState.url.startsWith('https://yourapp.com/order-complete')) {
// Dismiss WebView and check order status
}
}}
/>
```
Camera and microphone access is controlled by OS-level permissions — set in `AndroidManifest.xml` and `Info.plist` as shown below, not via WebView props.
---
## Flutter
Use `webview_flutter` with the following configuration:
```dart
import 'package:webview_flutter/webview_flutter.dart';
late final WebViewController controller;
controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(NavigationDelegate(
onNavigationRequest: (NavigationRequest request) {
if (request.url.startsWith('https://yourapp.com/order-complete')) {
// Dismiss WebView
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
))
..loadRequest(Uri.parse(checkoutUrl));
```
For camera access on Android, add to `AndroidManifest.xml`:
```xml
```
---
## Payment methods that redirect out of the WebView
iDEAL, Klarna, and PayPal cannot complete inside a WebView. When a customer selects one of these methods, they will be redirected to an external browser to complete their payment. After payment, the customer is returned to the Banxa order status page — they will not be returned automatically to your WebView.
Design your post-payment UX accordingly: a confirmation screen with a link back to your app is the recommended pattern.
---
## Configuration checklist
| Requirement | Android | iOS |
|---|---|---|
| Local storage | `domStorageEnabled = true` | Enabled by default in WKWebView |
| Camera access | `onPermissionRequest` grant | `WKUIDelegate` + Info.plist |
| Video playback | `WebChromeClient` + `mediaPlaybackRequiresUserGesture = false` | `allowsInlineMediaPlayback = true` |
| KYC liveness | Custom Chrome Tabs or WebView | SFSafariViewController required |
| Google Pay | Custom Chrome Tabs required | Supported in WKWebView |
---
Source: https://docs.banxa.com/products/hosted-checkout/docs/checkout-experience/redirect/redirect-overview.md
---
title: "Redirect Checkout Integration Overview | Banxa Docs"
description: "Host the Banxa checkout on a co-branded page with full redirect. Zero embedding required, compatible with all payment methods including Apple Pay and Google Pay."
---
# Redirect Checkout — Overview
In the redirect checkout mode, the customer is sent to a Banxa-hosted page to complete their transaction. This page opens in a new tab or replaces the current window, depending on how you implement the redirect.
---
## How it works
1. Your app creates a checkout URL — either via a [Referral link](../../referral-integration/constructing-referral-urls.md) or the `checkoutUrl` returned by `POST /v2/buy` or `POST /v2/sell`.
2. The customer is redirected to that URL.
3. Banxa presents the full checkout flow: payment details, identity verification, and order confirmation.
4. On completion or cancellation, the customer is redirected back to your `redirectUrl`.
---
## Co-branding
The Banxa-hosted checkout page can be co-branded with your logo and configured with custom colours. These settings are managed in your Partner Dashboard. Contact Banxa to configure co-branding for your account.
---
## Advantages
- No embedding or WebView configuration required.
- Fully compatible with all payment methods, including those with complex browser requirements (Apple Pay, Google Pay, ACH).
- Works across web and mobile without platform-specific setup.
---
## Considerations
- The customer visibly leaves your application to complete the transaction.
- You have less control over the surrounding UI context during checkout.
---
## Implementation
→ [Web Implementation](./web.md)
→ [Mobile Implementation](./mobile.md)
---
Source: https://docs.banxa.com/products/hosted-checkout/docs/checkout-experience/redirect/web.md
---
title: "Redirect Checkout: Web Implementation | Banxa Docs"
description: "Open Banxa checkout in a new tab or same window on web. Covers return URL handling, orderId parsing, security attributes, and an async checkout flow example."
---
# Redirect Checkout — Web Implementation
---
## Opening the checkout
Use the `checkoutUrl` returned by `POST /v2/buy` or `POST /v2/sell` (API integration), or your constructed referral URL (Referral integration).
### New tab (recommended)
```javascript
function openBanxaCheckout(checkoutUrl) {
window.open(checkoutUrl, '_blank', 'noopener,noreferrer');
}
```
Opening in a new tab keeps your application visible in the background, so the customer can return to it after checkout completes.
### Same window
```javascript
function openBanxaCheckout(checkoutUrl) {
window.location.href = checkoutUrl;
}
```
Use this when you prefer a full-page transition. The customer will be redirected back to your `redirectUrl` on completion.
---
## Handling the return
When the customer finishes (or cancels) checkout, Banxa redirects them to the `redirectUrl` you specified when creating the order.
### Return URL parameters
Banxa can append order parameters to your return URL on completion, allowing you to read the outcome without an additional API call. Contact your Account Manager to enable this for your account.
When enabled, the following parameters are appended:
| Parameter | Description |
|---|---|
| `orderId` | The Banxa order ID |
| `orderRef` | Banxa's internal order reference |
| `orderStatus` | Final order status |
| `fulfillmentStatus` | Fulfilment status of the order |
| `paymentStatus` | Payment processing status |
| `identityStatus` | KYC/identity status |
| `fiatAmount` | Fiat amount in the order |
| `fiat` | Fiat currency code |
| `coinAmount` | Crypto amount in the order |
| `coin` | Cryptocurrency code |
**Tip:** To link the customer to the Banxa order status page, append the `orderRef` value to your return URL — e.g. `https://{partnerRef}.banxa.com/status/{orderRef}`.
For the authoritative order status, use the [order lookup endpoint](../../transaction-lifecycle/order-lookup.md) or [webhooks](../../transaction-lifecycle/webhooks.md) — do not rely solely on return URL parameters.
---
## Security
Set `noopener,noreferrer` when opening in a new tab to prevent the checkout page from accessing your `window` object.
---
## Example flow
```javascript
async function startBanxaCheckout(orderParams) {
// 1. Create order
const response = await fetch('/api/create-banxa-order', {
method: 'POST',
body: JSON.stringify(orderParams)
});
const { checkoutUrl, orderId } = await response.json();
// 2. Store orderId for later status lookup
sessionStorage.setItem('pendingBanxaOrderId', orderId);
// 3. Redirect customer to checkout
window.open(checkoutUrl, '_blank', 'noopener,noreferrer');
}
```
---
Source: https://docs.banxa.com/products/hosted-checkout/docs/checkout-experience/redirect/mobile.md
---
title: "Redirect Checkout: Mobile Implementation | Banxa Docs"
description: "Open Banxa checkout on mobile using Custom Chrome Tabs (Android), SFSafariViewController (iOS), React Native InAppBrowser, and Flutter url_launcher."
---
# Redirect Checkout — Mobile Implementation
On mobile, opening the Banxa checkout in an external browser is the simplest integration path. It avoids all WebView configuration complexity and is compatible with all payment methods.
---
## Android
Use **Custom Chrome Tabs** to open the checkout URL. This provides a browser-quality experience while keeping the customer in your app's task stack.
### Implementation
```kotlin
// Kotlin
import androidx.browser.customtabs.CustomTabsIntent
fun openBanxaCheckout(context: Context, checkoutUrl: String) {
val customTabsIntent = CustomTabsIntent.Builder()
.setShowTitle(true)
.build()
customTabsIntent.launchUrl(context, Uri.parse(checkoutUrl))
}
```
```java
// Java
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder()
.setShowTitle(true)
.build();
customTabsIntent.launchUrl(context, Uri.parse(checkoutUrl));
```
Add the dependency to your `build.gradle`:
```groovy
implementation 'androidx.browser:browser:1.5.0'
```
---
## iOS
Use **`SFSafariViewController`** to open the checkout URL. This gives customers a full Safari experience (including saved passwords and Apple Pay) while staying within your app.
```swift
// Swift
import SafariServices
func openBanxaCheckout(url: URL) {
let safariVC = SFSafariViewController(url: url)
present(safariVC, animated: true)
}
```
---
## React Native
Use the `react-native-inappbrowser-reborn` package or `Linking` to open the checkout URL in the device browser or an in-app browser view.
```javascript
import { Linking } from 'react-native';
// or
import InAppBrowser from 'react-native-inappbrowser-reborn';
async function openBanxaCheckout(checkoutUrl) {
if (await InAppBrowser.isAvailable()) {
await InAppBrowser.open(checkoutUrl, {
// iOS
dismissButtonStyle: 'cancel',
preferredBarTintColor: '#000000',
// Android
showTitle: true,
enableUrlBarHiding: true,
});
} else {
Linking.openURL(checkoutUrl);
}
}
```
---
## Flutter
Use the `url_launcher` package to open the checkout URL in a Custom Tab (Android) or `SFSafariViewController` (iOS).
```dart
import 'package:url_launcher/url_launcher.dart';
Future openBanxaCheckout(String checkoutUrl) async {
final uri = Uri.parse(checkoutUrl);
if (await canLaunchUrl(uri)) {
await launchUrl(
uri,
mode: LaunchMode.externalApplication, // opens Custom Tab / SFSafariVC
);
}
}
```
Add the dependency to `pubspec.yaml`:
```yaml
dependencies:
url_launcher: ^6.1.0
```
---
## Handling the return
When checkout is complete, Banxa redirects to your `redirectUrl`. Handle this using your platform's deep link or URL scheme handling, then look up the order status via webhook or the order lookup endpoint.
---
Source: https://docs.banxa.com/products/hosted-checkout/docs/reference/supported-cryptocurrencies-and-blockchains.md
---
title: "Supported Crypto Assets & Blockchains | Banxa Docs"
description: "Complete list of cryptocurrencies and blockchain networks supported by Banxa for on-ramp and off-ramp. Includes buy/sell availability and geographic restrictions."
---
# Supported Cryptocurrencies & Blockchains
All cryptocurrencies and blockchain networks supported by Banxa for on-ramp and off-ramp transactions. Banxa is continuously adding new assets and networks — use **Cmd+F** (or **Ctrl+F**) to search this page.
The live list can be retrieved via the cryptocurrency lookup endpoint in your product's API Reference. Pass `buy` or `sell` to filter by transaction direction.
**Column key:** ✅ Supported · ❌ Not supported · Restricted Geos\* = not available in listed countries · Restricted US States\*\* = not available in listed US states.
---
## A–C
| Code | Name | Network | Buy | Sell | Restricted Geos* | Restricted US States** |
|---|---|---|---|---|---|---|
| AAVE | Aave | BSC | ✅ | ❌ | — | AS, PA, TX, VA, WA, WI |
| AAVE | Aave | ETH | ✅ | ❌ | — | — |
| ACA | Acala | ACA | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| ADA | Cardano | ADA | ✅ | ✅ | UK | — |
| ALEO | Aleo | ALEO | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| ALGO | Algorand | ALGO | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| APE | ApeCoin | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| APT | Aptos | APT | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| ARB | Arbitrum | ARB | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| ATOM | Cosmos | ATOM | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| AVAX | Avalanche | AVAX | ✅ | ✅ | UK | — |
| AXS | Axie Infinity | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| BCH | Bitcoin Cash | BCH | ✅ | ✅ | UK | — |
| BNB | BNB | BSC | ✅ | ✅ | UK | — |
| BTC | Bitcoin | BTC | ✅ | ✅ | — | — |
| BUSD | Binance USD | BSC | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
---
## D–G
| Code | Name | Network | Buy | Sell | Restricted Geos* | Restricted US States** |
|---|---|---|---|---|---|---|
| DAI | Dai | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| DAI | Dai | POLY | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| DOGE | Dogecoin | DOGE | ✅ | ✅ | UK | — |
| DOT | Polkadot | DOT | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| ENS | Ethereum Name Service | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| EOS | EOS | EOS | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| ETH | Ethereum | ETH | ✅ | ✅ | — | — |
| ETHW | EthereumPoW | ETHW | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| FIL | Filecoin | FIL | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| FLOKI | Floki | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| FLR | Flare | FLR | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| FTM | Fantom | FTM | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| GALA | Gala | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| GMT | STEPN | BSC | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
---
## H–L
| Code | Name | Network | Buy | Sell | Restricted Geos* | Restricted US States** |
|---|---|---|---|---|---|---|
| HBAR | Hedera | HBAR | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| ICP | Internet Computer | ICP | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| IMX | Immutable X | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| INJ | Injective | INJ | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| JASMY | JasmyCoin | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| KAVA | Kava | KAVA | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| KDA | Kadena | KDA | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| LINK | Chainlink | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| LTC | Litecoin | LTC | ✅ | ✅ | — | — |
| LUNA | Terra 2.0 | LUNA | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
---
## M–P
| Code | Name | Network | Buy | Sell | Restricted Geos* | Restricted US States** |
|---|---|---|---|---|---|---|
| MANA | Decentraland | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| MATIC | Polygon | POLY | ✅ | ✅ | UK | — |
| MINA | Mina | MINA | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| MKR | Maker | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| NEAR | NEAR Protocol | NEAR | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| ONE | Harmony | ONE | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| OP | Optimism | OP | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| PEPE | Pepe | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
---
## Q–S
| Code | Name | Network | Buy | Sell | Restricted Geos* | Restricted US States** |
|---|---|---|---|---|---|---|
| ROSE | Oasis Network | ROSE | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| SAND | The Sandbox | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| SHIB | Shiba Inu | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| SKL | SKALE | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| SOL | Solana | SOL | ✅ | ✅ | UK | — |
| SUPRA | Supra | SUPRA | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| SUI | Sui | SUI | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
---
## T–V
| Code | Name | Network | Buy | Sell | Restricted Geos* | Restricted US States** |
|---|---|---|---|---|---|---|
| TON | Toncoin | TON | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| TRX | TRON | TRX | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| UNI | Uniswap | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| USDC | USD Coin | ETH | ✅ | ✅ | UK | — |
| USDC | USD Coin | POLY | ✅ | ✅ | UK | — |
| USDC | USD Coin | SOL | ✅ | ✅ | UK | — |
| USDT | Tether | ETH | ✅ | ✅ | UK | — |
| USDT | Tether | TRX | ✅ | ✅ | UK | — |
| USDT | Tether | BSC | ✅ | ✅ | UK | — |
---
## W–Z
| Code | Name | Network | Buy | Sell | Restricted Geos* | Restricted US States** |
|---|---|---|---|---|---|---|
| WBTC | Wrapped Bitcoin | ETH | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| XLM | Stellar | XLM | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
| XRP | XRP | XRP | ✅ | ✅ | — | — |
| ZIL | Zilliqa | ZIL | ✅ | ❌ | UK | AS, PA, TX, VA, WA, WI |
---
> **Note:** This list is updated periodically. For the live list as configured for your partner account, use `GET /{partnerRef}/v2/crypto`. Assets shown here may be subject to your specific partner configuration — not all assets are available to all partners by default. Contact Banxa to enable specific assets.
---
Source: https://docs.banxa.com/products/hosted-checkout/docs/reference/supported-payment-methods.md
---
title: Supported Payment Methods
description: All Banxa payment methods by region for buy and sell transactions, including supported currencies, countries, and API retrieval.
---
# Supported Payment Methods
Banxa supports a range of payment methods across different regions for **buy (on-ramp)** and **sell (off-ramp)** transactions.
Availability may vary depending on the **customer's region**, **selected fiat currency**, and **order type**.
Your integration can retrieve supported payment methods dynamically using the **Payment Methods API**. This endpoint should be used as the source of truth for availability.
---
## Payment methods overview
| Payment Method | Buy | Sell | Region | Description | Payment Speed | Supported Currency | Details |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| Debit / Credit Cards | ✅ | ❌ | Worldwide | Card payments using Visa and MasterCard networks. | Instant | Multiple | [View details](#debit--credit-cards) |
| Apple Pay | ✅ | ❌ | Worldwide | Apple Pay payments using Visa or MasterCard cards stored in Apple Wallet. | Instant | Multiple | [View details](#apple-pay) |
| Google Pay | ✅ | ❌ | Worldwide | Google Pay payments using Visa or MasterCard cards stored in Google Wallet. | Instant | Multiple | [View details](#google-pay) |
| PayPal | ✅ | ❌ | Europe (EU/EEA) | Secure, MiCA-compliant on-ramp using PayPal balance or linked funding sources. | Instant | EUR | [View details](#paypal) |
| Card Payouts (Sell) | ❌ | ✅ | Selected European countries | Digital transfers directly to a recipient's debit or credit card. | Instant | EUR | [Supported countries](#card-payouts) |
| PayID | ✅ | ❌ | Australia | Australian bank transfer using PayID. | Instant | AUD | — |
| NPP Direct Entry | ✅ | ✅ | Australia | Australian bank transfer using BSB and account number. | Instant | AUD | — |
| iDEAL | ✅ | ❌ | Netherlands | Online payment method allowing customers to pay directly from their bank account in real time. | Instant | EUR | — |
| SEPA | ✅ | ✅ | Europe | Bank transfers within the Single Euro Payments Area (SEPA). | 1–3 Business Days | EUR | — |
| Klarna – Pay Now | ✅ | ❌ | Selected European countries | One-click payment allowing customers to pay immediately using their Klarna account. | Instant – 1 day | EUR, SEK | [Supported countries](#klarna--pay-now) |
| Faster Payments | ✅ | ✅ | United Kingdom | Real-time bank transfer network used in the United Kingdom. | Instant | GBP | — |
| Interac | ✅ | ✅ | Canada | Canada's domestic debit network allowing bank-to-bank payments. | Instant | CAD | — |
| ACH | ✅ | ✅ | United States | Electronic bank-to-bank transfers within the United States. | 1–3 Business Days | USD | — |
| PIX | ✅ | ✅ | Brazil | Real-time payment system operated by the Central Bank of Brazil. | Instant | BRL | — |
| SPEI | ✅ | ❌ | Mexico | Real-time electronic funds transfer system operated by the Bank of Mexico (Banxico). | Instant | MXN | — |
| Khipu | ✅ | ❌ | Chile | Redirect-based bank transfer solution supporting major Chilean banks. | Instant | CLP | — |
| Local Bank Transfer (South Africa) | ✅ | ❌ | South Africa | Localised bank transfer methods allowing customers to pay directly from their bank accounts. | Instant | ZAR | — |
---
## Payment method details
### Debit / Credit Cards
Supported Fiat Currencies
AUD, AED, BRL, CAD, CHF, CZK, DKK, EUR, GBP, HKD, IDR, INR, JPY, MXN, NOK, NZD, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR
---
### Apple Pay
Supported Fiat Currencies
AUD, AED, BRL, CAD, CHF, CZK, DKK, EUR, GBP, HKD, IDR, INR, JPY, MXN, NOK, NZD, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR
---
### Google Pay
Supported Fiat Currencies
AUD, AED, BRL, CAD, CHF, CZK, DKK, EUR, GBP, HKD, IDR, INR, JPY, MXN, NOK, NZD, PHP, PLN, QAR, RON, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR
---
### PayPal
PayPal provides a frictionless, one-tap checkout experience for European users. It is a MiCA-compliant solution that allows customers to move Euro into the crypto economy using their existing PayPal balance, linked bank accounts, or debit/credit cards.
- **Trust & Security:** Leverages PayPal's industry-leading fraud protection and seller protection.
- **Frictionless:** Recognised users can skip login and manual data entry, significantly reducing drop-off.
- **Gateway Fee:** 1.90%
> PayPal cannot run inside a WebView or iFrame. It requires an external redirect outside the app. See [iDEAL, Klarna & PayPal](../checkout-experience/iframe/webview-mobile.md) for implementation guidance.
Supported Countries (EU/EEA)
Austria, Belgium, Bulgaria, Croatia, Cyprus, Czech Republic, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Iceland, Ireland, Italy, Latvia, Liechtenstein, Lithuania, Luxembourg, Malta, Netherlands, Norway, Poland, Portugal, Romania, Slovakia, Slovenia, Spain, Sweden
Supported Fiat Currencies
EUR
---
### Card Payouts
Card payouts are currently supported in the following European countries.
Supported Countries
Austria, Belgium, Bulgaria, Croatia, Cyprus, Czech Republic, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Italy, Latvia, Lithuania, Luxembourg, Malta, Netherlands, Poland, Portugal, Republic of Ireland, Romania, Slovakia, Slovenia, Spain, Sweden
---
### Klarna – Pay Now
Klarna Pay Now allows eligible European users to purchase crypto instantly using their Klarna account. Payments are completed in full at checkout and confirmed immediately.
> Klarna cannot run inside a WebView or iFrame. It requires an external redirect outside the app. See [iDEAL, Klarna & PayPal](../checkout-experience/iframe/webview-mobile.md) for implementation guidance.
Supported Countries
Austria, Belgium, Finland, Germany, Netherlands, Spain, Sweden
---
### ACH
Electronic bank-to-bank transfers within the United States. Settlement takes 1–3 business days.
---
## Payment method IDs
Use these values in the `paymentMethodId` field when creating orders or constructing referral URLs.
| Payment Method | ID |
| :--- | :--- |
| Debit / Credit Card | `debit-credit-card` |
| Apple Pay | `apple-pay` |
| Google Pay | `google-pay` |
| SEPA Bank Transfer | `sepa-bank-transfer` |
| GBP Bank Transfer (Faster Payments) | `gbp-bank-transfer` |
| ACH Bank Transfer | `ach-bank-transfer` |
| PayID | `payid-bank-transfer` |
| NPP Direct Entry | `npp-bank-transfer` |
| PIX | `pix` |
| PayPal | `paypal` |
---
## Retrieve supported payment methods via API
Retrieve available payment methods dynamically for your integration.
### Endpoint
```
GET /{partner}/v2/payment-methods/{orderType}
```
### Path parameters
| Parameter | Description |
| :--- | :--- |
| `partner` | The partner code provided during onboarding (e.g. `metamask`). |
| `orderType` | `buy` or `sell` |
### Query parameters
| Parameter | Description |
| :--- | :--- |
| `fiat` | Optional. Filter by fiat currency code. |
### Example request
```bash
curl -X GET "https://api.banxa.com/metamask/v2/payment-methods/buy?fiat=USD" \
-H "x-api-key: YOUR_API_KEY"
```
### Example response
```json
[
{
"id": "apple-pay",
"name": "Apple Pay",
"description": "Conveniently buy digital currency using your personal VISA or MasterCard.",
"supportedFiats": [
"CAD", "CZK", "DKK", "HKD", "JPY", "NOK", "NZD", "PLN", "SEK", "SGD", "TRY"
]
}
]
```
Always use this endpoint to determine availability at runtime — the static table above may not reflect the latest additions to Banxa's payment network.
---
Source: https://docs.banxa.com/products/hosted-checkout/docs/testing/overview.md
---
title: "Integration Testing in Sandbox | Banxa Docs"
description: "Test your Banxa integration end-to-end in sandbox before going live. Covers checkout flow, webhooks, KYC sharing, iFrame embedding, and production readiness checklist."
---
# Testing Overview
Banxa provides a full sandbox environment for integration testing. The sandbox mirrors production behaviour — you can create orders, go through the complete checkout flow, and receive webhook notifications — without processing real money or crypto.
---
## Sandbox environment
| | Sandbox | Production |
|---|---|---|
| Base URL | `https://api.banxa-sandbox.com` | `https://api.banxa.com` |
| Checkout URL | `https://checkout.banxa-sandbox.com` | `https://checkout.banxa.com` |
| Real transactions | No | Yes |
| Test credentials | Yes | Real payment details only |
Your sandbox credentials (API key, partner reference) are separate from production and are provided during onboarding.
---
## What you can test in sandbox
- The full customer checkout flow (KYC, payment, order completion)
- Webhook delivery and order status transitions
- Quote pricing and order creation via the API
- Referral URL construction and parameter pre-population
- iFrame and WebView embedding
- KYC sharing and Sumsub token integration
---
## Testing checklist
Before requesting production access, complete the following:
- [ ] Create at least one buy order via your chosen integration method (API or Referral)
- [ ] Complete a full checkout using sandbox test credentials
- [ ] Confirm order status reaches `complete`
- [ ] Receive and handle at least one webhook notification
- [ ] Verify your `redirectUrl` is called correctly on checkout completion
- [ ] (If applicable) Test KYC sharing by calling the identity endpoint before checkout
- [ ] (If applicable) Test the off-ramp flow end-to-end (custodial: verify webhook receipt and deposit address retrieval)
---
## Next steps
→ [Sandbox Test Data](./sandbox-test-data.md) — test credentials and payment details
→ [End-to-End Testing](./end-to-end-testing.md) — step-by-step test flow
---
Source: https://docs.banxa.com/products/hosted-checkout/docs/testing/end-to-end-testing.md
---
title: "End-to-End Integration Testing Guide | Banxa Docs"
description: "Step-by-step guide to validate your Banxa integration in sandbox: complete a buy flow, sell flow with confirm endpoint, webhook delivery, and iFrame checkout."
---
# End-to-End Testing
Follow these steps to validate your complete integration before going to production.
---
## On-ramp (buy) test flow
### 1. Create a buy order
Call `POST /v2/buy` (API integration) or construct your referral URL (Referral integration) with:
- A valid test wallet address
- A supported crypto and fiat combination
- Your sandbox `redirectUrl`
Verify that you receive a `checkoutUrl` (API) or that your referral URL loads correctly.
### 2. Open the checkout
Navigate to the `checkoutUrl` in a browser or via your embedded checkout component.
Verify:
- The checkout loads without errors
- Pre-populated values (wallet address, crypto, fiat, amount) match what you submitted
### 3. Complete identity verification
Enter test personal details (realistic-looking name, address, date of birth).
If prompted for mobile verification, use:
- Mobile: any valid-format number
- PIN: `7203`
If prompted for document upload, use test document images.
### 4. Complete payment
Enter test card details:
- Card: `4111 1111 1111 1111`
- Expiry: any future date
- CVV: any 3 digits
### 5. Verify order completion
After completing payment:
- Confirm you are redirected to your `redirectUrl`
- Look up the order via `GET /v2/orders/{orderId}` and confirm `status` is `complete`
- Confirm a webhook was delivered to your configured endpoint with `status: "complete"`
---
## Off-ramp (sell) test flow
### 1. Create a sell order
Call `POST /v2/sell` with a test wallet address, crypto asset, and fiat currency.
### 2. Complete checkout
Open the `checkoutUrl`. Provide bank account details and complete any required KYC steps.
**Non-custodial:** The checkout will display a deposit address. In sandbox, no actual transfer is required — the order will simulate completion.
**Custodial:** The checkout will return the customer to your platform (via deeplink or webhook, depending on your configuration). Verify that your platform receives the deposit address correctly. In sandbox the order will simulate completion once the flow runs through.
### 3. Verify completion
Confirm the order reaches `complete` status via order lookup or webhook.
---
## Webhook test
1. Configure a webhook URL in the Partner Dashboard (use webhook.site or ngrok for local testing).
2. Create and complete an order.
3. Confirm the webhook is received with the correct `order_id` and `status`.
4. Confirm your endpoint responds with `200 OK`.
5. If using HMAC verification, confirm signature validation passes.
---
## iFrame / WebView test
If using embedded checkout:
1. Load the checkout URL in your iFrame or WebView component.
2. Verify the checkout renders correctly within your layout.
3. Confirm camera access works (attempt to reach the document upload step).
4. Complete a full order flow inside the embedded view.
5. Verify the WebView/iFrame navigates to your `redirectUrl` on completion.
---
## Ready for production
Once you have completed the end-to-end test flow and confirmed all components are working, notify Banxa to enable your production environment.
---
Source: https://docs.banxa.com/products/hosted-checkout/docs/testing/sandbox-test-data.md
---
title: "Sandbox Test Credentials & Test Data | Banxa Docs"
description: "Banxa sandbox test data: card 4111 1111 1111 1111, mobile PIN 7203, example wallet addresses, and how to trigger specific order statuses for testing."
---
# Sandbox Test Data
Use the following credentials and test data when testing in the sandbox environment.
---
## Mobile verification
When prompted for a mobile number during checkout, the sandbox accepts a PIN of `7203` for any number. Use one of the pre-approved Australian test numbers below — an actual SMS is sent to whatever number you enter, so do not use a real number.
| Mobile number | PIN |
|---|---|
| `+61 491577644` | `7203` |
| `+61 491578148` | `7203` |
| `+61 491578957` | `7203` |
| `+61 491579212` | `7203` |
| `+61 491574632` | `7203` |
| `+61 491579455` | `7203` |
| `+61 491570156` | `7203` |
| `+61 491570159` | `7203` |
---
## Credit / debit card
| Field | Value |
|---|---|
| Card number | `4111 1111 1111 1111` |
| Expiry | Any future date (e.g., `12/29`) |
| CVV | Any 3-digit number (e.g., `123`) |
| Name | Any name |
---
## KYC testing
When prompted for identity verification:
- Use **realistic-looking information** — test names, addresses, and dates of birth.
- Do not use placeholder values like "Test Test" or "123 Fake Street" — these may trigger additional review.
- Use test document images if prompted for document upload (contact Banxa for test document assets).
---
## Local payment methods
Some payment methods require a national identity number. Use the following test values:
| Country | Identity type | Test value |
|---|---|---|
| Brazil | Cadastro de Pessoas Físicas (CPF) | `10112075088` |
| Chile | Rol Único Nacional | `760864285` |
| Colombia | Cédula de Ciudadanía | `1077650154` |
| Mexico | CURP | `HEGG560427MVZRRL04` |
| South Africa | National ID | `8001015009087` |
| Thailand | Thai identity card number | `4854701245289` |
| United States | SSN | `222608111` |
---
## Bank transfers (off-ramp / AUD)
Use these details for AUD off-ramp testing. The account name must match the name submitted during KYC — any account number is accepted in sandbox.
| Field | Value |
|---|---|
| Name | Same name submitted during KYC |
| BSB | `032-050` |
| Account Number | `111111` |
---
## Wallet addresses
You can use any valid-format wallet address for testing. Example:
| Network | Example address |
|---|---|
| Ethereum (ETH) | `0xe3BDEFdAeFF070925eB7FfC49F9B30c647Cb751e` |
| Bitcoin (BTC) | `bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq` |
No crypto is actually transferred in sandbox. The checkout will simulate the transaction flow.
---
## Triggering specific order statuses
To test how your integration handles different order outcomes, you can engineer specific scenarios in the sandbox:
| Scenario | How to trigger |
|---|---|
| `complete` | Complete the full checkout flow with valid test credentials |
| `expired` | Leave the checkout URL without completing — wait for expiry |
| `cancelled` | Click "Cancel" or close the checkout before completing |
| `declined` | Use a card number that triggers decline (contact Banxa for test decline cards) |
---
## Webhooks in sandbox
Webhooks are delivered in sandbox just as in production. Use a tool like [webhook.site](https://webhook.site) or [ngrok](https://ngrok.com) to receive and inspect webhook payloads during local development.
Configure your sandbox webhook URL in the Partner Dashboard under the Sandbox environment setting.
---
---
Source: https://docs.banxa.com/products/native-api/@v0-beta/docs/how-it-works/otp-verification
---
title: OTP Email Verification
description: How to use headless OTP to verify a customer's email address within your app, without triggering a Banxa-hosted verification screen.
---
# OTP Email Verification
Banxa Native supports headless OTP: your app collects the customer's email address, triggers the verification flow server-side, and handles the code entry UI natively. No Banxa-hosted screens, no redirects.
If your app has a login mechanism, the OTP requirement can be disabled entirely — contact your Banxa integration manager. If your app does not have a login mechanism, headless OTP is required before you can process a transaction.
---
## When to use OTP verification
OTP is used to verify a customer's email address as part of identity establishment. It is relevant when:
- Your app does not have its own login or authentication mechanism and you need Banxa to verify the customer's email access
- A customer's identity was created without an email address (sparse identity) and you want to collect and verify email via OTP — if you only need to add an email without verification, use the identity patch endpoint instead
If OTP is not enabled on your account, the endpoints return `403 OtpFeatureNotEnabled`.
---
## Endpoints
Both endpoints use HMAC authentication. See [Authentication](../getting-started/authentication.md) for signing details.
| Action | Endpoint |
|---|---|
| Send OTP code | `POST /eapi/v1/verifications/otp` |
| Verify OTP code | `POST /eapi/v1/verifications/otp/verify` |
---
## The verification flow
```mermaid
sequenceDiagram
participant App
participant YourBackend as Your backend
participant Banxa
App->>YourBackend: Customer submits email
YourBackend->>Banxa: POST /eapi/v1/verifications/otp
Banxa-->>YourBackend: 200 { message: "OTP sent successfully" }
Banxa->>App: Email with OTP code (via customer's inbox)
App->>App: Customer enters OTP code
App->>YourBackend: Code submitted
YourBackend->>Banxa: POST /eapi/v1/verifications/otp/verify
Banxa-->>YourBackend: 200 { message: "Success" }
YourBackend-->>App: Email verified — proceed
```
---
## Step 1 — Send the OTP code
**`POST /eapi/v1/verifications/otp`**
```json
{
"identityReference": "customer-12345",
"email": "user@example.com"
}
```
| Field | Type | Description |
|---|---|---|
| `identityReference` | string | Your stable identifier for this customer |
| `email` | string | The email address to verify |
**Success response (200):**
```json
{
"message": "OTP sent successfully"
}
```
Banxa sends a short-lived 4-digit code to the provided email address. Your app should prompt the customer to check their inbox and enter the code promptly.
**Rate limit:** 3 requests per minute per customer.
---
## Step 2 — Verify the OTP code
**`POST /eapi/v1/verifications/otp/verify`**
```json
{
"identityReference": "customer-12345",
"email": "user@example.com",
"code": "1234"
}
```
| Field | Type | Description |
|---|---|---|
| `identityReference` | string | Same value used in the send request |
| `email` | string | Same email address used in the send request |
| `code` | string | 4-character code from the email |
**Success response (200):**
```json
{
"message": "Success"
}
```
On success, the email address is recorded as verified on the customer's identity. You can proceed with eligibility checks and ramp creation.
**Rate limit:** 4 verification attempts per minute per customer.
---
## Sparse identity and email collection
OTP can be used to collect and verify a customer's email address after identity creation. An identity created without an email address is valid — the OTP send call writes the email onto the identity record on successful verification.
This pattern is useful when your onboarding flow collects email separately from identity creation:
1. Create identity via `POST /eapi/v0/identities/basic` — omit the `email` field
2. When ready to verify the customer's email, call `POST /eapi/v1/verifications/otp` with the `identityReference` and `email`
3. The email is written onto the identity record on successful verification
---
## Email merging
If the email address supplied in the OTP flow already exists on a different Banxa identity record, Banxa merges the two records. The `identityReference` from the newer identity is moved onto the existing account; the newer identity and its associated `externalCustomerId` are removed.
**Practical effect:** after a merge, the `identityReference` you supplied continues to work, but it now refers to the older account. Any KYC state from the older account is carried over.
**What to watch for:** if a customer uses an email address that belongs to an existing Banxa account (e.g. they previously transacted via a different partner), the merge will silently absorb their new identity into the existing one. The customer's KYC history is preserved, but be aware that the older account's state governs their compliance tier.
---
## Error handling
### Wrong OTP code
A `422` response indicates the code is incorrect:
```json
{
"message": "Code does not match, please try again",
"code": 180,
"traceId": "2f92b534-55a0-4340-9e2a-2575913ff792"
}
```
An incorrect code cannot be corrected — the OTP flow must restart from the beginning. Call `POST /eapi/v1/verifications/otp` again to issue a new code before prompting the customer to re-enter.
### Rate limit exceeded
A `429` response is returned when the per-minute limit is reached:
```json
{
"message": "Too many OTP requests. Please try again later.",
"code": 429,
"traceId": "9fafad58-f1eb-44db-a77e-329610b1b755"
}
```
| Limit | Threshold |
|---|---|
| OTP send | 3 per minute per customer |
| OTP verify | 4 per minute per customer |
Present a clear wait-state to the customer rather than retrying silently.
### Feature not enabled
A `403` response means OTP is not enabled on your merchant account. Contact your Banxa integration manager.
### Invalid identity reference
A `422` response with `"The selected identity reference is invalid."` means the `identityReference` does not exist in Banxa's system. Ensure identity creation has completed successfully before triggering OTP.
---
## Interaction with Banxa Hosted Checkout
If your integration also uses Banxa Hosted Checkout, headless OTP suppresses the email verification screen that Banxa Hosted Checkout would otherwise show to the customer.
---
## Summary
| Step | Endpoint | Rate limit |
|---|---|---|
| 1. Send OTP | `POST /eapi/v1/verifications/otp` | 3/min |
| 2. Verify code | `POST /eapi/v1/verifications/otp/verify` | 4/min |
On wrong code: restart from step 1. On rate limit: wait and retry. On success: email is verified on the identity record and the customer can proceed.