5. Implement Callback URL
When a full payment is made a JSON request is sent to the merchant’s paymentWebhookURL.
We do a POST request when sending the payment details to the merchant's callback URL.
When is a Webhook sent to Merchant?Webhook is only sent when the customer has made full payment for the request raised
Webhook Request
Payments array for both failed and successful payments array.
| Parameter Name | Type | Description |
|---|---|---|
| payerClientCode | string | A unique identifying code of the payment option that will be used to initiate the request or was used to complete the payment. E.g. 'MPESA' for Mpesa payment option. |
| payerClientName | string | Identifier of the option that was used to make the payment e.g. Mpesa. |
| payerTransactionID | string | A unique identifier of the payment as logged on the payment channel's platform. This may be logged by the merchant for easier transaction tracking and support for customers. |
| currencyCode | string | The three character currency code (ISO 4217) used for the payment. |
| amountPaid | string | The amount received from the payment channel the customer paid from. |
| customerName | string | The name of the customer who made the payment. Available for payment options where the customer names are provided. |
| hubOverallStatus | string | Internal Cellulant processing status for the payment. |
| MSISDN | string | The mobile number that the payment originated from. |
| serviceCode | string | Identifier for the service that request has be raised to. |
| cpgTransactionID | string | A unique identifier to identify the payment on the Cellulant's payment Gateway. |
| accountNumber | string | Reference for the item being paid for eg: Pay TV account number or Airline ticket number. |
| datePaymentReceived | string | The date in which the payment was logged onto the cellulant payment gateway. |
| payerNarration | string | This is the MNO or bank payment narration shared to Cellulant. |
{
"serviceCode": "TESTSERVICE",
"MSISDN": "254713123888",
"originalRequestCurrencyCode": "KES",
"originalRequestAmount": 200,
"checkoutRequestID": 4826296,
"requestCurrencyCode": "KES",
"requestAmount": "200.00",
"accountNumber": "3201HR00",
"requestStatusCode": 178,
"requestStatusDescription": "Request fully paid",
"merchantTransactionID": "r77az121236884",
"requestDate": "2018-08-28 12:12:38.0",
"currencyCode": "KES",
"amountPaid": 200,
"serviceChargeAmount": 0,
"payments": [
{
"MSISDN": 254713123888,
"payerClientName": "Safaricom Kenya Limited",
"currencyCode": "KES",
"amountPaid": 200,
"cpgTransactionID": "288852770",
"serviceCode": "TESTSERVICE",
"payerTransactionID": "OHS01A3K",
"hubOverallStatus": 139,
"accountNumber": "3201HR00",
"customerName": "Customer",
"payerClientCode": "SAFKE",
"datePaymentReceived": "2018-08-28 12:13:33.0"
}
],
"failedPayments": []
}{
"serviceCode": "TESTSERVICE",
"MSISDN": "254713123888",
"originalRequestCurrencyCode": "KES",
"originalRequestAmount": 200,
"checkoutRequestID": 4826296,
"requestCurrencyCode": "KES",
"requestAmount": "200.00",
"accountNumber": "3201HR00",
"requestStatusCode": 99,
"requestStatusDescription": "Request fully paid",
"merchantTransactionID": "r77az121236884",
"requestDate": "2018-08-28 12:12:38.0",
"currencyCode": "KES",
"amountPaid": 200,
"serviceChargeAmount": 0,
"payments": [],
"failedPayments": [
{
"MSISDN": 254713123888,
"payerClientName": "Safaricom Kenya Limited",
"currencyCode": "KES",
"amountPaid": 200,
"cpgTransactionID": "288852770",
"serviceCode": "TESTSERVICE",
"payerTransactionID": "OHS01A3K",
"hubOverallStatus": 139,
"accountNumber": "3201HR00",
"customerName": "Customer",
"payerClientCode": "SAFKE",
"paymentStatus": "INSUFFICIENT_BALANCE",
"datePaymentReceived": "2018-08-28 12:13:33.0"
}
]
}Failed Payment Status (Work in Progress)
Kindly note on callback under the failed payments array we will send the field paymentStatus with the exact status code of why the request failed on the MNO's end. Here overallStatus for the request will be 99 or 101 or 102 however the individual failed payment will have the correct status code with the reason for failure. Note the new field showing the actual failure reason will be under failedPayments[].paymentStatus
| Status Code | Description |
|---|---|
| FAILED | Generic failure reason given by the payment provider. |
| TIMEOUT | There was a timeout when MNO was sending request to end users handset or customer did not enter their pin in time. |
| INVALID_PIN | Customer entered incorrect pin. |
| BLOCKED | Customers mobile number was blocked by the MNO. |
| INSUFFICIENT_BALANCE | This indicates customer does not have enough money in their wallet to complete these transactions. |
| CANCELLED | Request was cancelled by the customer. |
| LIMIT_EXCEEDED | Declined due to limit rule: would exceed or fall below the transfer limits |
| SUCCESS | Payment was debited successfully. |
| ERROR | Internal error / network timeout when trying to reach the MNO / Authentication error when sending the request to the MNO |
| NOT_ALLOWED | Customer is not allowed to make such a transaction either due to decimals or their account is on hold or it is a suspected fraudulent transaction |
| ENGAGED | Handset has a similar request they are processing hence cannot proceed. |
| INVALID | For the request sent one of the parameters are not correct and has a problem. |
| ACCOUNT_NOT_FOUND | MSISDN or wallet is not available on the acquirers end. |
Expected Webhook Response
The merchant is expected to send back a response with the following parameters:
Examples
Payment processed successfully
{
"checkoutRequestID": 4826296,
"merchantTransactionID": "abcd-efg-hijklm",
"statusCode": "183",
"statusDescription": "Payment processed successfully",
"receiptNumber": "r77az121236884"
}Payment processing failed
{
"checkoutRequestID": 4826296,
"merchantTransactionID": "abcd-efg-hijklm",
"statusCode": "180",
"statusDescription": "Payment was not processed successfully",
"receiptNumber": ""
}Updated 29 days ago
