CheckoutOptions
CheckoutOptions is the configuration object you pass when initiating a checkout. The shape is consistent across all platforms, with minor differences in typing and naming conventions.
Fields
Section titled “Fields”| Field | Type (TS / Dart / Swift / Kotlin) | Required | Description |
|---|---|---|---|
amount |
number / int / Int / Long |
Yes | Amount in minor units (kobo, cents, paise). 500000 = ₦5,000. See amount handling. |
currency |
string / String |
Yes | ISO 4217 currency code (NGN, USD, INR, etc.) |
customer |
CheckoutCustomer |
Yes | Customer details. email is required. |
reference |
string? / String? |
No | Your unique transaction reference. Auto-generated as sanwo_<timestamp>_<random> if omitted. |
metadata |
Record<string, unknown> / Map<String, dynamic> / [String: Any]? / Map<String, Any>? |
No | Arbitrary key-value pairs passed through to the provider. |
description |
string? / String? |
No | Human-readable checkout description. |
address |
CheckoutAddress? |
No | Billing address. Web and React only. |
onLoad |
() => void |
No | Fires when the checkout UI loads. Web/React/React Native only. |
onError |
(error) => void |
No | Fires on error with { message, raw? }. Web/React/React Native only. |
sanwoProviderOptions |
Record<string, unknown> |
No | Provider-specific fields. Web/React/React Native only. On Flutter/iOS/Android, these are flattened as top-level fields. |
Platform-specific top-level fields (Flutter / iOS / Android)
Section titled “Platform-specific top-level fields (Flutter / iOS / Android)”On native SDKs, provider-specific options are passed as top-level fields on CheckoutOptions instead of being nested in sanwoProviderOptions:
| Field | Type | Description |
|---|---|---|
channels |
List<String> / [String]? |
Allowed payment channels (e.g. ["card", "bank_transfer"]) |
extra |
Map<String, Any>? |
Catch-all for any provider-specific field not explicitly typed |
method |
String? |
Provider checkout method (e.g. "checkout", "newTransaction") |
Amount handling
Section titled “Amount handling”Sanwo always expects amounts in minor units (the smallest denomination of the currency):
| Currency | Minor unit | Example |
|---|---|---|
| NGN | kobo | 500000 = ₦5,000.00 |
| USD | cents | 1999 = $19.99 |
| INR | paise | 100000 = ₹1,000.00 |
Providers that natively accept major units (Flutterwave, Monnify) have their amounts auto-converted by Sanwo. You always pass minor units regardless of provider.
CheckoutCustomer
Section titled “CheckoutCustomer”| Field | Type | Required | Description |
|---|---|---|---|
email |
string / String |
Yes | Customer email address |
firstName |
string? / String? |
No | Customer first name |
lastName |
string? / String? |
No | Customer last name |
name |
string? / String? |
No | Full name (alternative to firstName + lastName) |
phone |
string? / String? |
No | Customer phone number |
CheckoutAddress (web / React only)
Section titled “CheckoutAddress (web / React only)”| Field | Type | Required |
|---|---|---|
line1 |
string |
Yes |
line2 |
string? |
No |
city |
string |
Yes |
state |
string |
Yes |
postalCode |
string |
Yes |
country |
string |
Yes |
TypeScript
Section titled “TypeScript”interface CheckoutOptions { amount: number; currency: string; customer: CheckoutCustomer; reference?: string; metadata?: Record<string, unknown>; description?: string; address?: CheckoutAddress; onLoad?: () => void; onError?: (error: { message: string; raw?: unknown }) => void; sanwoProviderOptions?: Record<string, unknown>;}
interface CheckoutCustomer { email: string; firstName?: string; lastName?: string; name?: string; phone?: string;}
interface CheckoutAddress { line1: string; line2?: string; city: string; state: string; postalCode: string; country: string;}class CheckoutOptions { final int amount; final String currency; final CheckoutCustomer customer; final String? reference; final Map<String, dynamic>? metadata; final String? description; final List<String>? channels; final Map<String, dynamic>? extra; final String? method;
CheckoutOptions({ required this.amount, required this.currency, required this.customer, this.reference, this.metadata, this.description, this.channels, this.extra, this.method, });}
class CheckoutCustomer { final String email; final String? firstName; final String? lastName; final String? name; final String? phone;
CheckoutCustomer({ required this.email, this.firstName, this.lastName, this.name, this.phone, });}struct CheckoutOptions { let amount: Int let currency: String let customer: CheckoutCustomer var reference: String? = nil var metadata: [String: Any]? = nil var description: String? = nil var channels: [String]? = nil var extra: [String: Any]? = nil var method: String? = nil}
struct CheckoutCustomer { let email: String var firstName: String? = nil var lastName: String? = nil var name: String? = nil var phone: String? = nil}Kotlin
Section titled “Kotlin”data class CheckoutOptions( val amount: Long, val currency: String, val customer: CheckoutCustomer, val reference: String? = null, val metadata: Map<String, Any>? = null, val description: String? = null, val channels: List<String>? = null, val extra: Map<String, Any>? = null, val method: String? = null,)
data class CheckoutCustomer( val email: String, val firstName: String? = null, val lastName: String? = null, val name: String? = null, val phone: String? = null,)The extra catch-all
Section titled “The extra catch-all”The extra field (native SDKs) and sanwoProviderOptions (web/React/React Native) serve the same purpose: passing provider-specific fields that are not explicitly typed in CheckoutOptions.
Any key-value pair placed here is forwarded directly to the provider SDK. Refer to your provider’s documentation for available options.
// Flutter — pass Paystack split code via extraCheckoutOptions( amount: 500000, currency: 'NGN', customer: CheckoutCustomer(email: 'customer@example.com'), extra: {'split_code': 'SPL_xxxxxxxx'},)// Web — same thing via sanwoProviderOptionsawait sanwo({ amount: 500000, currency: "NGN", customer: { email: "customer@example.com" }, sanwoProviderOptions: { split_code: "SPL_xxxxxxxx", },});