Download OpenAPI specification:
This API is part of the our ecosystem. It allows you to make payments, find out the status of transactions and much more. Here you will find the latest documentation on setting up your solution.
Merchant’s request and callback have to be signed to verify sent data. To generate the signature all sent parameters from the payload are included in the order they were sent. The parameter signature should be excluded, of course, and added to the payload after generating.
Note: to generate a correct signature you need a secretKey received with other credentials.
function calculateSignature(array $data, string $secretKey, string $currentParamPrefix = '', int $depth = 16, int $currentRecursionLevel = 0 ): string
{
if ($currentRecursionLevel >= $depth) {
throw new Exception('Recursion level exceeded');
}
$stringForSignature = '';
foreach ($data as $key => $value) {
if (is_array($value)) {
$stringForSignature .= calculateSignature(
$value,
$secretKey,
"$currentParamPrefix$key.",
$depth,
$currentRecursionLevel + 1
);
} else if ($key !== 'signature') {
$stringForSignature .= "$currentParamPrefix$key" . $value;
}
}
if ($currentRecursionLevel == 0) {
return strtolower(hash_hmac('sha512', $stringForSignature, $secretKey));
} else {
return $StringForSignature;
}
}
$postData = [
'merchant_id' => 'fffed61be9780b97c5e4c65e4e07bb6b',
'provider_id' => 14,
'client_id' => '080000000',
'country' => 'ZM',
'order_id' => 'order_3444298767545',
'amount' => 1000,
'currency' => 'ZMW',
'callback_url' => 'https://my.callback.url'
];
$secretKey = "cf11635572c1e8d77297207152dc0791ad91f22b32d23c758ce3ba2637202ad8f7290ba41f2243cccf32edde1dfb8bf0f5dea62525309e293b3adb2c76eed6a5";
$signature = calculateSignature($postData, $secretKey);
$postData['signature'] = $signature;
Examples in other languages are available on request
| Code | Name | Description |
|---|---|---|
| -1 | undefined | Operation status is undefined (for example in an error situation) |
| 0 | initiated | Operation is initiated |
| 1 | in progress | Operation is in progress |
| 2 | success | Operation is successful |
| 3 | failed | Operation is failed |
| 4 | cancelled | Operation is cancelled |
| 5 | cancelled partially | Operation is cancelled partially (this status is related to POS payments) |
| 6 | in_transit | Operation is in transition (for example for withdrawal operation it means that cash was held but wasn’t received by the customer, this status also is related to POS payments) |
The result of the query processing by the system
| Code | Message | Description |
|---|---|---|
| 0 | OK | Operation is successful |
| 1 | INVALID PIN | PIN wasn’t accepted by Provider |
| 2 | PIN IS BLANK | PIN wasn’t accepted by Provider |
| 3 | INVALID PIN LENGTH | PIN wasn’t accepted by Provider |
| 10201 | MERCHANT AUTHENTICATION ERROR | The merchant’s request wasn’t authenticated by the Payment gateway security mechanism. For example, because of an incorrect signature |
Depending on the type of request you may see the following code
| Code | Operation |
|---|---|
| 16 | payment_b2c |
| 17 | payment_c2b |
| Code | Note |
|---|---|
| USD | Non-betting merchants only |
| ZMW | Zambia, betting and non-betting merchants |
| MWK | Malawi, Malawian kwacha |
| KES | the Republic of Kenya, Kenyan shilling |
| ETB | Ethiopia, Ethiopian Birr |
Responses for confirmation requests have the same format as original operation responses.
C2b transaction status is sent via callback because it needs a confirmation by client done asynchronously. Usually the callback should be sent in 2-3 minutes maximum. In case of missing callback there is a way to get the transaction status using API method status. It needs the order ID as an parameter and returns a status of the performed transaction.
Payment gateway considers the Merchant system response as successful if HTTP 200 was received.
| Provider ID | Provider Name | Notes |
|---|---|---|
| 14 | Simulator | For testing purposes |
During tests runs, using 14 provider ID (simulator) the callback is not returned and the transaction remains in the "in progress" status and if successful you will see in the response
{
"order_id": "54321",
"transaction_id": "12345",
"transaction_ref": "",
"status": 1,
"result": {
"code": 0,
"message": "OK"
},
"provider_result": {
"code": -8888,
"message": "Good"
},
"service_id": 1,
"service_version": "1.03/1.14|1.0/1.26|1.0/1.0|1.01/1.01|1.01/1.01||1.01/1.27",
"service_date_time": "2023-05-15 10:00:00.000000",
"confirm_type": 0
}
| Provider ID | Provider Name | Notes |
|---|---|---|
| 2120 | MTN | Check provider id with your manager |
| 2121 | MOOV | Check provider id with your manager |
22900000000 - This is the format of the phone number you have to send in the payment requests.
For C2B payments, you should send a customer full name in the payment requests. Parameter extra->customer_name. Please see the example in the API Methods section.
| c2b minimum | b2c minimum | Maximum transaction limit |
|---|---|---|
| XOF 200.00 | XOF 200.00 | XOF 1500000.00 |
| Provider ID | Provider Name | Notes |
|---|---|---|
| 2141 | Orange | Client's phone should start from 0: 0800000000 |
| 2142 | Airtel | Client's phone shouldn't start from 0: 999000000 |
| 2140 | Vodacom | 243000000000 - This is the format of the phone number sent in the request |
| 2143 | Africel | Client's phone should start from 0: 0900000000 |
The flow is standard, no need to pass extra parameters
| c2b minimum | b2c minimum | Maximum transaction limit |
|---|---|---|
| CDF 100 | CDF 100 | CDF 1500000 |
| Provider ID | Provider Name | Notes |
|---|---|---|
| 5064 | BankTransfer |
251000000000 - This is the format of the phone number you have to send in the payment requests.
| c2b minimum | b2c minimum | Maximum transaction limit |
|---|---|---|
| ETB 10.00 | ETB 500.00 | ETB 150000.00 |
| Provider ID | Provider Name | Notes |
|---|---|---|
| 2122 | MTN | Check provider id with your manager |
| 2123 | Airtel | |
| 2124 | Vodafone |
233000000000 - This is the format of the phone number you have to send in the payment requests.
For C2B and B2C payments you should send a customer full name and customer email in the payment requests. Parameters extra->customer_name and extra->customer_email. Please see the example in the API Methods section.
| c2b minimum | b2c minimum | Maximum transaction limit |
|---|---|---|
| GHS 10.00 | GHS 10.00 | GHS 25000.00 |
| Provider ID | Provider Name | Notes |
|---|---|---|
| 2125, 2406 | MTN | Check provider id with your manager |
| 2126, 2408 | Moov | Check provider id with your manager |
| 2127, 2407 | Orange | Check provider id with your manager |
| 2128, 2409 | Wave | Check provider id with your manager |
2250000000000 - This is the format of the phone number you have to send in the payment requests.
For C2B and B2C payments you should send a customer full name and customer email in the payment requests. Parameters extra->customer_name and extra->customer_email. Please see the example in the API Methods section.
For 2128 Provider ID Wave after successful response of accepting the transaction into processing (status:1), you call the status method. In the response you get the URL in the parameter extra->customer_redirect which you have to redirect the Customer.
For 2127 Provider ID Orange the Customer must create an OTP code on the Operator side. This OTP must be sent in payment requests. Parameter extra->otp. User should dial #144*82# (May change on the method side, information is updated periodically)
| c2b minimum | b2c minimum | Maximum transaction limit |
|---|---|---|
| XOF 5.00 | XOF 1.00 | XOF 550000.00 |
| c2b minimum | b2c minimum | Maximum transaction limit |
|---|---|---|
| XOF 100.00 | XOF 100.00 | XOF 500 000.00 |
| Provider ID | Provider Name | Notes |
|---|---|---|
| 824 | M-Pesa Safaricom | |
| 5063 | BankTransfer |
254000000000 - This is the format of the phone number you have to send in the payment requests.
The payment flow is standard.
| c2b minimum | b2c minimum | Maximum transaction limit |
|---|---|---|
| KES 10.00 | KES 500.00 | KES 150000.00 |
| Provider ID | Provider Name | Notes |
|---|---|---|
| 2129, 749 | Tigo | Check provider id with your manager |
| 2130 | Vodacom | Check provider id with your manager |
| 2131, 750 | HaloPesa | Check provider id with your manager |
| 2132, 748 | Airtel | Check provider id with your manager |
| 5045 | Bank Transfer | Check provider id with your manager |
255000000000 - This is the format of the phone number you have to send in the payment requests.
For C2B payments, you should send a customer full name and customer email in the payment requests. Parameters extra->customer_name and extra->customer_email. Please see the example in the API Methods section.
For 748, 749, 750: For C2B payments the flow is standard. For B2C payments, you should send a customer full name in the payment requests. Parameter extra->customer_name. Please see the example in the API Methods section.
For 5045 (only B2C): You should set account number as customer_id and send customer full name and bank BIC("Bank Identifier Code", ask your bank) in the payment request. Parameters extra->customer_name and extra->bic. Please see the example in the API Methods section.
| c2b minimum | b2c minimum | Maximum transaction limit |
|---|---|---|
| TZS 1000.00 | TZS 7500.00 | TZS 3000000.00 |
For 748, 749, 750:
| c2b minimum | b2c minimum | Maximum transaction limit |
|---|---|---|
| TZS 1000.00 | TZS 1000.00 | TZS 5000000.00 |
| Provider ID | Provider Name | |
|---|---|---|
| 2055, 2133, 2137 | BankTransfer | Check provider id with your manager |
| 2056, 2134, 2138 | BankTransfer Pay Attitude | Check provider id with your manager |
| 2057, 2135 | BankTransfer OPay | |
| 2058, 2136, 2139 | BankTransfer Palmpay | Check provider id with your manager |
Bank Transfer / Pay Attitude / OPay / Palmpay / Card payment C2B (deposit) scenario: * Customer initiates the payment via Bank Transfer/Pay Attitude/OPay/Palmpay/Card method on the Merchant’s side. * Merchant requests Customer’s Name, Email and Amount. This step is optional, as this data may be stored in the merchant's system
```
{
"provider_id": 2133,
"merchant_id": "cd4645yh720cc83gh5443d2bd6424b",
"customer_id": "2349061239999",
"order_id": "1234567890",
"country": "NG",
"amount": "10000",
"currency": "NGN",
"callback_url": "https://example.com",
"email": "test@gmail.com",
"name": "John Christopher",
"signature": "3bca46363467e8683d73dbd8e564fa93596f5d4fede1f252d2c875597bf6945730fbbc8da66a4100fe60d"
}
Customer_message example:
{
"order_id": "1234567890",
"transaction_id": "0987654321",
"transaction_ref": "",
"status": 1,
"result": {
"code": 0,
"message": "OK"
},
"provider_result": {
"code": -8888,
"message": ""
},
"service_id": 1,
"service_version": "1.03/1.14|1.0/2.0|1.0/1.0|1.01/1.0|1.01/2.0||1.02/1.27",
"service_date_time": "2025-05-25 15:15:55.050505",
"extra": {
"account_name": "EXAMPLE TECH – LTD",
"account_number": "1597534560",
"bank_name": "GLOBUS BANK",
"transfer_amount": "10000"
},
"confirm_type": 0
}
For 2137, 2138, 2139 provider_id instead of the bank details a link will be returned in the customer_redirect parameter to which the user should be redirected
Please note that on channels 2133, 2134, 2135, 2136 users have the opportunity to pay the wrong amount using the details, as well as make payments several times. To avoid discrepancies in amounts, long processing of transactions on these channels and other difficulties, we recommend that you create an information board for users. In the text, please warn that the details are used only once and only for the stated amount. In other cases, the transaction processing time may take a very long time. For example, to be convincing, you can warn about the high probability of losing funds
Bank Transfer B2C (withdrawal) scenario:
Passing bank_code in the request is relevant only for 2133 and 2137 provider_id
B2C Bank Transfer request example:
{
"merchant_id":"cd4645yh720cc83gh5443d2bd6424b",
"order_id":"1234567890",
"customer_id":"16280954971628095497",
"amount":"1000",
"currency":"NGN",
"provider_id":2133,
"extra":{
"customer_name":"John Christopher",
"customer_email": "test@gmail.com",
"bank_code":"000001"
},
"signature":"d7d6d76b0e22c6f9d36f107053d12bfd248t498ghoshgos93f9379c803be455d81cfe792f00cd8892c26ce7cf5a05beebb9c80843e"
}
| c2b minimum | b2c minimum | Maximum transaction limit |
|---|---|---|
| NGN | NGN | NGN |
| Provider ID | Provider Name | Notes |
|---|---|---|
| 236, 874 | Airtel | Check provider id with your manager |
| 237, 254, 875, 9115 | MTN | Check provider id with your manager |
| 238, 876 | ZAMTEL | Check provider id with your manager |
260000000000 - This is the format of the phone number you have to send in the payment requests.
| c2b minimum | b2c minimum | Maximum transaction limit |
|---|---|---|
| ZMW 1.00 | ZMW 1.00 | ZMW 20000.00 |
| c2b minimum | b2c minimum | Maximum transaction limit |
|---|---|---|
| ZMW 1.00 | ZMW 1.00 | ZMW 5000.00 |
| Provider ID | Provider Name | Notes |
|---|---|---|
| 662 | Airtel | Check provider id with your manager |
| 663 | TNM | Check provider id with your manager |
265000000000 - This is the format of the phone number you have to send in the payment requests.
For C2B payments, the flow is standard, no need to pass extra parameters For B2C payments, you should send a customer full name in the payment requests. Parameter extra->customer_name. Please see the example in the API Methods section.
| c2b minimum | b2c minimum | Maximum transaction limit |
|---|---|---|
| MWK 50.00 | MWK 50.00 | MWK 750000.00 |
| public_id required | string Example: f54ec96649be11ebb3780242ac130002 Merchant public ID |
Parameters to initiate a customer to the merchant payment
| merchant_id required | string (merchantIdDef) Unique Merchant ID received during the merchant registration |
| customer_id required | string (customerIdDef) Customer ID (usually mobile phone number of the customer) |
| order_id required | string (orderIdDef) The unique value is generated by the transaction initiator for each Operation. Max length is 128 symbols. Allowed symbols: [a-z], [A-Z], [0-9], “_” (underscore character), “-” (hyphen), “:” (colon), “.” (dot). For example, GUID or TIMESTAMP can be used as an order_id. This parameter provides API idempotency. It means that requests with identical nonce from the same transaction initiator will have identical responses and The corresponding operation won’t be repeated. |
| amount required | string Amount to pay, should be in format with two digits after point |
| currency required | string (currencyDef) Currency code in ISO 4217 format from the list of availabe currencies |
| country | string (countryDef) Country code in ISO 3166-1 alpha-2 format as defined in the payment providers. |
| callback_url | string URL to notify the merchant via callback. Recommended |
| provider_id required | integer (providerDef) Provider ID. Can be one of the option from this list. |
object Extra parameters | |
| signature required | string (signatureDef) Merchant’s request and callback have to be signed to verify sent data. To generate the signature all sent parameters are included in the order they were sent. The parameter signature should be excluded, of course. Example can be found here |
{- "merchant_id": "e0fecd91fcb24f348048193b3fb34875ba3722b4",
- "customer_id": "0900000001",
- "order_id": "16280954971628095497",
- "amount": "100.00",
- "currency": "ZMW",
- "country": "ZM",
- "provider_id": 14,
- "extra": {
- "customer_name": "Name Surname"
}, - "signature": "d7d6d76b0e22c6f9d369fa6c24f107053d12bfd24d3b154f2deb6676bf179c123134e1f20879c803be455d81cfe792f00cd8892c26ce7cf5a05beebb9c80843e"
}{- "order_id": "16280954971628095497",
- "transaction_id": "732007046722",
- "transaction_ref": "MP.33234.342.CP33",
- "status": 1,
- "result": {
- "code": 0,
- "message": "OK"
}, - "provider_result": {
- "code": 0,
- "message": "OK"
}, - "service_id": 1,
- "service_version": 11.1,
- "service_date_time": "2020-11-25 10:08:32.832969"
}{- "merchant_id": "e0fecd91fcb24f348048193b3fb34875ba3722b4",
- "operation_type": 17,
- "customer_id": "0900000001",
- "amount": 100,
- "order_id": "16280954971628095497",
- "transaction_id": "1234567",
- "transaction_ref": "QR555RQ",
- "status": 2,
- "provider_id": 14,
- "destination_id": "",
- "result": {
- "code": 0,
- "message": "OK"
}, - "provider_result": {
- "code": 0,
- "message": "OK"
}, - "service_id": 1,
- "service_version": "1.03/1.0|1.0/1.26|1.0/1.0|1.01/1.0|1.01/1.0||1.01/1.27",
- "service_date_time": "2020-11-25 10:08:32.832969",
- "signature": "d7d6d76b0e22c6f9d369fa6c24f107053d12bfd24d3b154f2deb6676bf179c123134e1f20879c803be455d81cfe792f00cd8892c26ce7cf5a05beebb9c80843e"
}Cashless payment from the merchant to the customer. If the confirm_type response parameter is a non-zero merchant, send the second payment_b2c request with confirmation data according to the section Confirmation Types.
| public_id required | string Example: f54ec96649be11ebb3780242ac130002 Merchant public ID |
Parameters to initiate the merchant to the customer payment
| merchant_id required | string (merchantIdDef) Unique Merchant ID received during the merchant registration |
| customer_id required | string (customerIdDef) Customer ID (usually mobile phone number of the customer) |
| order_id required | string (orderIdDef) The unique value is generated by the transaction initiator for each Operation. Max length is 128 symbols. Allowed symbols: [a-z], [A-Z], [0-9], “_” (underscore character), “-” (hyphen), “:” (colon), “.” (dot). For example, GUID or TIMESTAMP can be used as an order_id. This parameter provides API idempotency. It means that requests with identical nonce from the same transaction initiator will have identical responses and The corresponding operation won’t be repeated. |
| amount required | string Amount to pay, with two digits after point |
| currency required | string (currencyDef) Currency code in ISO 4217 format from the list of availabe currencies |
| country | string (countryDef) Country code in ISO 3166-1 alpha-2 format as defined in the payment providers. |
| callback_url | string URL to notify the merchant via callback |
| provider_id required | integer (providerDef) Provider ID. Can be one of the option from this list. |
object Extra parameters | |
| signature required | string (signatureDef) Merchant’s request and callback have to be signed to verify sent data. To generate the signature all sent parameters are included in the order they were sent. The parameter signature should be excluded, of course. Example can be found here |
{- "merchant_id": "e0fecd91fcb24f348048193b3fb34875ba3722b4",
- "customer_id": "0900000001",
- "order_id": "16280954971628095497",
- "amount": "100.00",
- "currency": "ZMW",
- "country": "ZM",
- "provider_id": 14,
- "extra": {
- "customer_name": "Name Surname"
}, - "signature": "d7d6d76b0e22c6f9d369fa6c24f107053d12bfd24d3b154f2deb6676bf179c123134e1f20879c803be455d81cfe792f00cd8892c26ce7cf5a05beebb9c80843e"
}{- "order_id": "16280954971628095497",
- "transaction_id": "732007046722",
- "transaction_ref": "MP.33234.342.CP33",
- "status": 1,
- "result": {
- "code": 0,
- "message": "OK"
}, - "provider_result": {
- "code": 0,
- "message": "OK"
}, - "service_id": 1,
- "service_version": 11.1,
- "service_date_time": "2020-11-25 10:08:32.832969"
}| public_id required | string Example: f54ec96649be11ebb3780242ac130002 Merchant public ID |
Get the status of the performed transaction
| merchant_id required | string (merchantIdDef) Unique Merchant ID received during the merchant registration |
| order_id required | string (orderIdDef) The unique value is generated by the transaction initiator for each Operation. Max length is 128 symbols. Allowed symbols: [a-z], [A-Z], [0-9], “_” (underscore character), “-” (hyphen), “:” (colon), “.” (dot). For example, GUID or TIMESTAMP can be used as an order_id. This parameter provides API idempotency. It means that requests with identical nonce from the same transaction initiator will have identical responses and The corresponding operation won’t be repeated. |
| signature required | string (signatureDef) Merchant’s request and callback have to be signed to verify sent data. To generate the signature all sent parameters are included in the order they were sent. The parameter signature should be excluded, of course. Example can be found here |
{- "merchant_id": "e0fecd91fcb24f348048193b3fb34875ba3722b4",
- "order_id": "16280954971628095497",
- "signature": "d7d6d76b0e22c6f9d369fa6c24f107053d12bfd24d3b154f2deb6676bf179c123134e1f20879c803be455d81cfe792f00cd8892c26ce7cf5a05beebb9c80843e"
}{- "order_id": "16280954971628095497",
- "transaction_id": "532007056722",
- "transaction_ref": "",
- "status": 1,
- "result": {
- "code": 0,
- "message": "OK"
}, - "provider_result": {
- "code": 0,
- "message": "OK"
}, - "extra": {
- "customer_message": "Complete the payment by following the instructions received by USSD"
}, - "service_id": 11,
- "service_version": 11.1,
- "service_date_time": "2020-11-25 10:08:32.832969",
- "confirm_type": 0
}