Webhook
1. Overview
When a payment succeeds or a refund is completed, whether it succeeds or fails,
RedotPay Connect's system will send a webhook to the merchant’s webhook URL.
Webhooks are sent separately for payment events and refund events.
If a webhook request fails (for example, due to a timeout or an error response), RedotPay Connect automatically retries it according to the retry policy.
NOTED: Webhooks also require signature verification.The signature will be passed by RedotPay Connect in the request header X-R-Signature during the webhooks.
2. Webhook Mechanism
| Webhook Type | Description | Trigger Condition |
|---|---|---|
| PAYMENT | Notifies the merchant of the payment result | Sent when a payment succeeds |
| REFUND | Notifies the merchant of the refund result | Sent when a refund succeeds or fails |
Each webhook is asynchronous and stateless.
Make sure your system handles it idempotently so retries do not cause duplicate processing.
Signature Verification
To ensure the authenticity and integrity of incoming webhook notifications and prevent forged requests, it is strongly recommended to verify the validity of the X-R-Signature header before processing any business logic.
The verification process involves extracting the signature, timestamp, and key version from the request headers, and validating them using your appKey and RedotPay's public key.
For the complete signature verification steps, code examples in multiple languages, and troubleshooting, please refer to the “Verifying RedotPay Callback Notification Signatures” section in the Request Signature and Verification Guide.
3. Payment Webhook
Request Example
{
"outerOrder": "T300088...",
"preSn": "RAP202601051045558385...",
"orderCurrency": "USD",
"billCoin": "USD",
"outerUid": "T3111...",
"txId": "PAYH20260105104613401...",
"rateExtra": 0,
"actionType": "ACQUIRER_PAY",
"billAmount": 0.99,
"orderAmount": 1,
"orderTime": 1767609970940,
"merchantId": 3000000...,
"cryptoAmount": 1,
"rate": 1,
"walletName": "redotpay",
"paymentDeadline": 1767611755616,
"sn": "RA20260105104610940923...",
"paymentTime": 1767609973423,
"orderStatus": 2,
"coin": "USDT",
"clientIp": "13.230.109.247",
"source": "WEB"
}
| Field | Type | Required | Description |
|---|---|---|---|
outerOrder | String | Yes | Merchant’s original order number. DEPRECATED |
outerOrderSn | String | Yes | Merchant’s original order number |
preSn | String | Yes | Prepayment serial number, used to match previous requests. DEPRECATED |
orderSn | String | Yes | Prepayment serial number, used to match previous requests |
orderCurrency | String | Yes | Order's fiat currency |
billCoin | String | Yes | Bill's fiat currency. DEPRECATED |
fiatCurrency | String | Yes | Bill's fiat currency |
outerUid | String | Yes | External user ID or identifier passed when the payment was created |
txId | String | Yes | Channel payment transaction id |
rateExtra | decimal | Yes | Merchant exchange rate markup |
actionType | String | Yes | Type of payment webhbook action. Always"ACQUIRER_PAY"for payment webhooks |
billAmount | decimal | Yes | Bill's fiat amount |
orderAmount | decimal | Yes | Order's fiat amount |
orderTime | long | Yes | Order creation time in milliseconds |
merchantId | long | Yes | Merchant's unique ID |
cryptoAmount | decimal | Yes | Total crypto currency amount of orders |
rate | String | Yes | Fiat to cryptocurrency exchange rates |
walletName | String | Yes | Payment selection wallet name. DEPRECATED |
paymentMethod | String | Yes | Payment selection wallet name |
paymentDeadline | long | Yes | Payment deadline in milliseconds. DEPRECATED |
timeExpire | long | Yes | Payment deadline in milliseconds |
sn | String | Yes | Payment serial number |
paymentTime | long | Yes | Successful payment completion time(timestamp in milliseconds) |
orderStatus | int | Yes | Payment status:1= Paying; 2= Success; 3= Payment failed; 4= Payment closed |
clientIp | String | Yes | Buyer's terminal ip |
source | String | Yes | buyer's source: H5/APP/WEB |
4. Refund Webhook
Request Example
{
"refundSn": "RE2025121402253023...",
"merchantRefundSn": "TestRefund20251201...",
"merchantId": 2135213432...,
"status": "SUCCESS",
"completeTime": 1768357531591,
"outerOrderSn": "test-quick-pay-1768301309...",
"refundType": "redotpay",
"createTime": 1768354530000,
"refundAmount": 0.01001,
"refundCurrency": "USDT",
"eventType": "MERCHANT"
}
Field Description
| Field | Type | Required | Description |
|---|---|---|---|
merchantRefundSn | String | Yes | Refund serial number sent by the merchant when initiating the refund |
refundSn | String | Yes | Refund reference number |
status | String | Yes | Refund result status: REFUNDING、SUCCESS、FAILED |
failRason | String | No | Explains why refund order fails |
merchantId | int | Yes | Merchant's unique ID |
failReason | String | No | Reason the refund failed |
completeTime | long | Yes | Refund completion time (timestamp in milliseconds) |
outerOrderSn | String | Yes | Merchant’s original payment number related to the refund |
eventType | String | Yes | Type of refund webhook event "MERCHANT"= refund initiated by the merchant "PAY_DUPLICATION"= refund for duplicate payments; "PAY_EXPIRED" = refund for expired payments |
refundType | String | Yes | Refund channel types(Refund via original payment channel) |
refundCurrency | String | Yes | Currency of refund order |
address | String | No | Refund wallet address(returned only for Web3 decentralized payments |
5. Expected Merchant Response
After your system processes the webhook, your endpoint should return the following JSON response:
Response Example
{
"code": "SUCCESS",
"requestId": "0195c081-d54e-4569-a657-0f54388fa9ba"
}
{
"code": "FAIL",
"requestId": "0d992439-38a7-4674-9e06-19a7602eae2e",
"msg":"update failed"
}
Response Rules
| Field | Type | Required | Description |
|---|---|---|---|
code | String | Yes | "SUCCESS"or "FAIL" |
msg | String | No | Error message, present only when code is "FAIL" |
requestId | String | Yes | Unique request ID |
Retry Policy
| Condition | Retry Interval | Max Retries |
|---|---|---|
Non-SUCCESS code response | 180 seconds | 3 |
The webhook is marked as failed after all retry attempts.
You can then use the query APIs to manually check the transaction or refund status.
Updated about 1 month ago
