The Banxa iOS SDK (BanxaPaymentSDK) is a headless Swift interface to Banxa Hosted Checkout for native iOS apps. You configure it once and start a payment with a single call. The SDK checks eligibility, creates the order, presents checkout, and reports the outcome on a delegate.
For the end-to-end walkthrough, see the iOS SDK Integration Guide.
| Requirement | Version |
|---|---|
| iOS | 13.1 and above |
| Xcode | 16 and above |
| Swift | 6.0 and above |
The public surface is @MainActor isolated and built on Swift concurrency.
dependencies: [
.package(url: "https://github.com/BanxaOfficial/ios-payment-sdk", from: "1.0.0")
].target(
name: "YourApp",
dependencies: [
.product(name: "BanxaPaymentSDK", package: "ios-payment-sdk")
]
)- Select File, Add Package Dependencies.
- Enter the repository URL.
- Select BanxaPaymentSDK and add it to your app target.
The SDK transitively pulls in the payment provider SDK. You do not import or reference it directly.
import BanxaPaymentSDK
let config = BanxaConfig(
apiKey: "YOUR_API_KEY",
partnerID: "your-partner-id",
environment: .sandbox
)
BanxaPaymentSDK.shared.configure(config: config)
BanxaPaymentSDK.shared.delegate = self| Field | Type | Required | Description |
|---|---|---|---|
apiKey | String | Yes | Your v2 API key from the merchant dashboard. |
partnerID | String | Yes | Your partner identifier. |
environment | Environment | Yes | .sandbox or .production. |
Requests use x-api-key authentication.
| Environment | Host |
|---|---|
.sandbox | https://api.banxa-sandbox.com |
.production | https://api.banxa.com |
The effective base URL is <host>/{partnerID}/v2. Sandbox and production credentials are separate and are not interchangeable.
BanxaPaymentSDK.shared.startPayment(request: request, controller: self)| Parameter | Description |
|---|---|
request | A CreateOrderRequest. |
controller | The UIViewController that hosts the checkout presentation. |
startPayment creates the order and presents checkout in a single call. It returns nothing: results arrive on the delegate. Call it when the customer confirms, not in advance, because Banxa checkout must be loaded within one minute of order creation.
Requires a prior configure(config:) call. Otherwise it fails with APIError.sdkNotConfigured.
Three methods, each with a default no-op implementation. All callbacks are delivered on the main actor. All callback types are Banxa-owned: you never import or reference the underlying payment provider SDK.
extension MyViewController: BanxaPaymentSDKDelegate {
func banxaDidCompleteCheckout(_ result: BanxaCheckoutResult) { }
func banxaDidFail(error: Error) { }
func banxaDidDismiss() { }
}| Method | Fires when |
|---|---|
banxaDidCompleteCheckout(_:) | The customer completed payment. |
banxaDidFail(error:) | Any Banxa, network, validation, or checkout failure. Banxa-originated failures are APIError. |
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 |
|---|---|---|---|
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. |
paymentMethodID | String? | Yes | Banxa payment method id, for example debit-credit-card. |
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. |
paymentMethodID is declared as an optional in the Swift signature, but Banxa requires a value. Omitting it fails at payment execution rather than at compile time, so the compiler will not catch it for you. Always pass an id returned by fetchPaymentMethods.
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.
All configuration calls are async throws and require a configured SDK with non-blank credentials.
GET /{partnerID}/v2/countries. The list is the same for buy and sell.
let countries = try await BanxaPaymentSDK.shared.fetchCountries()| Type | Fields |
|---|---|
Country | id, description, states: [CountryState]? |
CountryState | id, description |
GET /{partnerID}/v2/fiats/{orderType}.
let fiats = try await BanxaPaymentSDK.shared.fetchFiats(orderType: .buy)| Type | Fields |
|---|---|
OrderType | .buy, .sell |
Fiat | id, description?, symbol?, supportedPaymentMethods: [FiatPaymentMethod]? |
FiatPaymentMethod | id, name?, minimum?, maximum? |
GET /{partnerID}/v2/crypto/{orderType}.
let assets = try await BanxaPaymentSDK.shared.fetchCrypto(orderType: .buy)| Type | Fields |
|---|---|
Cryptocurrency | id, description?, blockchains: [CryptoBlockchain]? |
CryptoBlockchain | id, description?, isDefaultBlockchain?, address?, network?, minimum?, unsupportedCountries: [String: [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/payment-methods/{orderType}. Optionally filter by fiat.
let methods = try await BanxaPaymentSDK.shared.fetchPaymentMethods(orderType: .buy)
let usdOnly = try await BanxaPaymentSDK.shared.fetchPaymentMethods(orderType: .buy, fiat: "USD")| Type | Fields |
|---|---|
PaymentMethod | id, name?, description?, supportedFiats: [String]? |
GET /{partnerID}/v2/quotes/{orderType}. Do not cache: call immediately before showing a price.
let request = QuoteRequest(
paymentMethodID: "debit-credit-card",
crypto: "ETH",
blockchain: "ETH",
fiat: "USD",
fiatAmount: "200"
)
let quotes = try await BanxaPaymentSDK.shared.fetchQuotes(orderType: .buy, request: request)| Type | Fields |
|---|---|
QuoteRequest | paymentMethodID, crypto, blockchain, fiat, fiatAmount?, cryptoAmount?, externalCustomerID?, ipAddress?, discountCode? |
Quote | paymentMethodID?, cryptoAmount?, fiatAmount?, processingFee?, networkFee?, discount: QuoteDiscount? |
QuoteDiscount | originalQuote: QuoteOriginalAmounts?, discountCode? |
QuoteOriginalAmounts | originalCryptoAmount?, originalNetworkFee?, originalProcessingFee?, originalFiatAmount? |
Provide either fiatAmount or cryptoAmount. If both are set, Banxa uses cryptoAmount. Banxa may return a single object or an array when discount codes apply, and fetchQuotes always returns [Quote].
Failures are surfaced through banxaDidFail(error:) as APIError. Each case provides a human-readable errorDescription.
| Case | Meaning |
|---|---|
.invalidURL | The endpoint URL could not be built. |
.serverError(Int) | Non-2xx HTTP response. |
.unauthorized | 401 from Banxa. Check apiKey. |
.decodingFailed(String) | The response payload failed to decode. |
.networkUnavailable | No network connectivity. |
.missingCredentials([String]) | apiKey or partnerID was blank in BanxaConfig. |
.sdkNotConfigured | startPayment was called before configure(config:). |
.unknown(String) | Any other unexpected error. |
Show user-facing messages only from validated error fields. Do not expose raw error strings that may include internal detail.
Register a URL scheme in your Info.plist and use it for redirectURL on CreateOrderRequest. This covers 3D Secure returns and the checkout return.
| 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 |
| Payment sheet theming | Not exposed on iOS | Available on Android. See Android SDK Reference |
import SwiftUI
import BanxaPaymentSDK
@main
struct DemoApp: App {
init() {
let config = BanxaConfig(
apiKey: ProcessInfo.processInfo.environment["BANXA_API_KEY"] ?? "",
partnerID: "your-partner-id",
environment: .sandbox
)
BanxaPaymentSDK.shared.configure(config: config)
}
var body: some Scene {
WindowGroup { ContentView() }
}
}
final class CheckoutCoordinator: NSObject, BanxaPaymentSDKDelegate {
override init() {
super.init()
BanxaPaymentSDK.shared.delegate = self
}
func buy(from controller: UIViewController) {
let request = CreateOrderRequest(
crypto: "ETH",
fiat: "EUR",
fiatAmount: "40",
walletAddress: "0x0000000000000000000000000000000000000000",
email: "[email protected]",
redirectURL: "your-app-scheme://banxa-return",
paymentMethodID: "debit-credit-card"
)
BanxaPaymentSDK.shared.startPayment(request: request, controller: controller)
}
func banxaDidCompleteCheckout(_ result: BanxaCheckoutResult) {
print("Payment complete:", result.paymentId ?? result.rawQuery ?? "-")
}
func banxaDidFail(error: Error) {
print("Payment failed:", error.localizedDescription)
}
func banxaDidDismiss() {
print("Customer dismissed checkout")
}
}Availability varies by partner, region, and order type. Treat fetchPaymentMethods 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 |
apple-pay | AUD, EUR, GBP, USD |
google-pay | AUD, EUR, 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.
- iOS SDK Integration Guide: end-to-end walkthrough.
- Webhooks: configure webhook notifications.
- Order Statuses: full status reference.