Webhooks
Webhooks allow you to receive real-time notifications when events occur in your ChainPal account, such as when a payment is completed or fails.Configuration
Configure your webhook URLs in the ChainPal Dashboard under Integration > Webhooks. You can set separate webhook URLs for:- Live Environment: Receives events from production payments
- Test Environment: Receives events from test payments
You must generate a Webhook Signing Secret before you can configure
webhook URLs. This secret is used to verify that webhooks originate from
ChainPal.
Webhook URLs vs Callback URLs
- Webhook URL: A server-to-server endpoint that receives event notifications (POST requests) from ChainPal. Used for backend processing.
- Callback URL: A frontend redirect URL where customers are sent after payment. The payment ID and reference are appended as query parameters. Used for displaying success/failure pages to customers.
Webhook Delivery
When an event occurs, ChainPal sends an HTTP POST request to your configured webhook URL with:- Content-Type:
application/json - Method:
POST - Timeout: 10 seconds
- Retries: Up to 7 attempts with exponential backoff
Retry Schedule
If your endpoint doesn’t respond with a 2xx status code, we retry with the following schedule:
After 7 failed attempts (spanning approximately 31 hours), the webhook is marked as exhausted and no further retries are attempted.
Event Payload Structure
All webhook events follow this structure:Top-Level Fields
Event Types
About
reference vs clientReference in data: Both fields carry the
same value — the clientReference you supplied when initializing the payment
(or the one ChainPal generated for you if you didn’t pass one). reference
is kept as a legacy alias; new integrations should read clientReference.payment.received
Sent immediately when the initial cryptocurrency transaction is detected on the blockchain, before fiat processing completes.payment.completed
Sent when a payment has been successfully received and processed into fiat.payment.failed
Sent when a payment has failed (e.g., expired, underpaid, or processing error).Signature Verification
Every webhook request includes signature headers that you should use to verify the request originated from ChainPal.Headers
Verification Process
- Extract the timestamp from
X-ChainPal-Timestamp - Extract the signature from
X-ChainPal-Signature(remove thev1=prefix) - Create the signed content:
{timestamp}.{raw_request_body} - Compute HMAC-SHA256 of the signed content using your webhook signing secret
- Compare your computed signature with the received signature
Example: Node.js Verification
Example: Python Verification
Example: Go Verification
Best Practices
1. Respond Quickly
Return a 2xx response as quickly as possible. Process the webhook asynchronously if needed.2. Handle Duplicates
Use theid field to detect duplicate events. Store processed event IDs and skip duplicates.

