Base URL: /v1/checkout
Auth:
POST /v1/checkoutuses the business public key in the request body- other server-side checkout endpoints use
Authorization: Bearer <secret_key>
Quote checkout amount
GET /v1/checkout/quote
Preview the fiat/crypto conversion before creating a checkout session.
Query:
amountrequiredamount_typeoptional:fiat|cryptoassetoptional, defaultsolana:usdcpublic_keyoptional but recommended when the quote should reflect the business fee rule
Example:
GET /v1/checkout/quote?amount=10&amount_type=crypto&asset=solana:usdc&public_key=pk_live_xxxxxResponse body:
{
"success": true,
"status": "success",
"status_code": 200,
"message": "Checkout quote",
"data": {
"amount_type": "crypto",
"asset": "solana:usdc",
"fiat_amount": 14319.04,
"base_fiat_amount": 14097.58,
"fee_amount": 221.46,
"customer_pays_fee": true,
"requested_crypto_amount": 10,
"fiat_currency": "NGN",
"crypto_amount": 10,
"crypto_currency": "USDC",
"network": "solana",
"rate": 1409.758,
"expires_at": "2026-05-11 10:30:00",
"refresh_after_seconds": 60,
"quote": {
"rate": 1409.758
}
}
}Notes:
- quote previews are short-lived
- refresh the quote again after
refresh_after_secondsor onceexpires_athas passed - pass
public_keywhen you want the quote to reflect the businesswho_pays_feepreference - omitting
public_keyfalls back to the base provider pricing only - this endpoint depends on Tsara's stablecoin quote provider and returns
503when quote generation is temporarily unavailable
Checkout assets
GET /v1/checkout/assets
Return the supported checkout amount modes and crypto assets for the UI.
Notes:
- this response is config-driven from Tsara's supported checkout asset configuration
- updating the config changes both validation and the
checkout/assetsresponse - asset flags:
enabled: allowed in live checkout flowstest_enabled: allowed in test checkout flowshold_supported: allowed when the checkout falls back to hold mode
- asset UI metadata:
sort_order: controls returned display orderdisabled_reason: optional machine-friendly reasonmaintenance_message: optional user-facing message
Response body:
{
"success": true,
"status": "success",
"status_code": 200,
"message": "Checkout assets",
"data": {
"amount_types": ["fiat", "crypto"],
"assets": [
{
"network_asset": "solana:usdc",
"network": "solana",
"asset": "usdc",
"symbol": "USDC",
"label": "Solana USDC",
"sort_order": 10,
"enabled": true,
"test_enabled": true,
"hold_supported": true,
"disabled_reason": null,
"maintenance_message": null
},
{
"network_asset": "bsc:usdt",
"network": "bsc",
"asset": "usdt",
"symbol": "USDT",
"label": "BSC USDT",
"sort_order": 50,
"enabled": true,
"test_enabled": true,
"hold_supported": false,
"disabled_reason": null,
"maintenance_message": null
}
]
}
}Create checkout session
POST /v1/checkout
Create a checkout transaction and return the hosted checkout URL.
Body:
{
"public_key": "pk_live_xxxxx",
"trx_id": "order_001",
"email": "[email protected]",
"name": "John Doe",
"phone": "08000000000",
"amount": 5000,
"amount_type": "fiat",
"currency": "NGN",
"redirect_url": "https://example.com/checkout/return",
"payment_method": "bank-transfer",
"asset": "solana:usdc"
}Notes:
amount_typeis optional and defaults tofiat- supported values:
fiat:amountis treated as NGNcrypto:amountis treated as the requested crypto amount for the selectedasset
assetis optional and defaults tosolana:usdcassetis used for crypto checkout generation, especially the non-hold crypto payment flowpayment_methodis optional and defaults tobank-transferdata.expires_atis the overall checkout session expiryaccount.crypto.expires_atis the current crypto deposit instruction expiry- for
amount_type=crypto, the checkout still settles internally in NGN; the crypto amount is first priced into a fiat base amount - when the business preference says the customer pays checkout fees, the payable fiat amount is uplifted before payment instructions are generated
- when
amount_type=crypto,account.crypto.requested_amountandaccount.crypto.requested_amount_typeare returned available_payment_methodsreflects the business payment-method preferencedefault_payment_methodis resolved from the business preference:bank-transferif available- otherwise
crypto
- provisioning behavior at create time:
- bank-transfer only: generate fiat only
- crypto only: generate crypto only
- both: generate fiat only; crypto is created later when the user switches on the checkout UI
- the same fee rule now applies consistently to quote, fiat-first checkout, and crypto-first checkout pricing
- if the crypto payment provider is temporarily unavailable:
- crypto-only checkout creation fails
- dual-mode checkout creation still succeeds with fiat account details only
crypto_availableshows whether crypto payment details were created successfully for that checkoutcrypto_erroris returned when fiat checkout was created but crypto setup failed
Test-mode note:
- when the provided public key is a test key, the controller uses the same
amount_typepricing rules
Crypto-first example:
{
"public_key": "pk_live_xxxxx",
"trx_id": "order_002",
"email": "[email protected]",
"name": "John Doe",
"amount": 10,
"amount_type": "crypto",
"asset": "solana:usdc",
"redirect_url": "https://example.com/checkout/return"
}Response body:
{
"success": true,
"status": "success",
"status_code": 200,
"message": "Checkout Created",
"data": {
"id": "order_001",
"status": "pending",
"checkout_url": "https://checkout.tsara.ng/?trx_id=order_001",
"expires_at": "2026-05-07 14:00:00",
"available_payment_methods": ["bank-transfer", "crypto"],
"default_payment_method": "bank-transfer",
"crypto_available": true,
"crypto_error": null,
"account": {
"fiat": {
"bank_code": "090286",
"bank_name": "Safe Haven MFB",
"account_name": "TSARA CHECKOUT",
"account_number": "1234567890"
},
"crypto": {
"is_type": "offramp",
"reference": "6c01338d-67e5-4d0c-a394-9d3e367f46a5",
"publicKey": "7fYw4wLbW7F5L6LwY6u3pM7cQ2T8K1m3A9zP6n2sQ4rX",
"address": "7fYw4wLbW7F5L6LwY6u3pM7cQ2T8K1m3A9zP6n2sQ4rX",
"network": "solana",
"asset": "usdc",
"network_asset": "solana:usdc",
"deposit_address": "7fYw4wLbW7F5L6LwY6u3pM7cQ2T8K1m3A9zP6n2sQ4rX",
"deposit_asset": "solana:usdc",
"fiat_amount": 14097.58,
"fiat_currency": "NGN",
"expires_at": "2026-05-07 13:50:00",
"status": "AWAITING_DEPOSIT",
"type": "OFFRAMP",
"rate": {
"USDC": 1409.758
},
"amount": 10
}
}
},
"url": "https://checkout.tsara.ng/?trx_id=order_001",
"trx_id": "order_001",
"available_payment_methods": ["bank-transfer", "crypto"],
"default_payment_method": "bank-transfer",
"crypto_available": true,
"crypto_error": null,
"account": {
"fiat": {
"bank_code": "090286",
"bank_name": "Safe Haven MFB",
"account_name": "TSARA CHECKOUT",
"account_number": "1234567890"
},
"crypto": {
"is_type": "offramp",
"reference": "6c01338d-67e5-4d0c-a394-9d3e367f46a5",
"publicKey": "7fYw4wLbW7F5L6LwY6u3pM7cQ2T8K1m3A9zP6n2sQ4rX",
"address": "7fYw4wLbW7F5L6LwY6u3pM7cQ2T8K1m3A9zP6n2sQ4rX",
"network": "solana",
"asset": "usdc",
"network_asset": "solana:usdc",
"deposit_address": "7fYw4wLbW7F5L6LwY6u3pM7cQ2T8K1m3A9zP6n2sQ4rX",
"deposit_asset": "solana:usdc",
"fiat_amount": 14097.58,
"fiat_currency": "NGN",
"expires_at": "2026-05-07 13:50:00",
"status": "AWAITING_DEPOSIT",
"type": "OFFRAMP",
"rate": {
"USDC": 1409.758
},
"amount": 10
}
}
}Fallback example when crypto setup fails:
{
"success": true,
"status": "success",
"status_code": 200,
"message": "Checkout Created",
"data": {
"id": "order_001",
"status": "pending",
"checkout_url": "https://checkout.tsara.ng/?trx_id=order_001",
"expires_at": "2026-05-07 14:00:00",
"available_payment_methods": ["bank-transfer", "crypto"],
"default_payment_method": "bank-transfer",
"crypto_available": false,
"crypto_error": "Crypto payment is currently unavailable for this checkout.",
"account": {
"fiat": {
"bank_code": "090286",
"bank_name": "Safe Haven MFB",
"account_name": "TSARA CHECKOUT",
"account_number": "1234567890"
}
}
}
}Crypto-only example:
{
"success": true,
"status": "success",
"status_code": 200,
"message": "Checkout Created",
"data": {
"id": "order_001",
"status": "pending",
"checkout_url": "https://checkout.tsara.ng/?trx_id=order_001",
"expires_at": "2026-05-07 14:00:00",
"available_payment_methods": ["crypto"],
"default_payment_method": "crypto",
"crypto_available": true,
"crypto_error": null,
"account": {
"crypto": {
"network_asset": "solana:usdc",
"asset": "usdc"
}
}
}
}Fetch checkout account
GET /v1/checkout/account
Return the current payment account details for a checkout transaction.
Query:
trx_id(required)method(optional):fiat|crypto
Notes:
- when
method=crypto, only thecryptoblock is returned - when
method=fiat, only thefiatblock is returned - when
methodis omitted, both blocks are returned when available - this endpoint also returns
available_payment_methodsanddefault_payment_methodso the checkout UI can recover the business payment-mode state after refresh
Example:
GET /v1/checkout/account?trx_id=order_001&method=crypto
Authorization: Bearer sk_live_xxxxxResponse body:
{
"success": true,
"status": "success",
"status_code": 200,
"message": "Account updated!",
"data": {
"available_payment_methods": ["bank-transfer", "crypto"],
"default_payment_method": "bank-transfer",
"crypto": {
"is_type": "offramp",
"reference": "6c01338d-67e5-4d0c-a394-9d3e367f46a5",
"publicKey": "0xcd257a5867B42556fa14c35de714154B277f70fD",
"address": "0xcd257a5867B42556fa14c35de714154B277f70fD",
"deposit_address": "0xcd257a5867B42556fa14c35de714154B277f70fD",
"deposit_asset": "solana:usdc",
"fiat_amount": 14097.58,
"fiat_currency": "NGN",
"expires_at": "2026-05-07 13:50:00",
"status": "AWAITING_DEPOSIT",
"type": "OFFRAMP",
"asset": "usdc",
"network_asset": "solana:usdc",
"network": "solana",
"rate": {
"USDC": 1409.758
},
"amount": 10
}
}
}Update checkout crypto asset
POST /v1/checkout/crypto
Rebuild the crypto payment details for an existing checkout transaction using a selected network:asset.
Body:
{
"trx_id": "order_001",
"asset": "base:usdc"
}Notes:
- requires
Authorization: Bearer <secret_key> - updates the stored
account->cryptopayload for the transaction - returns the refreshed crypto details for the checkout UI
- also returns
available_payment_methodsanddefault_payment_method - hold mode currently supports
solana:usdconly - if the existing crypto payment instruction for the requested
network:assetis still valid, it is reused instead of creating a new one - this endpoint depends on Tsara's crypto payment provider for non-hold mode and returns
503when crypto payment refresh is temporarily unavailable
Response body:
{
"success": true,
"status": "success",
"status_code": 200,
"message": "Crypto payment account updated!",
"data": {
"available_payment_methods": ["bank-transfer", "crypto"],
"default_payment_method": "bank-transfer",
"crypto": {
"is_type": "offramp",
"reference": "6c01338d-67e5-4d0c-a394-9d3e367f46a5",
"publicKey": "0xcd257a5867B42556fa14c35de714154B277f70fD",
"address": "0xcd257a5867B42556fa14c35de714154B277f70fD",
"deposit_address": "0xcd257a5867B42556fa14c35de714154B277f70fD",
"deposit_asset": "base:usdc",
"fiat_amount": 14097.58,
"fiat_currency": "NGN",
"expires_at": "2026-05-07 13:50:00",
"status": "AWAITING_DEPOSIT",
"type": "OFFRAMP",
"asset": "usdc",
"network_asset": "base:usdc",
"network": "base",
"rate": {
"USDC": 1409.758
},
"amount": 10
}
}
}Checkout status
GET /v1/checkout/status
Query:
referenceortrx_id
Notes:
- returns
available_payment_methodsanddefault_payment_methodfor UI state recovery
Example:
GET /v1/checkout/status?trx_id=order_001
Authorization: Bearer sk_live_xxxxxResponse body:
{
"success": true,
"status": "success",
"status_code": 200,
"message": "Transaction Status",
"data": {
"status": "pending",
"trx_id": "order_001",
"available_payment_methods": ["bank-transfer", "crypto"],
"default_payment_method": "bank-transfer"
}
}Checkout index
GET /v1/checkout
Fetch checkout transactions for the authenticated business.
Query:
trx_id(optional)reference(optional)status(optional, list mode)customer_email(optional, list mode)date_from(optional, list mode)date_to(optional, list mode)page(optional, list mode, default1)limit(optional, list mode, default20, max100)
Notes:
- when fetching a single checkout by
trx_idorreference, the response also includesavailable_payment_methodsanddefault_payment_method - the
accountfield is returned in the same normalized checkout shape used by create/account/crypto responses - when no filter is passed, the endpoint returns a list of checkout transactions ordered by latest first
- list mode returns pagination metadata in
meta - date-only filters like
2026-05-16are expanded to full-day boundaries:date_from=>2026-05-16 00:00:00date_to=>2026-05-16 23:59:59
Single checkout response:
{
"success": true,
"status": "success",
"status_code": 200,
"message": "Transactions",
"data": {
"id": 1,
"trx_id": "order_001",
"reference": "ts-12345678",
"status": "pending",
"account": {
"fiat": {
"bank_code": "090286",
"bank_name": "Safe Haven MFB",
"account_name": "TSARA CHECKOUT",
"account_number": "1234567890"
}
},
"available_payment_methods": ["bank-transfer", "crypto"],
"default_payment_method": "bank-transfer"
}
}List response:
{
"success": true,
"status": "success",
"status_code": 200,
"message": "Transactions",
"data": [
{
"id": 2,
"trx_id": "order_002",
"reference": "ts-87654321",
"status": "pending",
"account": {
"crypto": {
"network_asset": "solana:usdc",
"asset": "usdc"
}
},
"available_payment_methods": ["crypto"],
"default_payment_method": "crypto"
},
{
"id": 1,
"trx_id": "order_001",
"reference": "ts-12345678",
"status": "pending",
"account": {
"fiat": {
"bank_code": "090286",
"bank_name": "Safe Haven MFB",
"account_name": "TSARA CHECKOUT",
"account_number": "1234567890"
}
},
"available_payment_methods": ["bank-transfer", "crypto"],
"default_payment_method": "bank-transfer"
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 2,
"total_pages": 1
}
}