Webhook Integration Guide¶
Trigger Events¶
The system will send webhook notifications when a transaction enters the following statuses. Each notification will retry up to a maximum number of times until a valid success response is received or the retry limit is reached.
Webhook Event | tradeType Fields |
requestStatus Fields |
Description |
---|---|---|---|
DepositTransactionInProgress | Deposit |
InProgress |
The deposit order has been marked as paid by the client. Payment confirmation is currently in progress. |
DepositTransactionFinished | Deposit |
Finished |
The deposit order has been successfully completed. |
DepositTransactionFailed | Deposit |
Failed |
The deposit order payment has failed. The failure reason can be retrieved from the message field. |
DepositTransactionCancelled | Deposit |
Cancelled |
The deposit order has been cancelled. The cancellation reason can be retrieved from the message field. |
WithdrawTransactionInProgress | Withdraw |
InProgress |
The withdrawal order is in progress. The system is currently processing the payout to the client. |
WithdrawTransactionFinished | Withdraw |
Finished |
The withdrawal order has been successfully completed. |
WithdrawTransactionFailed | Withdraw |
Failed |
The withdrawal order payment has failed. The failure reason can be retrieved from the message field. |
WithdrawTransactionCancelled | Withdraw |
Cancelled |
The withdrawal order has been cancelled. The cancellation reason can be retrieved from the message field. |
Important Security Notice¶
Upon receiving a webhook request, it is crucial to perform a verification of the signature
and timestamp
fields to
ensure the request's authenticity
and protect against external attacks.
Steps to Verify:¶
- Signature Validation: Ensure that the
signature
in the request matches the expected signature generated using the secret key and the payload. - Timestamp Check: Verify that the
timestamp
is within an acceptable range to avoid replay attacks (e.g., ensure the timestamp is within a few minutes of the current server time).
This extra layer of security ensures that the webhook requests are coming from a trusted source and prevents unauthorized or fraudulent access.
Webhook Payload¶
Webhook requests use the following JSON structure and are sent via HTTP POST with Content-Type: application/json
.
Request Body¶
Parameter | Type | Description |
---|---|---|
tradeType | TradeType | Transaction type: Deposit or Withdraw |
requestCode | String | Unique system-generated request code |
merchantOrderNo | String | Merchant's unique order number |
internalOrderNo | String | Internal system order number |
source | SourceFrom | Request source: MerchantBackend , API_V1 , API_V2 |
clientName | String | Client's name |
requestAmount | BigDecimal | Requested transaction amount |
requestCurrency | String | Currency of the transaction (e.g., MTC/CNY/HKD) |
message | String | Status message or additional information |
paymentMethod | PaymentOption? | Payment method used, if applicable |
requestStatus | RequestStatus | Current status of the transaction |
unitPrice | BigDecimal | Exchange rate used (fiat / MTC) |
transactionAmount | BigDecimal | Transaction Amount (MTC) |
receivedAmount | BigDecimal | Merchant received/deducted by the client |
transactionFee | BigDecimal | Transaction fee charged |
paymentAmount | BigDecimal | Final payment amount in fiat |
fiatCurrency | CurrencyCode | Fiat currency code: CNY, HKD |
Webhook Request Example¶
On Deposit In Progress¶
POST https://{MERCHANT_CALLBACK_HOST}/{MERCHANT_CALLBACK_ROUTE}
Host: {MERCHANT_CALLBACK_HOST}
Content-Type: application/json; charset=utf-8
{
"signature": "101EECC76667EBE8A6A252FCE493CFA97CAEBE1935666CF0B2C7ADE424B64D09",
"timestamp": 1742147003264,
"data": {
"tradeType": "Deposit", <-- Current trade type is [Deposit]
"requestCode": "7a4170465c994e8fa313efada0b0e4b6",
"merchantOrderNo": "ORDER_ID_HERE",
"internalOrderNo": "AT-D-3UNT8SRUN",
"source": "API_V2",
"clientName": "USER_REAL_NAME",
"requestAmount": 3213.44,
"requestCurrency": "CNY",
"message": "",
"paymentMethod": "BankCard",
"requestStatus": "InProgress", <-- Current status is [InProgress]
"unitPrice": 7.47,
"transactionAmount": 430.18,
"receivedAmount": 417.27,
"transactionFee": 12.91,
"paymentAmount": 3213.44,
"fiatCurrency": "CNY"
}
}
On Deposit Finished¶
POST https://{MERCHANT_CALLBACK_HOST}/{MERCHANT_CALLBACK_ROUTE}
Host: {MERCHANT_CALLBACK_HOST}
Content-Type: application/json; charset=utf-8
{
"signature": "86C70FA0D62BAA24EA35D6116BFF93A66336C856495DD4E0FA22F82E1556C5AE",
"timestamp": 1742147325570,
"data": {
"tradeType": "Deposit", <-- Current trade type is [Deposit]
"requestCode": "7a4170465c994e8fa313efada0b0e4b6",
"merchantOrderNo": "ORDER_ID_HERE",
"internalOrderNo": "AT-D-3UNT8SRUN",
"source": "API_V2",
"clientName": "USER_REAL_NAME",
"requestAmount": 3213.44,
"requestCurrency": "CNY",
"message": "",
"paymentMethod": "BankCard",
"requestStatus": "Finished", <-- Current status is [Finished]
"unitPrice": 7.47,
"transactionAmount": 430.18,
"receivedAmount": 417.27,
"transactionFee": 12.91,
"paymentAmount": 3213.44,
"fiatCurrency": "CNY"
}
}
Response Handling¶
The server will validate the webhook response based on your system’s return value.
Response Validation Logic¶
- The response must return either:
- A plain string equal to the string
success
, or - A JSON object with a field matching the
success
, and its value must be true.
- A plain string equal to the string
- If the response does not match, the webhook will retry until the maximum retry count is reached.
Sample Response (Plain Text)¶
Sample Response (JSON)¶
Webhook Retry Logic¶
To ensure reliable delivery, webhook notifications support automatic retries when a callback fails. Below is an explanation of the retry mechanism and its configuration.
To ensure eventual data consistency, please make sure your callback interface is implemented with idempotency.
Callback Execution Flow¶
When a webhook is triggered, the system will attempt to send the request to the configured webhookUrl
. Based on the
response, the system determines whether the callback was successful or needs to be retried.
Retry Status Logic¶
- Success: If the callback response is valid (see Callback Response Validation), the
status is marked as
success
and no further retries are made. - NeedRetry: If the response is invalid but retry attempts to remain, the status is marked as
NeedRetry
, and the next retry time is calculated. - Failed: If all retry attempts have been exhausted, the status is marked as
Failed
.
Retry Schedule¶
The retry system follows a progressive delay strategy based on the number of failed attempts. Below is the schedule:
Attempt Number | Delay Before Retry (Minutes) |
---|---|
1 | 1 |
2 | 1 |
3 | 1 |
4 | 5 |
5 | 30 |
6 | 30 |
7-16 | 60 |
- The system allows up to 16 retry attempts per webhook event.
- If all retries fail, no further callbacks will be attempted.