GbPay External Agent API
Version: 1.0.0
Base URL (Current): https://mygbpay.com/backend
Base URL (Planned): https://mygbpay.com/external
Authentication: Bearer JWT
Table of Contents
- Overview
- Base URL & Versioning
- Rate Limiting
- Standard Response Format
- Authentication
- Product Discovery
- Quotation
- Transaction Initiation - MOBILE_BANKING
- Direct Transaction - EXTERNAL_API Only
- Transaction Status
- Error Reference
1. Overview
The GbPay External Agent API enables authenticated external agents to:
- Obtain JWT access tokens via a login flow tailored to their agent type
- Discover available countries and products before initiating a transaction
- Request payment quotations (fees, commissions, taxes) before committing to a transaction
- Initiate transactions using a confirmed quote
- Poll transaction status
Agent Types, Auth Flows & Transaction Endpoints
| Agent Type | scope in login body | Auth Flow | Transaction endpoint |
|---|---|---|---|
EXTERNAL_API | "third-party" | Login → Token (direct) | POST /transaction/direct only |
MOBILE_BANKING | "third-party" | Login → Token (direct) | POST /transaction (quote-based) only |
Calling the wrong transaction endpoint for your agent type returns
403 Forbidden.
End-to-End Transaction Flow
Direct flow - EXTERNAL_API agents (single call, no pre-quote step):
1. Login → get accessToken
2. POST /transaction/direct → submit memberCode + productCategory + amount + debitTxReference
3. GET /transaction/{uuid}/status → poll until SUCCESS or FAILED
Use when you already know the GIMAC provider member code. Currently scoped to the Cameroon GIMAC network.
Quote-based flow - MOBILE_BANKING agents:
1. Login → get accessToken
2. GET countries-by-provider-type → pick country (get id)
3. GET products-by-category-country → pick product (get entityProduct + providerProduct UUIDs)
4. POST /quote → get quote UUID + fee breakdown
5. POST /transaction → submit quote UUID + debitTxReference
6. GET /transaction/{transactionReference}/status → poll until SUCCESS or FAILED
2. Base URL & Versioning
| Environment | Base URL |
|---|---|
| Current Production | https://mygbpay.com/backend |
| Planned Production | https://mygbpay.com/external |
All endpoint paths below are appended to the base URL.
3. Rate Limiting
Auth endpoints are rate-limited per IP address.
| Endpoints | Limit |
|---|---|
/login | 5 requests / 60 s |
All other /api/v1/authenticate/auth/** | 20 requests / 60 s |
429 Response body:
{
"error": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Please try again later.",
"path": "/api/v1/authenticate/auth/login"
}
4. Standard Response Format
All responses (except 429) use this envelope:
{
"timestamp": "2025-05-05T10:30:00.000Z",
"status": 200,
"isSuccess": true,
"message": "success",
"content": { }
}
| Field | Type | Description |
|---|---|---|
timestamp | string (ISO 8601) | Server time of response |
status | integer | HTTP status code mirrored in body |
isSuccess | boolean | true on success |
message | string | Human-readable status |
content | object | null | Payload - varies by endpoint |
5. Authentication
5.1 Login - EXTERNAL_API & MOBILE_BANKING Agents
Both EXTERNAL_API and MOBILE_BANKING agents must send scope: "third-party". Tokens are returned directly in the response body - no additional step required.
POST /api/v1/authenticate/auth/login
Request Body
{
"username": "agent001",
"password": "SecurePass@123",
"scope": "third-party"
}
| Field | Type | Required | Description |
|---|---|---|---|
username | string | ✅ | Agent username |
password | string | ✅ | Agent password |
scope | string | ✅ | Must be "third-party" |
Response - 200 OK
{
"timestamp": "2025-05-05T10:30:00.000Z",
"status": 200,
"isSuccess": true,
"message": "success",
"content": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"step": null
}
}
| Field | Type | Description |
|---|---|---|
accessToken | string | JWT - valid for 5 minutes |
refreshToken | string | JWT - valid for 24 hours |
step | null | null on direct login success |
Error Responses
| HTTP | Condition |
|---|---|
400 | Missing or blank username / password |
401 | Invalid credentials, wrong scope, or agent type not permitted |
403 | Account suspended or blocked |
429 | Rate limit exceeded |
5.2 Using the Access Token
Include the access token as a Bearer token on every subsequent request:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Token lifetimes:
- Access token: 5 minutes
- Refresh token: 24 hours
5.3 Refreshing the Access Token
When the access token expires, use the refresh token to obtain a new one without logging in again.
POST /api/v1/authenticate/auth/refresh-token
The refresh token is sent automatically as an HTTP cookie (set on login) - no request body is required.
Response - 200 OK
{
"timestamp": "2025-06-08T11:00:00.000Z",
"status": 200,
"isSuccess": true,
"message": "success",
"content": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}
Error Responses
| HTTP | Condition |
|---|---|
401 | Refresh token missing, expired, or invalid - log in again |
6. Product Discovery
Before requesting a quote, call these two endpoints to discover the countries and products available to the authenticated agent. The UUIDs returned here are required in the Quote request.
6.1 Get Countries by Provider Type
Returns countries that have active products for the specified provider type.
GET /api/v1/config/third-party/countries-by-provider-type
Authentication: Authorization: Bearer <accessToken>
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | ✅ | GIMAC provider type - see values below |
Provider type values:
| Value | Description |
|---|---|
MOBILE_MONEY | Mobile money operators (e.g. Orange Money, MTN MoMo) |
CARD | Card-based products |
BANK_ACCOUNT | Bank account transfers |
BILL_NUMBER | Bill payment providers |
REMITTANCE | International remittance corridors - returns non-CEMAC countries only |
Response - 200 OK
{
"timestamp": "2025-05-05T10:30:00.000Z",
"status": 200,
"isSuccess": true,
"message": "success",
"content": [
{
"id": 1,
"name": "Cameroon",
"countryCode": "CM",
"currency": "XAF",
"zone": "CEMAC",
"createdAt": "2025-01-01T00:00:00"
},
{
"id": 2,
"name": "Gabon",
"countryCode": "GA",
"currency": "XAF",
"zone": "CEMAC",
"createdAt": "2025-01-01T00:00:00"
}
]
}
| Field | Type | Description |
|---|---|---|
id | integer | Country ID - use as countryId in the next endpoint |
name | string | Country name |
countryCode | string | ISO 3166-1 alpha-2 |
currency | string | ISO 4217 currency code |
zone | string | CEMAC or OTHERS (non-CEMAC) |
Error Responses
| HTTP | Condition |
|---|---|
400 | Invalid or unrecognised provider type |
401 | Missing or expired access token |
6.2 Get Products by Category and Country
Returns all active products assigned to the authenticated agent for a given product category and country.
GET /api/v1/config/third-party/products-by-category-country
Authentication: Authorization: Bearer <accessToken>
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
category | string | ✅ | ProductCategory value - see table below |
countryId | integer | ✅ | Country ID from the previous endpoint |
Product category values:
| Group | Values |
|---|---|
| Wallet / Mobile Money | CASH_IN, CASH_OUT, CASH_OUT_REQUEST, CASH_OUT_CANCEL, CASH_OUT_VALIDATION, CASH_OUT_REVERSAL, MOBILE_TRANSFER, PREPAID_CARD_RELOADS |
| ATM / Cardless | ATM_TRANSFER, CARDS_PAYMENTS, CARDLESS_WITHDRAWAL, CARDLESS_WITHDRAWAL_CANCEL |
| Banking | WALLET_TO_ACCOUNT, ACCOUNT_TO_WALLET, ACCOUNT_TRANSFER, CORE_BANKING |
| Merchant / Deposit | CASH_DEPOSIT, MERCHANT_PURCHASE |
| Bill Payment | BILL_PAYMENT, ACCOUNT_INQUIRY |
| Vouchers | PURCHASE_VOUCHER, PURCHASE_VOUCHER_CANCEL, PURCHASE_VOUCHER_VALIDATION, PURCHASE_VOUCHER_REVERSAL |
| Remittances (inbound) | INCOMING_WALLET_REMIT, INCOMING_ACCOUNT_REMIT, INCOMING_VOUCHER_REMIT |
| Remittances (outbound) | OUTGOING_WALLET_REMIT, OUTGOING_CARD_REMIT, OUTGOING_ACCOUNT_REMIT, OUTGOING_VOUCHER_REMIT, OUTGOING_VOUCHER_REMIT_VALIDATION, OUTGOING_VOUCHER_REMIT_CANCEL |
Response - 200 OK
{
"timestamp": "2025-05-05T10:31:00.000Z",
"status": 200,
"isSuccess": true,
"message": "success",
"content": [
{
"uuid": "pp-uuid-001",
"id": 10,
"idPro": 15,
"name": "Orange Money",
"isDefault": true,
"publiclyVisible": true,
"description": "Orange Money cash-out",
"category": "CASH_OUT",
"Status": true,
"entityProduct": "ep-uuid-001",
"createdAt": "2025-01-15T08:30:00",
"gimacReference": 12345,
"gimacProviderReference": {
"id": 12345,
"uuid": "gp-uuid-001",
"name": "Orange Money CEMAC",
"code": "OM001",
"type": "MOBILE_MONEY",
"country": "Cameroon",
"createdAt": "2025-01-10T10:00:00"
},
"emitterTypeUuid": "op-uuid-001",
"emitterType": {
"uuid": "op-uuid-001",
"name": "Orange Money",
"countryCode": "CM",
"type": "OPERATOR",
"regexp": null,
"regexpJs": "^6[578]\\d{7}$",
"createdAt": "2025-01-10T10:00:00"
},
"provider": null,
"providerProduct": null
}
]
}
Extracting UUIDs for the Quote request:
content[n].entityProduct→ pass asentityProductin the QuoteRequestcontent[n].uuid→ pass asproviderProductin the QuoteRequestcontent[n].category→ determines which destination/source fields are required in the QuoteRequestcontent[n].emitterType.regexpJs→ optional client-side regex for validating wallet/account numbers
Error Responses
| HTTP | Condition |
|---|---|
400 | Invalid or unrecognised category |
401 | Missing or expired access token |
404 | Country not found or no products available |
7. Quotation
A quote must be obtained before initiating any transaction. It locks in the amount, fees,
commissions, and taxes for 15 minutes. Use the returned quote UUID to submit the transaction.
POST /api/v1/trans/quote
Authentication: Authorization: Bearer <accessToken>
Always-Required Fields
| Field | Type | Description |
|---|---|---|
entityProduct | string (UUID) | From ProductDto.entityProduct in the discovery response |
providerProduct | string (UUID) | From ProductDto.uuid in the discovery response |
amount | number | Payment amount in local currency |
description | string (max 255) | Free-text transaction description |
Destination & Source Fields (Category-Dependent)
The additional fields required depend on the product category from the discovery response.
The source account (
walletSource/bankAccountSource) is always the institution's omnibus account - the server resolves it automatically. Do not provide a source field unless specifically noted.
| Category group | Required destination |
|---|---|
Wallet / Mobile Money - CASH_IN, CASH_OUT, CASH_OUT_REQUEST, CASH_OUT_CANCEL, CASH_OUT_REVERSAL, MOBILE_TRANSFER, PREPAID_CARD_RELOADS, INCOMING_WALLET_REMIT, OUTGOING_WALLET_REMIT | walletDestination |
ATM / Cardless - ATM_TRANSFER, CARDLESS_WITHDRAWAL, CARDLESS_WITHDRAWAL_CANCEL | walletDestination |
Bank Account - WALLET_TO_ACCOUNT, ACCOUNT_TO_WALLET, ACCOUNT_TRANSFER, INCOMING_ACCOUNT_REMIT, OUTGOING_ACCOUNT_REMIT, CORE_BANKING | bankAccountDestination or ibanDestination (not both) |
Merchant Purchase - MERCHANT_PURCHASE | walletDestination (merchant wallet) + walletSource (customer wallet - required) |
Bill Payment - BILL_PAYMENT | billNumber + billService, or cachedBillId |
Account Inquiry - ACCOUNT_INQUIRY | walletDestination or bankAccountDestination |
Vouchers - PURCHASE_VOUCHER, PURCHASE_VOUCHER_CANCEL, PURCHASE_VOUCHER_REVERSAL, OUTGOING_VOUCHER_REMIT, OUTGOING_VOUCHER_REMIT_CANCEL | voucher.receiverPhone |
Voucher Validation - CASH_OUT_VALIDATION, PURCHASE_VOUCHER_VALIDATION, OUTGOING_VOUCHER_REMIT_VALIDATION | voucher.code (existing voucher code) |
Cards - CARDS_PAYMENTS, ATM_TRANSFER (card flow) | card object |
Outgoing Card Remit - OUTGOING_CARD_REMIT | bankAccountDestination |
Nested Objects
| Object | Required for |
|---|---|
receiver | OUTGOING_ACCOUNT_REMIT, OUTGOING_WALLET_REMIT, OUTGOING_CARD_REMIT, OUTGOING_VOUCHER_REMIT, INCOMING_ACCOUNT_REMIT |
sender | OUTGOING_ACCOUNT_REMIT, OUTGOING_WALLET_REMIT, OUTGOING_CARD_REMIT, OUTGOING_VOUCHER_REMIT |
voucher | All voucher categories (see table above) |
card | CARDS_PAYMENTS, ATM_TRANSFER |
Example Requests
CASH_OUT - wallet destination (EXTERNAL_API agent)
{
"entityProduct": "ep-uuid-001",
"providerProduct": "pp-uuid-001",
"amount": 50000.00,
"description": "Cash out for customer",
"walletDestination": "237691234567"
}
WALLET_TO_ACCOUNT - bank account destination
{
"entityProduct": "ep-uuid-002",
"providerProduct": "pp-uuid-002",
"amount": 100000.00,
"description": "Transfer to bank account",
"bankAccountDestination": "ACC-DEST-001"
}
BILL_PAYMENT - bill number
{
"entityProduct": "ep-uuid-003",
"providerProduct": "pp-uuid-003",
"amount": 25000.00,
"description": "Electricity bill payment",
"billNumber": "BILL-00123",
"billService": "ENEO"
}
MERCHANT_PURCHASE - both walletDestination and walletSource required
{
"entityProduct": "ep-uuid-004",
"providerProduct": "pp-uuid-004",
"amount": 15000.00,
"description": "Merchant purchase",
"walletDestination": "237650000001",
"walletSource": "237691234567"
}
OUTGOING_ACCOUNT_REMIT - bank destination with full sender/receiver
{
"entityProduct": "ep-uuid-005",
"providerProduct": "pp-uuid-005",
"amount": 200000.00,
"description": "International remittance",
"bankAccountDestination": "ACC-INTL-001",
"receiver": {
"receiverName": "Alice",
"receiverSecondName": "Mbarga",
"receiverPhone": "+237691234567",
"receiverCountry": "CM",
"receiverId": "1234567890",
"receiverIdType": "NATIONAL_ID"
},
"sender": {
"firstName": "Bob",
"secondName": "Talla",
"senderPhone": "+237670000001",
"senderCountry": "CM",
"senderId": "9876543210",
"senderIdType": "NATIONAL_ID"
}
}
Response - 200 OK
{
"timestamp": "2025-05-05T10:32:00.000Z",
"status": 200,
"isSuccess": true,
"message": "success",
"content": {
"quote": "84729130456712",
"amount": 50000.00,
"totalClientAmount": 51500.00,
"clientCharge": 1500.00,
"institutionCharge": 500.00,
"institutionCommission": 200.00,
"agentCommission": 150.00,
"partnerCommission": 50.00,
"gimacCommission": 100.00,
"issuerCommission": 80.00,
"acquirerCommission": 70.00,
"taxResult": {
"totalTax": 195.00,
"details": [
{
"name": "Value Added Tax",
"shortName": "VAT",
"rate": 19.25,
"fixedAmount": 0.00,
"baseAmount": 1500.00,
"calculatedAmount": 195.00
}
]
}
}
}
| Field | Type | Description |
|---|---|---|
quote | string | Quote UUID - pass to the transaction endpoint. Expires in 15 minutes |
amount | number | Base transaction amount |
totalClientAmount | number | Total debited from the client (amount + client charge) |
clientCharge | number | Fee charged to the client |
institutionCharge | number | Fee retained by the institution |
institutionCommission | number | Commission earned by the institution |
agentCommission | number | Commission earned by the agent |
partnerCommission | number | Commission earned by the partner |
gimacCommission | number | GIMAC network fee |
issuerCommission | number | Issuer-side commission |
acquirerCommission | number | Acquirer-side commission |
taxResult.totalTax | number | Total tax applied |
taxResult.details | array | Per-tax line breakdown |
Error Responses
| HTTP | Condition |
|---|---|
400 | Missing required fields or invalid values |
401 | Missing or expired access token |
403 | Agent not authorised for this product |
404 | Entity product or provider product not found, or not assigned to this agent |
422 | Business rule violation (e.g. amount below minimum or insufficient funds) |
8. Transaction Initiation - MOBILE_BANKING Agents
Submit the quote UUID to execute the transaction. The quote must not have expired (15-minute window)
or been previously used.
Agent types allowed: MOBILE_BANKING
Blocked: EXTERNAL_API agents receive 403 - use POST /api/v1/trans/transaction/direct instead.
POST /api/v1/trans/transaction
Authentication: Authorization: Bearer <accessToken>
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
quote | string | ✅ | Quote UUID from the /quote response |
debitTxReference | string | Recommended | Your core-banking debit reference - used for idempotency and reconciliation on your side |
{
"quote": "84729130456712",
"debitTxReference": "YOUR-REF-00123"
}
Response - 200 OK
status may be PENDING (async provider) or already SUCCESS / FAILED (sync provider).
Use content.transactionReference to poll GET /api/v1/trans/transaction/{transactionReference}/status for the final result.
{
"timestamp": "2025-05-05T10:33:00.000Z",
"status": 200,
"isSuccess": true,
"message": "success",
"content": {
"uuid": "93827410293847",
"transactionReference": "TXN-20250505-00123",
"externalReference": null,
"memberCode": "OM001",
"amount": 50000.00,
"status": "PENDING",
"error": null,
"errorCode": null,
"reference1": null,
"reference2": null,
"reference3": null,
"initiatorIp": "41.67.128.1",
"voucherCode": null,
"tax": 195.00,
"clientCharge": 1500.00,
"institutionCharge": 500.00,
"agentCommission": 150.00,
"institutionCommission": 200.00,
"partnerCommission": 50.00,
"total": 50000.00,
"clientTotal": 51500.00,
"description": "Cash out for customer"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
uuid | string | Unique transaction ID - use for status polling |
transactionReference | string | Human-readable transaction reference |
externalReference | string | null | Provider-side reference (set after processing) |
memberCode | string | GIMAC member code |
amount | number | Principal transaction amount |
status | string | See status table below |
error | string | null | Error message (SSL errors sanitized); null if no error |
errorCode | string | null | Machine-readable provider error code |
reference1/2/3 | string | null | Provider-specific references |
initiatorIp | string | IP address of the request sender |
voucherCode | string | null | Voucher code (voucher-based transactions only) |
tax | number | Tax amount |
clientCharge | number | Fee charged to the client |
institutionCharge | number | Fee retained by the institution |
agentCommission | number | Commission earned by the agent |
institutionCommission | number | Commission earned by the institution |
partnerCommission | number | Commission earned by the partner |
total | number | Total debited (principal + all charges) |
clientTotal | number | Total the client pays |
description | string | Transaction description |
Transaction Status Values
| Status | Meaning |
|---|---|
INITIATED | Created, queued for processing |
PENDING | Processing in progress (async provider) |
SUCCESS | Completed successfully |
FAILED | Processing failed |
CANCELLED | Cancelled before completion |
EXPIRED | Transaction expired before processing completed |
Error Responses
| HTTP | Condition |
|---|---|
400 | Missing or invalid quote UUID, or missing debitTxReference |
401 | Missing or expired access token |
403 | Agent type not permitted - EXTERNAL_API agents must use POST /api/v1/trans/transaction/direct |
409 | Quote already used or expired |
422 | Business rule violation (e.g. insufficient funds) |
500 | Internal server error |
9. Direct Transaction - EXTERNAL_API Agents Only
Combines quotation and transaction initiation into a single request. Instead of providing
entityProduct / providerProduct UUIDs from a prior product discovery call, you supply the
GIMAC provider member code and the product category. The server resolves the correct
product for your agent, creates the quote internally, and processes the transaction - all in one
round-trip.
Agent types allowed: EXTERNAL_API only
Blocked: MOBILE_BANKING agents receive 403 - use POST /api/v1/trans/transaction with a pre-created quote instead.
POST /api/v1/trans/transaction/direct
Authentication: Authorization: Bearer <accessToken>
Network scope: The product lookup is currently restricted to the Cameroon GIMAC network. The
memberCodemust match a GIMAC provider associated with a Cameroon country entry. Requests for member codes outside this network will return422.
Request Body
{
"memberCode": "OM001",
"productCategory": "CASH_OUT",
"amount": 50000.00,
"walletDestination": "237691234567",
"description": "Cash out for customer",
"debitTxReference": "YOUR-REF-00123"
}
Always-Required Fields
| Field | Type | Description |
|---|---|---|
memberCode | string | GIMAC provider member code - identifies the provider without a product discovery call |
productCategory | string | ProductCategory value - determines which destination field is required (see table below) |
amount | number | Transaction amount in local currency (must be positive) |
debitTxReference | string | Required. Your system's own transaction reference, stored for idempotency and reconciliation |
Destination Fields (Category-Dependent)
Provide the destination field that matches your productCategory.
| Category group | Required fields |
|---|---|
Mobile Money / Wallet - CASH_IN, CASH_OUT, CASH_OUT_REQUEST, MOBILE_RELOAD, MOBILE_TRANSFER, INCOMING_WALLET_REMIT | walletDestination |
ATM / Cardless - ATM_TRANSFER, CARDLESS_WITHDRAWAL | walletDestination |
Bank Account - WALLET_TO_ACCOUNT, ACCOUNT_TO_WALLET, ACCOUNT_TRANSFER, INCOMING_ACCOUNT_REMIT, CORE_BANKING | bankAccountDestination |
Bill Payment - BILL_PAYMENT | billNumber or billContractNumber (at least one) |
Outgoing Wallet Remit - OUTGOING_WALLET_REMIT | walletDestination + sender + receiver |
Outgoing Account Remit - OUTGOING_ACCOUNT_REMIT | bankAccountDestination + sender + receiver |
Outgoing Voucher Remit - OUTGOING_VOUCHER_REMIT | sender + receiver |
Voucher Validation - CASH_OUT_VALIDATION, PURCHASE_VOUCHER_VALIDATION, OUTGOING_VOUCHER_REMIT_VALIDATION | (no extra destination - voucher code is implicit) |
Request to Pay - REQUEST_TO_PAY | walletDestination (payee wallet) |
walletSourceis optional for all categories - the institution omnibus account is used when omitted. ForREQUEST_TO_PAY, providingwalletSourceexplicitly identifies the payer's wallet.
Optional Fields
| Field | Type | Description |
|---|---|---|
walletDestination | string | Destination wallet / mobile money number |
walletSource | string | Payer's wallet number (optional - omnibus used when absent). For REQUEST_TO_PAY, identifies the payer's wallet explicitly |
bankAccountDestination | string | Destination bank account number |
bankAccountSource | string | Source bank account (optional - omnibus used when absent) |
billNumber | string | Bill number (BILL_PAYMENT) |
billContractNumber | string | Bill contract number (BILL_PAYMENT) |
description | string | Free-text transaction description (max 255 chars) |
validityDuration | integer | Validity in seconds (900–172800, default 900). Used by REQUEST_TO_PAY and voucher categories |
receiver | object | Receiver identity - required for OUTGOING_WALLET_REMIT, OUTGOING_ACCOUNT_REMIT, OUTGOING_VOUCHER_REMIT |
sender | object | Sender identity - required for OUTGOING_WALLET_REMIT, OUTGOING_ACCOUNT_REMIT, OUTGOING_VOUCHER_REMIT |
Example Requests
CASH_OUT - wallet destination
{
"memberCode": "OM001",
"productCategory": "CASH_OUT",
"amount": 50000.00,
"walletDestination": "237691234567",
"description": "Cash out for customer",
"debitTxReference": "YOUR-REF-00123"
}
WALLET_TO_ACCOUNT - bank account destination
{
"memberCode": "GB001",
"productCategory": "WALLET_TO_ACCOUNT",
"amount": 100000.00,
"bankAccountDestination": "ACC-DEST-001",
"description": "Transfer to bank account",
"debitTxReference": "YOUR-REF-00124"
}
BILL_PAYMENT - by bill number
{
"memberCode": "ENEO001",
"productCategory": "BILL_PAYMENT",
"amount": 25000.00,
"billNumber": "BILL-00123",
"description": "Electricity bill payment",
"debitTxReference": "YOUR-REF-00125"
}
BILL_PAYMENT - by contract number
{
"memberCode": "CAMWATER001",
"productCategory": "BILL_PAYMENT",
"amount": 12000.00,
"billContractNumber": "CONTRACT-00456",
"description": "Water bill payment",
"debitTxReference": "YOUR-REF-00125B"
}
OUTGOING_WALLET_REMIT - wallet remittance with sender and receiver
{
"memberCode": "OM001",
"productCategory": "OUTGOING_WALLET_REMIT",
"amount": 150000.00,
"walletDestination": "237691234567",
"description": "Remittance to beneficiary",
"debitTxReference": "YOUR-REF-00126",
"receiver": {
"receiverName": "Alice",
"receiverSecondName": "Mbarga",
"receiverPhone": "+237691234567",
"receiverCountry": "CM",
"receiverId": "1234567890",
"receiverIdType": "NATIONAL_ID"
},
"sender": {
"firstName": "Bob",
"secondName": "Talla",
"senderPhone": "+237670000001",
"senderCountry": "CM",
"senderId": "9876543210",
"senderIdType": "NATIONAL_ID"
}
}
MOBILE_RELOAD - mobile top-up / airtime
{
"memberCode": "OM001",
"productCategory": "MOBILE_RELOAD",
"amount": 1000.00,
"walletDestination": "237691234567",
"description": "Airtime top-up",
"debitTxReference": "YOUR-REF-00127"
}
MOBILE_TRANSFER - wallet-to-wallet transfer
{
"memberCode": "OM001",
"productCategory": "MOBILE_TRANSFER",
"amount": 20000.00,
"walletDestination": "237691234568",
"description": "Transfer to friend",
"debitTxReference": "YOUR-REF-00128"
}
CASH_OUT_REQUEST - initiate a cash-out voucher
{
"memberCode": "OM001",
"productCategory": "CASH_OUT_REQUEST",
"amount": 30000.00,
"walletDestination": "237691234567",
"description": "Cash-out voucher request",
"validityDuration": 3600,
"debitTxReference": "YOUR-REF-00129"
}
ACCOUNT_TRANSFER - bank account to bank account
{
"memberCode": "GB001",
"productCategory": "ACCOUNT_TRANSFER",
"amount": 75000.00,
"bankAccountDestination": "ACC-DEST-002",
"description": "Inter-bank transfer",
"debitTxReference": "YOUR-REF-00130"
}
OUTGOING_ACCOUNT_REMIT - bank account remittance with sender and receiver
{
"memberCode": "GB001",
"productCategory": "OUTGOING_ACCOUNT_REMIT",
"amount": 200000.00,
"bankAccountDestination": "ACC-INTL-001",
"description": "International bank remittance",
"debitTxReference": "YOUR-REF-00131",
"receiver": {
"receiverName": "Alice",
"receiverSecondName": "Mbarga",
"receiverPhone": "+237691234567",
"receiverCountry": "CM",
"receiverId": "1234567890",
"receiverIdType": "NATIONAL_ID"
},
"sender": {
"firstName": "Bob",
"secondName": "Talla",
"senderPhone": "+237670000001",
"senderCountry": "CM",
"senderId": "9876543210",
"senderIdType": "NATIONAL_ID"
}
}
OUTGOING_VOUCHER_REMIT - voucher remittance with sender and receiver
{
"memberCode": "OM001",
"productCategory": "OUTGOING_VOUCHER_REMIT",
"amount": 50000.00,
"description": "Voucher remittance to beneficiary",
"validityDuration": 7200,
"debitTxReference": "YOUR-REF-00132",
"receiver": {
"receiverName": "Alice",
"receiverSecondName": "Mbarga",
"receiverPhone": "+237691234567",
"receiverCountry": "CM",
"receiverId": "1234567890",
"receiverIdType": "NATIONAL_ID"
},
"sender": {
"firstName": "Bob",
"secondName": "Talla",
"senderPhone": "+237670000001",
"senderCountry": "CM",
"senderId": "9876543210",
"senderIdType": "NATIONAL_ID"
}
}
REQUEST_TO_PAY - request payment from a payer (with explicit payer wallet)
{
"memberCode": "OM001",
"productCategory": "REQUEST_TO_PAY",
"amount": 5000.00,
"walletDestination": "237650000001",
"walletSource": "237691234567",
"description": "Payment for order #123",
"validityDuration": 900,
"debitTxReference": "YOUR-REF-00133"
}
REQUEST_TO_PAY response:
statuswill bePENDING- the request has been registered with the payer's bank.voucherCodecarries the GIMAC voucher code for the pending request. Payment completion arrives asynchronously when the payer approves; pollGET /api/v1/trans/transaction/{uuid}/statusfor the final outcome.
REQUEST_TO_PAY - without explicit payer wallet (omnibus as source)
{
"memberCode": "OM001",
"productCategory": "REQUEST_TO_PAY",
"amount": 5000.00,
"walletDestination": "237650000001",
"description": "Payment for invoice #456",
"debitTxReference": "YOUR-REF-00134"
}
Response - 200 OK
Same structure as the standard transaction initiation response. The transaction may be PENDING
(async processing) or already SUCCESS / FAILED (sync processing) depending on the provider.
{
"timestamp": "2025-05-28T10:33:00.000Z",
"status": 200,
"isSuccess": true,
"message": "success",
"content": {
"uuid": "93827410293847",
"transactionReference": "TXN-20250528-00123",
"externalReference": null,
"memberCode": "OM001",
"amount": 50000.00,
"status": "PENDING",
"error": null,
"errorCode": null,
"reference1": null,
"reference2": null,
"reference3": null,
"initiatorIp": "41.67.128.1",
"voucherCode": null,
"tax": 195.00,
"clientCharge": 1500.00,
"institutionCharge": 500.00,
"agentCommission": 150.00,
"institutionCommission": 200.00,
"partnerCommission": 50.00,
"total": 50000.00,
"clientTotal": 51500.00,
"description": "Cash out for customer"
}
}
Use content.transactionReference to poll GET /api/v1/trans/transaction/{transactionReference}/status for the final result. Note: the status endpoint takes transactionReference (e.g. TXN-...), not the UUID. The full-details endpoint GET /{transactionId} is the one keyed by UUID.
Error Responses
| HTTP | Condition |
|---|---|
400 | Missing required fields (memberCode, productCategory, amount, or debitTxReference) |
401 | Missing or expired access token |
403 | Agent type not permitted - only EXTERNAL_API agents may use this endpoint. MOBILE_BANKING agents must use POST /api/v1/trans/transaction with a pre-created quote |
409 | Conflict during processing (e.g. duplicate debitTxReference) |
422 | No active product found for the given memberCode + productCategory combination assigned to this agent, or business rule violation (e.g. insufficient funds) |
500 | Internal server error |
10. Transaction Status
Poll for the final outcome of an initiated transaction.
GET /api/v1/trans/transaction/{transactionId}/status
Authentication: Authorization: Bearer <accessToken>
| Path Parameter | Description |
|---|---|
transactionId | The uuid returned by the transaction initiation endpoint |
Response - 200 OK
{
"timestamp": "2025-05-05T10:34:00.000Z",
"status": 200,
"isSuccess": true,
"message": "success",
"content": {
"uuid": "93827410293847",
"transactionReference": "TXN-20250505-00123",
"amount": 50000.00,
"clientTotal": 51500.00,
"status": "SUCCESS",
"error": null,
"errorCode": null
}
}
Error Responses
| HTTP | Condition |
|---|---|
401 | Missing or expired access token |
404 | Transaction not found |
11. Error Reference
Standard Error Envelope
{
"timestamp": "2025-05-05T10:30:00.000Z",
"status": 401,
"isSuccess": false,
"message": "Unauthorized",
"content": null
}
HTTP Status Codes
| Code | Meaning |
|---|---|
200 | Success |
400 | Bad request - validation failed |
401 | Unauthorized - token missing, expired, or invalid |
403 | Forbidden - account suspended/blocked or insufficient permissions |
404 | Resource not found |
409 | Conflict - e.g. quote already used |
422 | Unprocessable - business rule violation |
429 | Too many requests - rate limit exceeded |
500 | Internal server error |