Webhook Notifications — API Checkout
When a checkout order status changes, PSC sends a POST request to your callbackUrl.
Webhook Request Headers
| Header | Type | Description | Example |
|---|---|---|---|
X-Timestamp | Long | Notification timestamp (milliseconds) | 1640000000000 |
X-Signature | String | Request signature (Base64-encoded). Algorithm: Base64(HMAC-SHA256(timestamp + "\n" + "POST" + "\n" + path + "\n" + Base64(SHA256(requestBody)), apiSecret)) | base64-hmac-sha256 |
Signature Verification
- Extract
X-TimestampandX-Signaturefrom the request headers - Read the complete raw request body as a string (do not re-serialize)
- Compute:
bodySha256Base64 = Base64(SHA256(requestBody))signContent = timestamp + "\n" + "POST" + "\n" + path + "\n" + bodySha256Base64expectedSignature = Base64(HMAC-SHA256(signContent, apiSecret))
- Compare
expectedSignaturewithX-Signature - Verify the timestamp is within 5 minutes to prevent replay attacks
Webhook Body Fields
| Field | Type | Description | Example |
|---|---|---|---|
acquiringOrderId | String | Platform order ID | ORD_20240101_1234567890ABCDEF |
paymentOrderId | String | Payment order ID | PAY_20240101_1234567890ABCDEF |
merchantId | String | Merchant ID | MCH_20240101_ABC123 |
merchantOrderId | String | Merchant order ID | ORDER_2024010112345678 |
status | String | Order status: PROCESSING / SUCCEEDED / FAILED / CLOSED | SUCCEEDED |
finalStatus | Boolean | Whether this is a terminal status | true |
orderAmount | Object | Order amount | {"value": "100.50", "currency": "USDC"} |
cryptoPaymentAmount | Object | Required payment amount | {"value": "101.00", "currency": "USDC"} |
cryptoPaidAmount | Object | Actual amount paid | {"value": "101.00", "currency": "USDC"} |
depositAddress | String | Deposit address | TYdRLmP9kN4oY3hZ8xT6wQ2vS5uW7aV1b |
network | String | Blockchain network code | tron |
networkDisplayName | String | Network display name | TRON Network |
cryptoPaymentDetail | Object | On-chain transaction details (same structure as Query Order) | - |
paymentMethodType | String | Payment method type | ON_CHAIN_TRANSFER |
paymentMethodValue | String | Payment method value (null for on-chain) | null |
callbackUrl | String | Merchant's callback URL | https://api.merchant.com/webhooks/payment |
Response Requirements
Your endpoint must respond within 5 seconds with HTTP 200 and:
json
{
"code": "00000"
}Any non-200 response or timeout will trigger a retry.
Retry Schedule
| Attempt | Delay after previous failure |
|---|---|
| 1 | 1 minute |
| 2 | 5 minutes |
| 3 | 15 minutes |
| 4 | 30 minutes |
| 5 | 1 hour |
| 6 | 2 hours |
| 7 | 4 hours |
| 8 | 8 hours |
After all retries are exhausted, query the order status manually using the Query Checkout Order API.
Webhook Example
json
{
"acquiringOrderId": "ORD_20240101_1234567890ABCDEF",
"paymentOrderId": "PAY_20240101_1234567890ABCDEF",
"merchantId": "MCH_20240101_ABC123",
"merchantOrderId": "ORDER_2024010112345678",
"status": "SUCCEEDED",
"finalStatus": true,
"orderAmount": {
"value": "100.50",
"currency": "USDC"
},
"cryptoPaymentAmount": {
"value": "101.00",
"currency": "USDC"
},
"cryptoPaidAmount": {
"value": "101.00",
"currency": "USDC"
},
"depositAddress": "TYdRLmP9kN4oY3hZ8xT6wQ2vS5uW7aV1b",
"network": "tron",
"networkDisplayName": "TRON Network",
"cryptoPaymentDetail": {
"network": "tron",
"cryptoCurrency": "USDC",
"transactionHash": "0x1234567890abcdef1234567890abcdef",
"fromAddress": "TXdQKjYz8f9vN3kYh2xL6mP8sR5wT7uV2a",
"toAddress": "TYdRLmP9kN4oY3hZ8xT6wQ2vS5uW7aV1b",
"amount": "101.00",
"confirmations": 21,
"requiredConfirmations": 21
},
"paymentMethodType": "ON_CHAIN_TRANSFER",
"paymentMethodValue": null,
"callbackUrl": "https://api.merchant.com/webhooks/payment"
}Related Documentation
- API Checkout Reference - Full API endpoint and field reference
- API Checkout Integration Guide - Step-by-step integration
- Signature Algorithm - Signature calculation details