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

  <th>
    Type
  </th>

  <th>
    Description
  </th>
</tr>
  <td>
    `integer`
  </td>

  <td>
    Unique transaction ID identifying the transaction as provided by the checkout platform.
  </td>
</tr>

<tr>
  <td>
    merchantRequestID
  </td>

  <td>
    `string`
  </td>

  <td>
    Unique transaction ID identifying the transaction as given by the merchant.
  </td>
</tr>

<tr>
  <td>
    requestStatusCode
  </td>

  <td>
    `integer`
  </td>

  <td>
    Request status after the customer makes the payment.

    99 - A failed payment has been received for this request. Request is still open to receive payments.

    102 - Insufficient funds

    101 - Invalid pin/canceled

    129 - Request has expired with no partial payment received.

    176 - Partial payment made for the request and has been marked as closed. Available for merchants who accept partial payments for their request.

    178 - Full payment made for the request.

    179 - Request has expired with one or more partial payments made. The partial payment(s) will be reversed.

    186 - This is indicates that the partial refund for the request was successfully processed.

    187 - This is indicates that the full refund for the request was successfully processed.

    191 - This indicates a failed refund.
  </td>
</tr>

<tr>
  <td>
    requestStatusDescription
  </td>

  <td>
    `string`
  </td>

  <td>
    Request status description.
  </td>
</tr>

<tr>
  <td>
    MSISDN
  </td>

  <td>
    `string`
  </td>

  <td>
    Customer mobile number.
  </td>
</tr>

<tr>
  <td>
    serviceCode
  </td>

  <td>
    `string`
  </td>

  <td>
    Identifier for the service that request has be raised to.
  </td>
</tr>

<tr>
  <td>
    accountNumber
  </td>

  <td>
    `string`
  </td>

  <td>
    Reference for the item being paid for eg: Pay TV account number or Airline ticket number.
  </td>
</tr>

<tr>
  <td>
    currencyCode
  </td>

  <td>
    `string`
  </td>

  <td>
    The three character currency code (ISO 4217) used for the payment.
  </td>
</tr>

<tr>
  <td>
    amountPaid
  </td>

  <td>
    `double`
  </td>

  <td>
    Amount received from customer.
  </td>
</tr>

<tr>
  <td>
    requestCurrencyCode
  </td>

  <td>
    `string`
  </td>

  <td>
    A three character currency code (ISO 4217) that the transaction was converted to for collection.
  </td>
</tr>

<tr>
  <td>
    requestAmount
  </td>

  <td>
    `integer`
  </td>

  <td>
    Amount of the transaction request after conversion.
  </td>
</tr>

<tr>
  <td>
    requestDate
  </td>

  <td>
    `string`
  </td>

  <td>
    Date and time payment was logged into the Cellulant Payment Gateway.
  </td>
</tr>

<tr>
  <td>
    payments
  </td>

  <td>
    `JSON Array`
  </td>

  <td>
    List of individual payments made for the checkout request.
  </td>
</tr>

<tr>
  <td>
    serviceChargeAmount
  </td>

  <td>
    `integer`
  </td>

  <td>
    Extra charge set if available for the service.
  </td>
</tr>

<tr>
  <td>
    originalRequestAmount
  </td>

  <td>
    `double`
  </td>

  <td>
    The original amount that was passed on the request to checkout.
  </td>
</tr>

<tr>
  <td>
    originalRequestCurrencyCode
  </td>

  <td>
    `string`
  </td>

  <td>
    Original currency code provided on the request to checkout
  </td>
</tr>

<tr>
  <td>
    failedPayments
  </td>

  <td>
    `JSON Array`
  </td>

  <td>
    An array of failed payment attempts by the customer.  Available only if service is enabled to receive failed notifications. Contact Cellulant to activate this option.
  </td>
</tr>
Parameter Name
checkoutRequestID

Payments array for both failed and successful payments array.

Parameter NameTypeDescription
payerClientCodestringA 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.
payerClientNamestringIdentifier of the option that was used to make the payment e.g. Mpesa.
payerTransactionIDstringA 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.
currencyCodestringThe three character currency code (ISO 4217) used for the payment.
amountPaidstringThe amount received from the payment channel the customer paid from.
customerNamestringThe name of the customer who made the payment. Available for payment options where the customer names are provided.
hubOverallStatusstringInternal Cellulant processing status for the payment.
MSISDNstringThe mobile number that the payment originated from.
serviceCodestringIdentifier for the service that request has be raised to.
cpgTransactionIDstringA unique identifier to identify the payment on the Cellulant's payment Gateway.
accountNumberstringReference for the item being paid for eg: Pay TV account number or Airline ticket number.
datePaymentReceivedstringThe date in which the payment was logged onto the cellulant payment gateway.
payerNarrationstringThis 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 CodeDescription
FAILEDGeneric failure reason given by the payment provider.
TIMEOUTThere was a timeout when MNO was sending request to end users handset or customer did not enter their pin in time.
INVALID_PINCustomer entered incorrect pin.
BLOCKEDCustomers mobile number was blocked by the MNO.
INSUFFICIENT_BALANCEThis indicates customer does not have enough money in their wallet to complete these transactions.
CANCELLEDRequest was cancelled by the customer.
LIMIT_EXCEEDEDDeclined due to limit rule: would exceed or fall below the transfer limits
SUCCESSPayment was debited successfully.
ERRORInternal error / network timeout when trying to reach the MNO / Authentication error when sending the request to the MNO
NOT_ALLOWEDCustomer 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
ENGAGEDHandset has a similar request they are processing hence cannot proceed.
INVALIDFor the request sent one of the parameters are not correct and has a problem.
ACCOUNT_NOT_FOUNDMSISDN 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:

  <th>
    Type
  </th>

  <th>
    Description
  </th>

  <th>
    Required
  </th>
</tr>
  <td>
    `integer`
  </td>

  <td>
    Unique transaction ID identifying the transaction as provided by the checkout platform.
  </td>

  <td>
    TRUE
  </td>
</tr>

<tr>
  <td>
    merchantTransactionID
  </td>

  <td>
    `string`
  </td>

  <td>
    Unique transaction ID identifying the transaction as given by the merchant.
  </td>

  <td>
    FALSE
  </td>
</tr>

<tr>
  <td>
    statusCode
  </td>

  <td>
    `integer`
  </td>

  <td>
    A status indicating the result of payment processing.

    180 - The payment was rejected by the merchant. Only accepted if the notification was for a full request.

    183 - The payment was accepted by the merchant. Only accepted if the notification was for a full request.

    188 - The payment/request was received. Acknowledgement will be initiated later if the notification was for a fully paid request. See Acknowledge Payment on custom API for details.

    For a failed payment notification, no further action will be taken.

    189 - There was an error in processing the payments/request on the merchant's platform. The request should be re-sent for processing.
  </td>

  <td>
    TRUE
  </td>
</tr>

<tr>
  <td>
    statusDescription
  </td>

  <td>
    `string`
  </td>

  <td>
    A description of the status provided above
  </td>

  <td>
    TRUE
  </td>
</tr>

<tr>
  <td>
    receiptNumber
  </td>

  <td>
    `string`
  </td>

  <td>
    A transaction ID indicating the receipt of the payments.
  </td>

  <td>
    TRUE
  </td>
</tr>
Parameter Name
checkoutRequestID

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": ""
}