The Banxa Android SDK (BanxaPaymentSDK) is a headless Kotlin interface to Banxa Hosted Checkout for native Android apps. You initialise it once and render the StartPayment composable to run a payment. The SDK checks eligibility, creates the order, presents checkout, and reports the outcome through callback lambdas.
For the end-to-end walkthrough, see the Android SDK Integration Guide.
| Requirement | Version |
|---|---|
| Android API level | 24 and above |
| Kotlin | 2.0 and above, with the Compose Compiler Gradle plugin |
| Jetpack Compose | Enabled in your project |
The SDK is distributed as an AAR. Copy it into your module's libs directory and reference it from your Gradle build file.
dependencies {
implementation(files("libs/BanxaPayment-1.0.0.aar"))
}The Android SDK is not currently published to a Maven repository, so it does not resolve by coordinate and does not update through your dependency manager. Contact Banxa to obtain the AAR and to be notified when a new version is released.
val config = BanxaConfig.Builder()
.apiKey("YOUR_API_KEY")
.partnerID("your-partner-id")
.environment(Environment.SANDBOX)
.build()
Banxa.initialize(config)| Method | Required | Description |
|---|---|---|
apiKey(String) | Yes | Your v2 API key from the merchant dashboard. |
partnerID(String) | Yes | Your partner identifier. |
environment(Environment) | Yes | Environment.SANDBOX or Environment.PRODUCTION. |
primerTheme(PrimerTheme) | No | Overrides the native payment sheet colour tokens. Relevant only when the native payment sheet is in use. See Banxa Native. |
Requests use x-api-key authentication.
| Environment | Host |
|---|---|
Environment.SANDBOX | https://api.banxa-sandbox.com |
Environment.PRODUCTION | https://api.banxa.com |
The effective base URL is <host>/{partnerID}/v2. Sandbox and production credentials are separate and are not interchangeable.
StartPayment is a composable. Render it when the customer confirms.
StartPayment(
createOrderRequest = CreateOrderRequest(
fiat = "EUR",
crypto = "ETH",
fiatAmount = "40",
cryptoAmount = null,
walletAddress = "0x0000000000000000000000000000000000000000",
redirectUrl = "your-app-scheme://banxa-return",
paymentMethodId = "debit-credit-card",
email = "[email protected]"
),
banxaDidReceiveCheckout = { result ->
println("Paid: ${result.paymentId ?: result.rawQuery ?: "-"}")
},
banxaDidFail = { error ->
println("Failed: $error")
},
banxaDidDismiss = {
println("Customer dismissed checkout")
}
)StartPayment creates the order and presents checkout together. Render it when the customer confirms, not in advance, because Banxa checkout must be loaded within one minute of order creation.
Requires a prior Banxa.initialize(config) call.
All callbacks have a default no-op implementation, so supply only what you need.
| Callback | Fires when |
|---|---|
banxaDidReceiveCheckout | The customer completed payment. Receives a checkout result. |
banxaDidFail | Any Banxa, network, validation, or checkout failure. |
banxaDidDismiss | The customer closed checkout without completing. |
| Field | Populated when |
|---|---|
paymentId | The native payment sheet was used. |
orderId | The native payment sheet was used. |
status | The native payment sheet was used. |
rawQuery | Banxa checkout was used. Contains the terminal success URL query string. |
The success callback is a UI signal, not the authoritative order state. Confirm the final state from webhooks or Order Lookup before you credit a customer.
| Field | Type | Required | Description |
|---|---|---|---|
paymentMethodId | String | Yes | Banxa payment method id, for example google-pay. |
crypto | String | Yes | Crypto asset symbol, for example ETH. |
fiat | String | Yes | Fiat currency code, for example EUR. |
fiatAmount | String | Yes | Fiat amount as a string. |
walletAddress | String | Yes | Destination wallet address. |
email | String | Yes | Customer email address. |
redirectUrl | String | Yes | URL Banxa redirects to after checkout. |
id | String? | No | Your order id. |
blockchain | String? | No | Explicit blockchain network. |
cryptoAmount | String? | No | Crypto amount when ordering by crypto value. |
walletAddressTag | String? | No | Tag or memo for chains that require it. |
subPartnerId | String? | No | Sub-partner identifier. |
metadata | String? | No | Opaque metadata string. |
externalCustomerId | String? | No | Your stable customer identifier. |
externalOrderId | String? | No | Your order reference. |
discountCode | String? | No | Promotion or discount code. |
XRP, XLM, EOS, and ATOM require a memo or tag. Pass it as walletAddressTag. An order to one of these chains without the memo can be unrecoverable.
Use these to populate payment method selectors and currency pickers at runtime instead of hardcoding values. Each returns a Result.
val repository = BanxaRepository(
RetrofitClient.getApi(config.baseUrl, config.environment)
)GET /{partnerID}/v2/payment-methods/{orderType}. Optionally filter with fiat.
val result = repository.getPaymentMethods(
partner = config.partner,
apiKey = config.apiKey,
orderType = "buy",
fiat = "USD" // optional
)
result.onSuccess { methods ->
methods.forEach { method ->
println("${method.id}: ${method.name} to ${method.supportedFiats}")
}
}PaymentMethod field | Type | Notes |
|---|---|---|
id | String | Payment method id, for example apple-pay. |
name | String | Display name. |
description | String? | Human-readable description. |
supportedFiats | List<String> | Fiat codes available for this method. |
GET /{partnerID}/v2/countries. The list is the same for buy and sell.
val result = repository.getCountries(
partner = config.partner,
apiKey = config.apiKey
)| Type | Fields |
|---|---|
Country | id, description, states: List<CountryState> |
CountryState | id, description |
states is empty when the country has no state breakdown.
GET /{partnerID}/v2/fiats/{orderType}. Includes payment method minimum and maximum limits.
val result = repository.getFiats(
partner = config.partner,
apiKey = config.apiKey,
orderType = "buy"
)| Type | Fields |
|---|---|
Fiat | id, description, symbol?, supportedPaymentMethods: List<FiatPaymentMethod> |
FiatPaymentMethod | id, name, minimum?, maximum? |
GET /{partnerID}/v2/crypto/{orderType}.
val result = repository.getCrypto(
partner = config.partner,
apiKey = config.apiKey,
orderType = "buy"
)| Type | Fields |
|---|---|
Crypto | id, description, blockchains: List<Blockchain> |
Blockchain | id, description, isDefaultBlockchain, address?, network?, minimum?, unsupportedCountries: Map<String, List<String>> |
In unsupportedCountries, the key is a country code and the value is the restricted state codes. An empty list means the whole country is restricted.
GET /{partnerID}/v2/quotes/{orderType}. Do not cache: call immediately before showing a price.
val result = repository.getQuote(
partner = config.partner,
apiKey = config.apiKey,
orderType = "buy",
request = QuoteRequest(
fiat = "AUD",
crypto = "ETH",
blockchain = "ETH",
paymentMethodId = "debit-credit-card",
fiatAmount = "200"
)
)QuoteRequest field | Type | Required | Notes |
|---|---|---|---|
fiat | String | Yes | Fiat currency code. |
crypto | String | Yes | Crypto asset symbol. |
blockchain | String | Yes | Blockchain network. |
paymentMethodId | String | Yes | Payment method id. |
fiatAmount | String? | Conditional | Provide this or cryptoAmount. |
cryptoAmount | String? | Conditional | Provide this or fiatAmount. |
externalCustomerId | String? | No | Your customer identifier, for more accurate pricing. |
ipAddress | String? | No | Customer IP for regional pricing. |
discountCode | String? | No | Promotion or discount code. |
Quote field | Type | Notes |
|---|---|---|
paymentMethodId | String | Payment method the quote applies to. |
cryptoAmount | String | Crypto the customer receives. |
fiatAmount | String | Fiat the customer spends. |
processingFee | String? | Banxa processing fee in fiat. |
networkFee | String? | Blockchain network fee in fiat. |
discount | QuoteDiscount? | Present when a discount code was applied. |
Failures are surfaced through banxaDidFail. Banxa-originated failures are APIError, covering invalid URL, non-2xx server response, unauthorised (401), decoding failure, no network connectivity, missing credentials, uninitialised SDK, checkout failure, and unknown.
Show user-facing messages only from validated error fields. Do not expose raw error strings that may include internal detail. See Error Codes.
| Capability | Reason | Alternative |
|---|---|---|
| Order lookup by id or customer | Not exposed | Order Lookup via the API |
| Full order list across all customers | Not exposed | GET /{partnerRef}/v2/orders via API integration |
| KYC data sharing (Sumsub token share) | Requires HMAC authentication, which the SDK does not use | KYC Sharing |
| Off-ramp (sell) orders | The SDK covers buy orders only | Create Sell Order |
Availability varies by partner, region, and order type. Treat getPaymentMethods as the source of truth. The table below is a static reference.
| Payment method id | Supported fiats |
|---|---|
debit-credit-card | AED, ARS, AUD, BRL, CAD, CHF, CZK, DKK, EUR, GBP, HKD, IDR, INR, JPY, KRW, MXN, MYR, NGN, NOK, NZD, PHP, PLN, QAR, RUB, SAR, SEK, SGD, THB, TRY, TWD, USD, VND, ZAR |
google-pay | AUD, EUR, USD |
apple-pay | AUD, EUR, GBP, USD |
payid-bank-transfer | AUD |
pix | BRL |
zar-bank-transfer | ZAR |
pse | COP |
khipu | CLP |
interac-bank-transfer | CAD |
klarna-paynow | EUR |
ideal-bank-transfer | AUD, EUR |
sepa-bank-transfer | EUR |
gbp-bank-transfer | GBP |
spei | MXN |
For the full list, see Supported Payment Methods.
- Android SDK Integration Guide: end-to-end walkthrough.
- Webhooks: configure webhook notifications.
- Order Statuses: full status reference.