Payment Webhook API
Environment: Live
Successful P01 and failed P02 payment callbacks, transaction fields, failure reasons, and the full callback source IP allowlist.
# Payment Webhook API
Provide your callback URL when creating a wallet, activating API access, or generating a payment link. Moolre sends HTTP POST notifications to this URL for successful payments and failed payment attempts. Successful callbacks use P01; failed callbacks use P02 and include a failure reason.
## Endpoint
- **Method**: POST
- **URL**: {{YOUR_CALLBACK_URL}}
## Request Body
| Parameter | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| status | integer | Yes | 1 for a successful payment; 0 for a failed payment. |
| code | string | Yes | Payment outcome code: P01 (successful) or P02 (failed). Not an HTTP status code. |
| message | string | Yes | Outcome message, such as Transaction Successful or Transaction Failed. |
| data | object | Yes | Transaction details, including txstatus and externalref; failed callbacks may include reason and a null transactionid. |
| go | null | No | Navigation hint; null in these callback examples. |
## Transaction fields
The fields below are inside `data`.
| Field | Format | Description |
| :--- | :--- | :--- |
| txstatus | Integer | Transaction status: 1 (Successful), 0 (Pending), or 2 (Failed). |
| payer | String | The payer number associated with the payment attempt. A failed callback does not establish that funds were debited. |
| terminalid | String | Terminal ID associated with the payment. Can be an empty string. |
| accountnumber | String | The destination Moolre wallet account number. A failed callback does not mean this wallet was credited. |
| name | String | Merchant reference name or identifier associated with the terminal. Can be an empty string. |
| amount | String (decimal) | Transaction amount, encoded as a decimal string. Can be "0" in a failed callback. |
| value | String (decimal) | Transaction value after applicable fees, encoded as a decimal string. Can be "0" in a failed callback. |
| transactionid | String or null | Moolre transaction identifier. Can be null for a failed payment; use externalref to identify the payment attempt. |
| externalref | String | The reference supplied by your integration. Use it to correlate the callback with the payment attempt. |
| thirdpartyref | String | Transaction reference from the payment institution. Can be an empty string. |
| reason | String (when supplied) | Failure reason returned with a failed callback. May be absent from successful callbacks. Treat it as a diagnostic string, not a guaranteed list of separate causes. |
| secret | String | Callback verification secret. Validate it against the expected secret for your integration; never use the example placeholder as a real secret. |
| ts | String | Transaction timestamp (GMT), formatted as YYYY-MM-DD HH:mm:ss. |
## Handling callbacks
- Validate the callback and its expected secret before changing payment records. IP allowlisting is an additional safeguard, not a replacement for callback verification.
- Match data.externalref to the payment attempt in your system. Handle duplicate notifications idempotently so the same callback does not apply the same business action twice.
- For status 1, code P01, and data.txstatus 1, process the successful-payment outcome after validating the callback and transaction details.
- For status 0, code P02, and data.txstatus 2, record the failed attempt and its reason. Do not mark the payment as paid, credit the wallet, or fulfil an order from this callback.
- Accept null transactionid, zero-valued amount/value strings, and empty optional references in failed callbacks. Do not require a transactionid to find the attempt when externalref is available.
- A callback arriving at your server is not itself proof of a successful payment. The payment outcome is in the payload; P02 is a payload code, not an HTTP status code.
## Successful payment callback
A successful payment has status 1, code P01, and data.txstatus 1.
```json
{
"status": 1,
"code": "P01",
"message": "Transaction Successful",
"data": {
"txstatus": 1,
"payer": "233250130550",
"terminalid": "",
"accountnumber": "420500413146",
"name": "Nancy Naaki",
"amount": "15.21",
"value": "15.21",
"transactionid": "32712684",
"externalref": "vbundle_C2394897D48042826013EFC24A280676E3",
"thirdpartyref": "48149622075",
"secret": "YOUR_CALLBACK_SECRET",
"ts": "2024-11-27 21:11:29"
},
"go": null
}
```
## Failed payment callback
A failed payment has status 0, code P02, and data.txstatus 2. data.reason explains the failure; data.transactionid can be null.
```json
{
"status": 0,
"code": "P02",
"message": "Transaction Failed",
"data": {
"txstatus": 2,
"payer": "233245659500",
"terminalid": "",
"accountnumber": "10927206072742",
"name": "",
"amount": "0",
"value": "0",
"transactionid": null,
"externalref": "1791031157570_73837",
"thirdpartyref": "",
"reason": "LOW_BALANCE_OR_PAYEE_LIMIT_REACHED_OR_NOT_ALLOWED",
"secret": "YOUR_CALLBACK_SECRET",
"ts": "2026-10-03 12:44:23"
},
"go": null
}
```
## Callback Source IP Addresses
To help verify that incoming payment callbacks originate from Moolre, add the IP addresses listed below to your server's allowlist.
Moolre sends payment callbacks from these IP addresses. Allowlisting them helps protect your callback endpoint by restricting requests to approved sources.
| Version | Source address |
| --- | --- |
| IPv4 | `174.138.44.22` |
| IPv4 | `174.138.40.67` |
| IPv4 | `192.241.135.134` |
| IPv6 | `2604:a880:400:d1:0:3:4cf0:c001` |
| IPv6 | `2604:a880:400:d0::1a77:4001` |
| IPv6 | `2604:a880:400:d0::4234:2001` |
**Security Note:** IP allowlisting adds an extra layer of security but should not be your only method of verification. Always validate the callback secret, verify the transaction details, and use HTTPS to secure callback communication.