GBPAY

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

  1. Overview
  2. Base URL & Versioning
  3. Rate Limiting
  4. Standard Response Format
  5. Authentication
  6. Product Discovery
  7. Quotation
  8. Transaction Initiation - MOBILE_BANKING
  9. Direct Transaction - EXTERNAL_API Only
  10. Transaction Status
  11. 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 Typescope in login bodyAuth FlowTransaction 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

EnvironmentBase URL
Current Productionhttps://mygbpay.com/backend
Planned Productionhttps://mygbpay.com/external

All endpoint paths below are appended to the base URL.


3. Rate Limiting

Auth endpoints are rate-limited per IP address.

EndpointsLimit
/login5 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": { }
}
FieldTypeDescription
timestampstring (ISO 8601)Server time of response
statusintegerHTTP status code mirrored in body
isSuccessbooleantrue on success
messagestringHuman-readable status
contentobject | nullPayload - 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"
}
FieldTypeRequiredDescription
usernamestringAgent username
passwordstringAgent password
scopestringMust 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
  }
}
FieldTypeDescription
accessTokenstringJWT - valid for 5 minutes
refreshTokenstringJWT - valid for 24 hours
stepnullnull on direct login success

Error Responses

HTTPCondition
400Missing or blank username / password
401Invalid credentials, wrong scope, or agent type not permitted
403Account suspended or blocked
429Rate 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

HTTPCondition
401Refresh 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

ParameterTypeRequiredDescription
typestringGIMAC provider type - see values below

Provider type values:

ValueDescription
MOBILE_MONEYMobile money operators (e.g. Orange Money, MTN MoMo)
CARDCard-based products
BANK_ACCOUNTBank account transfers
BILL_NUMBERBill payment providers
REMITTANCEInternational 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"
    }
  ]
}
FieldTypeDescription
idintegerCountry ID - use as countryId in the next endpoint
namestringCountry name
countryCodestringISO 3166-1 alpha-2
currencystringISO 4217 currency code
zonestringCEMAC or OTHERS (non-CEMAC)

Error Responses

HTTPCondition
400Invalid or unrecognised provider type
401Missing 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

ParameterTypeRequiredDescription
categorystringProductCategory value - see table below
countryIdintegerCountry ID from the previous endpoint

Product category values:

GroupValues
Wallet / Mobile MoneyCASH_IN, CASH_OUT, CASH_OUT_REQUEST, CASH_OUT_CANCEL, CASH_OUT_VALIDATION, CASH_OUT_REVERSAL, MOBILE_TRANSFER, PREPAID_CARD_RELOADS
ATM / CardlessATM_TRANSFER, CARDS_PAYMENTS, CARDLESS_WITHDRAWAL, CARDLESS_WITHDRAWAL_CANCEL
BankingWALLET_TO_ACCOUNT, ACCOUNT_TO_WALLET, ACCOUNT_TRANSFER, CORE_BANKING
Merchant / DepositCASH_DEPOSIT, MERCHANT_PURCHASE
Bill PaymentBILL_PAYMENT, ACCOUNT_INQUIRY
VouchersPURCHASE_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 as entityProduct in the QuoteRequest
  • content[n].uuid → pass as providerProduct in the QuoteRequest
  • content[n].category → determines which destination/source fields are required in the QuoteRequest
  • content[n].emitterType.regexpJs → optional client-side regex for validating wallet/account numbers

Error Responses

HTTPCondition
400Invalid or unrecognised category
401Missing or expired access token
404Country 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

FieldTypeDescription
entityProductstring (UUID)From ProductDto.entityProduct in the discovery response
providerProductstring (UUID)From ProductDto.uuid in the discovery response
amountnumberPayment amount in local currency
descriptionstring (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 groupRequired 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_REMITwalletDestination
ATM / Cardless - ATM_TRANSFER, CARDLESS_WITHDRAWAL, CARDLESS_WITHDRAWAL_CANCELwalletDestination
Bank Account - WALLET_TO_ACCOUNT, ACCOUNT_TO_WALLET, ACCOUNT_TRANSFER, INCOMING_ACCOUNT_REMIT, OUTGOING_ACCOUNT_REMIT, CORE_BANKINGbankAccountDestination or ibanDestination (not both)
Merchant Purchase - MERCHANT_PURCHASEwalletDestination (merchant wallet) + walletSource (customer wallet - required)
Bill Payment - BILL_PAYMENTbillNumber + billService, or cachedBillId
Account Inquiry - ACCOUNT_INQUIRYwalletDestination or bankAccountDestination
Vouchers - PURCHASE_VOUCHER, PURCHASE_VOUCHER_CANCEL, PURCHASE_VOUCHER_REVERSAL, OUTGOING_VOUCHER_REMIT, OUTGOING_VOUCHER_REMIT_CANCELvoucher.receiverPhone
Voucher Validation - CASH_OUT_VALIDATION, PURCHASE_VOUCHER_VALIDATION, OUTGOING_VOUCHER_REMIT_VALIDATIONvoucher.code (existing voucher code)
Cards - CARDS_PAYMENTS, ATM_TRANSFER (card flow)card object
Outgoing Card Remit - OUTGOING_CARD_REMITbankAccountDestination

Nested Objects

ObjectRequired for
receiverOUTGOING_ACCOUNT_REMIT, OUTGOING_WALLET_REMIT, OUTGOING_CARD_REMIT, OUTGOING_VOUCHER_REMIT, INCOMING_ACCOUNT_REMIT
senderOUTGOING_ACCOUNT_REMIT, OUTGOING_WALLET_REMIT, OUTGOING_CARD_REMIT, OUTGOING_VOUCHER_REMIT
voucherAll voucher categories (see table above)
cardCARDS_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
        }
      ]
    }
  }
}
FieldTypeDescription
quotestringQuote UUID - pass to the transaction endpoint. Expires in 15 minutes
amountnumberBase transaction amount
totalClientAmountnumberTotal debited from the client (amount + client charge)
clientChargenumberFee charged to the client
institutionChargenumberFee retained by the institution
institutionCommissionnumberCommission earned by the institution
agentCommissionnumberCommission earned by the agent
partnerCommissionnumberCommission earned by the partner
gimacCommissionnumberGIMAC network fee
issuerCommissionnumberIssuer-side commission
acquirerCommissionnumberAcquirer-side commission
taxResult.totalTaxnumberTotal tax applied
taxResult.detailsarrayPer-tax line breakdown

Error Responses

HTTPCondition
400Missing required fields or invalid values
401Missing or expired access token
403Agent not authorised for this product
404Entity product or provider product not found, or not assigned to this agent
422Business 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

FieldTypeRequiredDescription
quotestringQuote UUID from the /quote response
debitTxReferencestringRecommendedYour 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

FieldTypeDescription
uuidstringUnique transaction ID - use for status polling
transactionReferencestringHuman-readable transaction reference
externalReferencestring | nullProvider-side reference (set after processing)
memberCodestringGIMAC member code
amountnumberPrincipal transaction amount
statusstringSee status table below
errorstring | nullError message (SSL errors sanitized); null if no error
errorCodestring | nullMachine-readable provider error code
reference1/2/3string | nullProvider-specific references
initiatorIpstringIP address of the request sender
voucherCodestring | nullVoucher code (voucher-based transactions only)
taxnumberTax amount
clientChargenumberFee charged to the client
institutionChargenumberFee retained by the institution
agentCommissionnumberCommission earned by the agent
institutionCommissionnumberCommission earned by the institution
partnerCommissionnumberCommission earned by the partner
totalnumberTotal debited (principal + all charges)
clientTotalnumberTotal the client pays
descriptionstringTransaction description

Transaction Status Values

StatusMeaning
INITIATEDCreated, queued for processing
PENDINGProcessing in progress (async provider)
SUCCESSCompleted successfully
FAILEDProcessing failed
CANCELLEDCancelled before completion
EXPIREDTransaction expired before processing completed

Error Responses

HTTPCondition
400Missing or invalid quote UUID, or missing debitTxReference
401Missing or expired access token
403Agent type not permitted - EXTERNAL_API agents must use POST /api/v1/trans/transaction/direct
409Quote already used or expired
422Business rule violation (e.g. insufficient funds)
500Internal 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 memberCode must match a GIMAC provider associated with a Cameroon country entry. Requests for member codes outside this network will return 422.


Request Body

{
  "memberCode": "OM001",
  "productCategory": "CASH_OUT",
  "amount": 50000.00,
  "walletDestination": "237691234567",
  "description": "Cash out for customer",
  "debitTxReference": "YOUR-REF-00123"
}

Always-Required Fields

FieldTypeDescription
memberCodestringGIMAC provider member code - identifies the provider without a product discovery call
productCategorystringProductCategory value - determines which destination field is required (see table below)
amountnumberTransaction amount in local currency (must be positive)
debitTxReferencestringRequired. Your system's own transaction reference, stored for idempotency and reconciliation

Destination Fields (Category-Dependent)

Provide the destination field that matches your productCategory.

Category groupRequired fields
Mobile Money / Wallet - CASH_IN, CASH_OUT, CASH_OUT_REQUEST, MOBILE_RELOAD, MOBILE_TRANSFER, INCOMING_WALLET_REMITwalletDestination
ATM / Cardless - ATM_TRANSFER, CARDLESS_WITHDRAWALwalletDestination
Bank Account - WALLET_TO_ACCOUNT, ACCOUNT_TO_WALLET, ACCOUNT_TRANSFER, INCOMING_ACCOUNT_REMIT, CORE_BANKINGbankAccountDestination
Bill Payment - BILL_PAYMENTbillNumber or billContractNumber (at least one)
Outgoing Wallet Remit - OUTGOING_WALLET_REMITwalletDestination + sender + receiver
Outgoing Account Remit - OUTGOING_ACCOUNT_REMITbankAccountDestination + sender + receiver
Outgoing Voucher Remit - OUTGOING_VOUCHER_REMITsender + 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_PAYwalletDestination (payee wallet)

walletSource is optional for all categories - the institution omnibus account is used when omitted. For REQUEST_TO_PAY, providing walletSource explicitly identifies the payer's wallet.

Optional Fields

FieldTypeDescription
walletDestinationstringDestination wallet / mobile money number
walletSourcestringPayer's wallet number (optional - omnibus used when absent). For REQUEST_TO_PAY, identifies the payer's wallet explicitly
bankAccountDestinationstringDestination bank account number
bankAccountSourcestringSource bank account (optional - omnibus used when absent)
billNumberstringBill number (BILL_PAYMENT)
billContractNumberstringBill contract number (BILL_PAYMENT)
descriptionstringFree-text transaction description (max 255 chars)
validityDurationintegerValidity in seconds (900–172800, default 900). Used by REQUEST_TO_PAY and voucher categories
receiverobjectReceiver identity - required for OUTGOING_WALLET_REMIT, OUTGOING_ACCOUNT_REMIT, OUTGOING_VOUCHER_REMIT
senderobjectSender 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: status will be PENDING - the request has been registered with the payer's bank. voucherCode carries the GIMAC voucher code for the pending request. Payment completion arrives asynchronously when the payer approves; poll GET /api/v1/trans/transaction/{uuid}/status for 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

HTTPCondition
400Missing required fields (memberCode, productCategory, amount, or debitTxReference)
401Missing or expired access token
403Agent 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
409Conflict during processing (e.g. duplicate debitTxReference)
422No active product found for the given memberCode + productCategory combination assigned to this agent, or business rule violation (e.g. insufficient funds)
500Internal 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 ParameterDescription
transactionIdThe 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

HTTPCondition
401Missing or expired access token
404Transaction 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

CodeMeaning
200Success
400Bad request - validation failed
401Unauthorized - token missing, expired, or invalid
403Forbidden - account suspended/blocked or insufficient permissions
404Resource not found
409Conflict - e.g. quote already used
422Unprocessable - business rule violation
429Too many requests - rate limit exceeded
500Internal server error