This page is the complete endpoint reference for the Money API. Every request must be authenticated and signed — a bearer token plus x-hmac-signature and x-timestamp on every call, and an idempotency-key on creates. See Authentication for how to build those headers; the examples below abbreviate them as # + signed headers.
Endpoints use the /money/v1 service path on your base host. The examples use the sandbox base https://sandbox-api.gozem.co; production is https://api.gozem.co (see Environments & Access).
Charge and payout responses carry a success flag: reads return the resource under data, creates return a slim acknowledgement. Transaction details and Account carry success and message too, but return their fields flat in the envelope rather than under data. Failures return the error envelope for the matching group, described in Errors.
The endpoints are grouped into Charges, Payouts, Transaction details, and Account.
Charges
A charge pulls money from a payer into your merchant account. See Concepts for the model and Payments Lifecycle & Events for how a charge settles.
Create a charge
POST /money/v1/charge
Request body
| Field | Type | Required | Description |
|---|---|---|---|
amount |
integer | Yes | Amount in the smallest currency unit (e.g. centimes). Must be > 0. |
currency |
string | Yes | XOF or XAF. |
payer_identifier |
object | Yes | { "identifier": "...", "type": "gm_account" | "phone" }. |
channel |
string | Yes | gozem, flooz-tg, or yas-tg. |
pin |
string | Yes | Merchant Gozem Money PIN authorizing the charge — plain, or encrypted (see PIN encryption). |
payer_account_type |
string | Conditional | Client, Driver, or Merchant. Required when payer_identifier.type is phone and channel is gozem; recommended on PSP channels (used to resolve the payer’s display name). |
account_number |
string | No | Wallet to credit. Must belong to your merchant; defaults to your primary merchant account. |
message |
string | No | Optional note, up to 255 characters, visible to both parties. |
payment_reference |
object | No | { "ref_number", "ref_document" }. ref_document is base64, max 2 MB decoded, and must be a JPEG, PNG, or PDF — the file type is verified from the document bytes. |
metadata |
object | No | Optional key–value data forwarded internally. |
Payment channels
| Channel | Behaviour |
|---|---|
gozem |
The response includes a redirect_link; the payer approves in the Gozem app. Poll the charge or await the webhook for the final state. |
flooz-tg |
Flooz mobile money (Togo). Returns pending; final status by webhook. |
yas-tg |
Mix by Yas mobile money (Togo). Returns pending; final status by webhook. |
Example request
curl -X POST https://sandbox-api.gozem.co/money/v1/charge \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "idempotency-key: 6f9619ff-8b86-d011-b42d-00cf4fc964ff" \
# + signed headers (x-timestamp, x-hmac-signature)
-d '{
"amount": 15000,
"currency": "XOF",
"channel": "gozem",
"payer_identifier": { "identifier": "12053377", "type": "gm_account" },
"pin": "1234"
}'
Example response 201
{
"success": true,
"reference": "61684531",
"redirect_link": "https://app.gozem.co/user/authorize?pid=68811f0c2a…"
}
redirect_link is present only on the gozem channel — surface it to your payer to complete the in-app authorization; always use the returned value rather than constructing it. Use reference with Get charge for the full detail. Upstream processing may be asynchronous — observe the terminal state via webhook.
Typical errors: 400 VALIDATION_ERROR, 401, 403, 404 PAYER_NOT_FOUND, 409 IDEMPOTENCY_CONFLICT, 429, 503. See Errors.
Get charge
GET /money/v1/charge/:reference
reference is the value returned at creation. Returns { "success": true, "data": { … } } using the transaction envelope. Returns 404 CHARGE_NOT_FOUND if the charge is unknown or not owned by your client.
curl https://sandbox-api.gozem.co/money/v1/charge/61684531 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" # + signed headers
List charges
GET /money/v1/charge
Paginated list of charges for your client, newest first.
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
integer | 1 |
1-based page number |
limit |
integer | 20 |
Page size, 1–100 |
status |
string | — | PENDING, COMPLETED, FAILED, or CANCELLED |
channel |
string | — | gozem, flooz-tg, or yas-tg |
start_date |
string | — | ISO 8601 lower bound on created_at |
end_date |
string | — | ISO 8601 upper bound on created_at |
Example response 200
{
"success": true,
"data": [],
"pagination": { "page": 1, "limit": 20, "total": 0, "pages": 0 }
}
data holds transaction-envelope rows; pagination.total is the count across all filters and pagination.pages the total page count.
Payouts
A payout sends money from your merchant account to a beneficiary. On the envelope a payout has type payout and a negative amount.value.
Create a payout
POST /money/v1/payout
Request body
| Field | Type | Required | Description |
|---|---|---|---|
amount |
integer | Yes | Smallest currency unit. Must be > 0 and within your payout limits (see below). |
currency |
string | Yes | XOF or XAF. |
beneficiary_identifier |
object | Yes | { "identifier": "...", "type": "gm_account" | "phone" } (bank_account is reserved for future use). |
channel |
string | Yes | gozem, flooz-tg, or yas-tg. |
pin |
string | Yes | Merchant Gozem Money PIN authorizing the payout — plain, or encrypted (see PIN encryption). |
account_number |
string | No | Wallet to debit. Must belong to your merchant; defaults to your primary merchant account. |
beneficiary_account_type |
string | Conditional | Client, Driver, or Merchant. Required when the beneficiary is a phone and channel is gozem; recommended on PSP channels. |
message |
string | No | Optional note, up to 255 characters, visible to both parties. |
payment_reference |
object | No | { "ref_number", "ref_document" } — same format and limits as on charges. |
metadata |
object | No | Optional key–value data stored with the payout. |
Before submitting, the API checks the source balance and your payout limits: minimum amount, per-transaction maximum, daily and monthly caps, and a velocity limit of 20 payouts per rolling 5-minute window. Breaches return 402 INSUFFICIENT_FUNDS or 403 LIMIT_EXCEEDED with the relevant limit fields.
Example response 201
{ "success": true, "reference": "61684531" }
Use reference with Get payout.
Typical errors: 400 VALIDATION_ERROR, 401, 402 INSUFFICIENT_FUNDS, 403 LIMIT_EXCEEDED, 404 BENEFICIARY_NOT_FOUND, 409 IDEMPOTENCY_CONFLICT, 429, 503.
Get payout
GET /money/v1/payout/:reference
reference is the value returned at creation. Returns { "success": true, "data": { … } } using the transaction envelope; for payouts type is transfer and amount.value is negative. Returns 404 PAYOUT_NOT_FOUND if unknown or not owned by your client.
List payouts
GET /money/v1/payout
Same list envelope as List charges. Query parameters match, with one extra status value:
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
integer | 1 |
1-based page number |
limit |
integer | 20 |
Page size, 1–100 |
status |
string | — | PENDING, COMPLETED, FAILED, CANCELLED, or REVERSED |
channel |
string | — | gozem, flooz-tg, or yas-tg |
start_date |
string | — | ISO 8601 lower bound |
end_date |
string | — | ISO 8601 upper bound |
Transaction details
GET /money/v1/transaction-details/:id
Returns normalized payment details when your client is the payer or payee on the transaction. id is a payment identifier or unique_id.
This endpoint returns the transaction flat inside the envelope — success, message, and the transaction’s own fields as siblings. There is no data wrapper. The transaction’s shared note is exposed as shared_note, because message belongs to the envelope.
curl https://sandbox-api.gozem.co/money/v1/transaction-details/61684531 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" # + signed headers
Example response 200
{
"success": true,
"message": "Ok",
"reference": "61684531",
"status": { "code": 3, "label": "success" },
"type": "payment",
"amount": { "value": 15000, "currency": "XOF" },
"balance_after": { "value": 40891, "currency": "XOF" },
"counterpart_account": { "identifier": "98297646", "channel": "moov_money_flooz", "name": null },
"account": { "identifier": "12489777", "channel": "gz_money", "name": "QA FOOD Money" },
"category": { "id": "66fbd6a4038aaa9a5cb9a6c5", "label": "Other" },
"note": null,
"shared_note": "",
"description": "Paiement de 15 000 F au marchand QA FOOD Money",
"payment_references": [],
"created_at": "2026-01-18T16:30:00.000Z"
}
| Field | Description |
|---|---|
note |
Your client’s private note on the transaction, or null. |
shared_note |
The note shared between both parties (the transaction’s own message). |
category |
{ id, label } — Gozem Money transaction category, when one applies. |
Field presence varies by channel and transaction state; see the transaction envelope. Returns 404 transaction_not_found when the transaction is unknown, or your client is neither payer nor payee, and 403 merchant_not_linked when your client is not linked to a merchant account:
{
"success": false,
"message": "No transaction details found for this API client.",
"error_code": "transaction_not_found"
}
Account
GET /money/v1/account
Returns your merchant profile and primary Gozem Money wallet. Your merchant is resolved from your authenticated client; no identifier is passed in the URL.
Like transaction details, the profile is returned flat inside the envelope — no data wrapper.
Example response 200
{
"success": true,
"message": "Ok",
"id": "900001",
"name": "QA FOOD Money",
"type": "merchant",
"status": "active",
"country_code": "TG",
"phone_number": "+22897000010",
"account": {
"number": "12489777",
"balance": { "value": 40891, "currency": "XOF" },
"primary": true,
"payment_link": "https://sandbox-api.gozem.co/pay/12489777"
},
"created_at": "2025-07-09T10:33:03.441Z",
"updated_at": "2026-05-11T11:33:11.249Z"
}
| Field | Description |
|---|---|
id |
Merchant business identifier (unique_id), not the wallet or internal database id. |
status |
Merchant status, for example active or closed. |
account.number |
Primary Gozem Money wallet account number. |
account.payment_link |
Public link customers can use to pay this wallet. May be null if no base URL is configured. |
success, message, id, name, type, status, and account are always present; country_code, phone_number, created_at, and updated_at may be null when the profile does not carry them.
Typical errors: 400 merchant_account_not_configured / merchant_profile_incomplete, 403 merchant_not_linked / merchant_not_resolved, 404 account_not_found, 502 service_unavailable (safe to retry with backoff). See Errors.