Skip to main content

Ghana

The 54Pay Collections API enables merchants to accept mobile money payments in Ghana. For the Ghanaian market, the payment completion workflow is determined by your transaction risk category.

Supported Operators

OperatorCode
MTNGHMTN
AirtelTigoGHATL
VodafoneGHVOD

Payment Completion Methods

Understanding your risk category flow is critical for successful integration.

  • High Risk (Gaming) - STK Push

    For high-risk traffic, such as those in Gaming, the collection process is a single-step flow. An STK push notification is triggered and sent directly to the customer's mobile device. Once the customer enters their PIN to authorize the payment on their device, the transaction is completed.

    Flow: API Request → STK Push to Customer's Device → Customer Authorizes

  • Low Risk (Forex and Remittance) - OTP Verification

    For low-risk traffic, such as those in Forex and Remittance, the collection process is a two-step flow. The mobile operator sends an OTP to the customer's mobile number. The merchant must collect this OTP from the customer and include it in a secondary /complete-payin request to finalize the transaction.

    Flow: API Request → OTP Sent to Customer → Collect OTP from Customer → Call /collection/v1/complete-payin with OTP

Authentication

Headers

HeaderTypeDescription
X-modulestringBase64(amount+transactionReference+customerNumber)
X-businessstringBase64-encoded Merchant Public Key: {Base64(Merchant Public Key)}
Content-TypestringMust be application/json
X-appstringMust be api

1. Initiate Collection (High Risk (1) - Gaming)

Creates a payment collection request that triggers an STK push directly to the user's phone.

Endpoint: POST /collection/v1/payin

Request

BASH

curl --location 'https://subsidiary.dev.mypaygate.co/collection/v1/payin' --header 'Accept: application/json' --header 'X-module: {Base64(amount+transactionReference+customerNumber)}' --header 'X-business: {Base64(Merchant Public Key)}' --header 'Content-Type: application/json' --header 'X-app: api' --data-raw '{
"requestHeader": {
"clientId": "",
"requestType": "Collections"
},
"customerName": "Kwame Mensah",
"customerEmail": "kwame@example.com",
"customerNumber": "233550000000",
"transactionReference": "TXN10273646",
"transactionDescription": "Wallet Funding",
"transactionAmount": 200,
"transactionCurrency": "GHS",
"transactionCountry": "GH",
"transactionType": "1", //Gaming
"successUrl": "",
"errorUrl": "",
"cancelUrl": "",
"operatorCode": "GHMTN",
"webhookUrl": ""
}'

Sample Response

JSON

{
"responseDetails": {
"responseCode": "09",
"responseMessage": "PENDING"
},
"transactionReference": "TXN61043784",
"otpIsRequired": false,
"lengthOfOtp": 0,
"paymentCompletionRequired": false,
"redirectionRequired": false
}

2. Initiate Collection (Low Risk (2) - Forex/Remittance)

Initiates the first step of the two-step flow. This request triggers an OTP to be sent to the customer's device.

Endpoint: POST /collection/v1/payin

Request

BASH

curl --location 'https://subsidiary.dev.mypaygate.co/collection/v1/payin' --header 'Accept: application/json' --header 'X-module: {Base64(amount+transactionReference+customerNumber)}' --header 'X-business: {Base64(Merchant Public Key)}' --header 'Content-Type: application/json' --header 'X-app: api' --data-raw '{
"requestHeader": {
"clientId": "",
"requestType": "Collections"
},
"customerName": "Ama Osei",
"customerEmail": "ama@example.com",
"customerNumber": "233550000000",
"transactionReference": "TXN10273646",
"transactionDescription": "Wallet Funding",
"transactionAmount": 200,
"transactionCurrency": "GHS",
"transactionCountry": "GH",
"transactionType": "2", //Forex or Remittance
"successUrl": "",
"errorUrl": "",
"cancelUrl": "",
"operatorCode": "GHVOD",
"webhookUrl": ""
}'

Sample Response

JSON

{
"responseDetails": {
"responseCode": "09",
"responseMessage": "PENDING"
},
"transactionReference": "TXN10273646",
"otpIsRequired": true,
"lengthOfOtp": 6,
"paymentCompletionRequired": true,
"redirectionRequired": false,
"paymentCompletionUrl": "/collection/v1/complete-payin"
}

2.1. Complete Payment (Low Risk (2) - Forex/Remittance)

The mobile operator sends a 6-digit OTP to the customer's mobile number. Collect this OTP and include it in the complete-payin request to finalize the transaction.

Endpoint: POST /collection/v1/complete-payin

Request

Additional Parameter: otpCode (The OTP provided by the customer)

Bash

curl --location 'https://subsidiary.dev.mypaygate.co/collection/v1/complete-payin' --header 'Accept: application/json' --header 'X-module: {Base64(amount+transactionReference+customerNumber)}' --header 'X-business: {Base64(Merchant Public Key)}' --header 'Content-Type: application/json' --header 'X-app: api' --data-raw '{
"requestHeader": {
"clientId": "",
"requestType": "Collections"
},
"customerName": "Ama Osei",
"customerEmail": "ama@example.com",
"customerNumber": "233550000000",
"transactionReference": "TXN10273646",
"transactionDescription": "Remittance Funding",
"transactionAmount": 200,
"transactionType": "2", //Forex or Remittance
"otpCode": "123456",
"transactionCurrency": "GHS",
"transactionCountry": "GH",
"successUrl": "",
"errorUrl": "",
"cancelUrl": "",
"operatorCode": "GHVOD",
"webhookUrl": ""
}'

Webhooks

Payment Status Webhook

The API sends POST requests to your webhookUrl when payment status changes.

Sample Webhook

{
"transaction_reference": "176414160871313",
"transaction_status": "Funds Received",
"transaction_fee": 0,
"amount_received": 50,
"initiated_date": "2025-11-26 08:20:08",
"current_status_date": "2025-11-26 08:29:21",
"received_from": {},
"merchant_reference": "TXN10273646",
"status": "COMPLETED",
"channel": "MOBILE_MONEY",
"currency_code": "GHS"
}

Webhook Status Values

StatusDescription
COMPLETEDPayment successfully received
FAILEDPayment failed or expired

Webhook Implementation

Your webhook endpoint must:

  • Accept POST requests: Listen for incoming webhook notifications
  • Validate payload: Verify merchant_reference matches your records
  • Return 200 OK
  • Process asynchronously: Handle business logic after responding
  • Handle duplicates: Implement idempotency using transaction_reference

Webhook Security

  • Verify requests originate from 54Pay IP addresses
  • Validate the merchant_reference exists in your system
  • Store webhook payloads for audit trail