WasaaPay API (1.0.0)

Download OpenAPI specification:

WasaaPay Developer Platform: developers@wasaapay.com URL: https://developers.wasaapay.com License: Proprietary

WasaaPay is a multi-currency payment aggregator for platforms and marketplaces operating in Africa. This specification covers the public merchant-facing API: collections, sub-merchant onboarding, wallets, split rules, payouts, webhooks, and FX. It implements the conventions defined in the WasaaPay Backend Engineering Document (response envelope, idempotency, error catalog) and the schemas defined in the WasaaPay Database Design Document.

Collections

Initiate and inspect payment collections across mobile money, card, and bank rails.

Initiate a payment collection

Creates a new collection (payment) via mobile money, card, or bank rail. Requires an Idempotency-Key header; retrying the same key returns the original result rather than creating a duplicate transaction.

Authorizations:
apiKeyAuth
header Parameters
Idempotency-Key
required
string

A client-generated key unique per logical operation. Retried requests with the same key return the original result.

Request Body schema: application/json
required
amount
required
integer >= 1

Minor currency units (e.g. cents).

currency
required
string = 3 characters
rail
required
string (Rail)
Enum: "mobile_money" "card" "bank" "ussd" "qr"
sub_merchant_id
string or null <uuid>
payer_phone
string or null

Required when rail = mobile_money or ussd.

payer_card_token
string or null

Tokenized card reference from the certified card processor. Required when rail = card.

payer_account_ref
string or null

Tokenized bank account reference from the certified provider. Required when rail = bank.

reference
string or null

Merchant-supplied order/reference string, echoed back on the transaction.

hold_in_escrow
boolean
Default: false

When true, the merchant leg of the settlement lands in the pending (escrow) bucket for later release by the split/escrow flow.

Responses

Request samples

Content type
application/json
{
  • "amount": 150000,
  • "currency": "KES",
  • "rail": "mobile_money",
  • "payer_phone": "2547XXXXXXXX",
  • "reference": "order_10293"
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Retrieve collection status

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Refund a collection (partial or full)

Creates a refund transaction against a successful collection. Omit amount (or the request body) to refund the full remaining amount; supply amount in minor currency units for a partial refund. The refund is returned as a transaction with type=refund and parent_transaction_id set to the original collection's ID. Requires an Idempotency-Key header; retrying the same key returns the original result rather than creating a duplicate refund.

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>
header Parameters
Idempotency-Key
required
string

A client-generated key unique per logical operation. Retried requests with the same key return the original result.

Request Body schema: application/json
optional
amount
integer or null >= 1

Refund amount in minor currency units. Omit (or send null) to refund the full remaining amount of the original collection. Must not exceed the original collection amount minus prior refunds.

reason
string or null <= 500 characters

Optional merchant-supplied reason, stored on the refund transaction.

Responses

Request samples

Content type
application/json
{
  • "amount": 50000,
  • "reason": "Customer returned one of two items."
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Checkout

Hosted-checkout sessions — payer-facing, capability-token flows where the payer picks the rail.

Open a hosted-checkout session

Creates a payer-facing checkout session for a fixed amount/currency and returns a one-time client_token capability secret. Unlike createCollection (where the merchant picks the rail at creation), the PAYER later chooses a rail from allowed_rails and pays via payCheckoutSession — authorized ONLY by the client_token, never the merchant API key. Requires an Idempotency-Key header; retrying the same key returns the original session (and its token) rather than minting a duplicate.

Authorizations:
apiKeyAuth
header Parameters
Idempotency-Key
required
string

A client-generated key unique per logical operation. Retried requests with the same key return the original result.

Request Body schema: application/json
required
amount
required
integer >= 1

Minor currency units (e.g. cents).

currency
required
string = 3 characters
reference
string or null

Merchant-supplied order/reference string, echoed on the resulting transaction.

sub_merchant_id
string or null <uuid>
allowed_rails
Array of strings (Rail) non-empty
Items Enum: "mobile_money" "card" "bank" "ussd" "qr"

Rails the payer may choose from. Defaults to all rails when omitted.

Responses

Request samples

Content type
application/json
{
  • "amount": 150000,
  • "currency": "KES",
  • "reference": "order_10293",
  • "allowed_rails": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Retrieve a checkout session (payer-facing)

Returns the non-sensitive fields the hosted checkout renders. Authorized by the session's client_token (the X-Checkout-Token header or a client_token query parameter), NOT the merchant API key; the client_token is never echoed back. A session past its expires_at is reported as expired.

Authorizations:
checkoutTokenAuth
path Parameters
id
required
string <uuid>
query Parameters
client_token
string

The session's client_token capability secret, as an alternative to the X-Checkout-Token header (see the checkoutTokenAuth security scheme). Supply exactly one of the two.

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Pay a checkout session (payer-facing)

The payer picks a rail from the session's allowed_rails and supplies the matching payer reference; this creates the underlying collection through the same path as createCollection and marks the session completed. Authorized by the session's client_token (the X-Checkout-Token header or a client_token query parameter). Requires an Idempotency-Key header; a same-key replay returns the original result, and a completed or expired session rejects new pays. Returns the resulting transaction (action_url / ussd_code are populated when a payer challenge is required).

Authorizations:
checkoutTokenAuth
path Parameters
id
required
string <uuid>
query Parameters
client_token
string

The session's client_token capability secret, as an alternative to the X-Checkout-Token header (see the checkoutTokenAuth security scheme). Supply exactly one of the two.

header Parameters
Idempotency-Key
required
string

A client-generated key unique per logical operation. Retried requests with the same key return the original result.

Request Body schema: application/json
required
rail
required
string (Rail)
Enum: "mobile_money" "card" "bank" "ussd" "qr"
payer_phone
string or null

Required when rail = mobile_money or ussd.

payer_card_token
string or null

Tokenized card reference. Required when rail = card.

payer_account_ref
string or null

Tokenized bank account reference. Required when rail = bank.

Responses

Request samples

Content type
application/json
{
  • "rail": "mobile_money",
  • "payer_phone": "2547XXXXXXXX"
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Transactions

Search and inspect transaction records.

List transactions

Cursor-paginated list of transactions, filterable by status, rail, and date range.

Authorizations:
apiKeyAuth
query Parameters
cursor
string

Opaque pagination cursor from a previous response's meta.next_cursor.

limit
integer [ 1 .. 100 ]
Default: 50
status
string (TransactionStatus)
Enum: "pending" "success" "failed" "reversed"
rail
string (Rail)
Enum: "mobile_money" "card" "bank" "ussd" "qr"
date_from
string <date-time>
date_to
string <date-time>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "error": {
    },
  • "meta": {
    }
}

Retrieve a transaction by ID

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Sub-Merchants

Onboard and manage sellers, vendors, riders, and individual earners.

Onboard a new sub-merchant

Programmatically onboard a seller, vendor, rider, or individual earner. Triggers a KYC case per the assigned kyc_tier.

Authorizations:
apiKeyAuth
header Parameters
Idempotency-Key
required
string

A client-generated key unique per logical operation. Retried requests with the same key return the original result.

Request Body schema: application/json
required
display_name
required
string
type
required
string
Enum: "individual" "business"
country
required
string = 2 characters
kyc_tier
string (KycTier)
Enum: "tier_1" "tier_2"
object

Responses

Request samples

Content type
application/json
{
  • "display_name": "Jane's Boutique",
  • "type": "individual",
  • "country": "KE",
  • "kyc_tier": "tier_1",
  • "contact": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

List sub-merchants

Authorizations:
apiKeyAuth
query Parameters
cursor
string

Opaque pagination cursor from a previous response's meta.next_cursor.

limit
integer [ 1 .. 100 ]
Default: 50
kyc_status
string (KycStatus)
Enum: "pending" "verified" "rejected" "needs_review"

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "error": {
    },
  • "meta": {
    }
}

Retrieve a sub-merchant by ID

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Team

Dashboard team management — the users belonging to a merchant.

List the merchant's dashboard users (team roster)

Returns every dashboard user under the authenticated merchant. The listing is always scoped to the caller's merchant, so one merchant can never enumerate another merchant's users. Requires the team:read permission (admin, finance, read_only, or compliance roles).

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "error": {
    },
  • "meta": {
    }
}

Wallets

Multi-currency wallet balances.

List wallets

Returns every wallet owned by the authenticated merchant (one per currency) or its sub-merchants.

Authorizations:
apiKeyAuth
query Parameters
cursor
string

Opaque pagination cursor from a previous response's meta.next_cursor.

limit
integer [ 1 .. 100 ]
Default: 50
owner_id
string <uuid>

Filter to a specific merchant or sub-merchant owner.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "error": {
    },
  • "meta": {
    }
}

Retrieve current available and pending balance

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Split Rules

Configure how a transaction's value is divided among recipients.

Create a split rule

Defines how a transaction's value is divided among recipients, with optional escrow per recipient.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
rule_type
required
string (SplitRuleType)
Enum: "percentage" "flat" "tiered"
currency
string or null = 3 characters

Required for flat (fixed-amount) rules — the ISO 4217 currency the flat recipient values are denominated in. Omit for percentage rules.

required
Array of objects (SplitRuleRecipient) non-empty

Responses

Request samples

Content type
application/json
{
  • "name": "Standard marketplace split",
  • "rule_type": "percentage",
  • "recipients": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

List split rules

Authorizations:
apiKeyAuth
query Parameters
cursor
string

Opaque pagination cursor from a previous response's meta.next_cursor.

limit
integer [ 1 .. 100 ]
Default: 50
active
boolean

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "error": {
    },
  • "meta": {
    }
}

Retrieve a split rule by ID

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Payouts

Single and bulk disbursements.

Initiate a single payout

Authorizations:
apiKeyAuth
header Parameters
Idempotency-Key
required
string

A client-generated key unique per logical operation. Retried requests with the same key return the original result.

Request Body schema: application/json
required
wallet_id
required
string <uuid>
destination_type
required
string (DestinationType)
Enum: "mobile_money" "bank" "card"
destination_ref
required
string

Tokenized destination account reference obtained via the payout-destination tokenization flow.

amount
required
integer >= 1
currency
required
string = 3 characters
scheduled_at
string or null <date-time>

Responses

Request samples

Content type
application/json
{
  • "wallet_id": "8f3a2b10-1c9e-4c2a-9b2f-3e6d2a1e9c11",
  • "destination_type": "mobile_money",
  • "destination_ref": "tok_dest_9f21ac",
  • "amount": 500000,
  • "currency": "KES"
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

List payouts

Authorizations:
apiKeyAuth
query Parameters
cursor
string

Opaque pagination cursor from a previous response's meta.next_cursor.

limit
integer [ 1 .. 100 ]
Default: 50
status
string (PayoutStatus)
Enum: "queued" "processing" "success" "failed"
wallet_id
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "error": {
    },
  • "meta": {
    }
}

Initiate a batch of payouts

Creates a payout_batch and its individual payouts in a single call, for paying many sub-merchants at once.

Authorizations:
apiKeyAuth
header Parameters
Idempotency-Key
required
string

A client-generated key unique per logical operation. Retried requests with the same key return the original result.

Request Body schema: application/json
required
wallet_id
required
string <uuid>

Source wallet shared by every payout in the batch.

required
Array of objects [ 1 .. 1000 ] items

Responses

Request samples

Content type
application/json
{
  • "wallet_id": "d9a8fbfc-848f-43a2-9168-911ed3a04a48",
  • "payouts": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Retrieve a payout batch by ID

Returns the batch, its aggregate status, and its individual payouts.

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Retrieve a payout by ID

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Webhooks

Register endpoints to receive event notifications.

Register a webhook endpoint

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
url
required
string <uri>
subscribed_events
required
Array of strings (WebhookEventType) non-empty
Items Enum: "transaction.pending" "transaction.success" "transaction.failed" "transaction.reversed" "payout.queued" "payout.processing" "payout.success" "payout.failed" "escrow.held" "escrow.released" "escrow.returned" "dispute.opened" "dispute.resolved" "kyc.verified" "kyc.rejected"

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

List registered webhook endpoints

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "error": {
    },
  • "meta": {
    }
}

Remove a webhook endpoint

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": { },
  • "error": {
    },
  • "meta": {
    }
}

FX

Foreign exchange rates and rate locks.

Retrieve current FX rates

Authorizations:
apiKeyAuth
query Parameters
base_currency
required
string = 3 characters
quote_currency
required
string = 3 characters

Responses

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}

Lock an FX rate for a scheduled future payout

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
base_currency
required
string = 3 characters
quote_currency
required
string = 3 characters

Responses

Request samples

Content type
application/json
{
  • "base_currency": "str",
  • "quote_currency": "str"
}

Response samples

Content type
application/json
{
  • "data": {
    },
  • "error": {
    },
  • "meta": {
    }
}