Skip to main content

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.
Configure Webhook URLs in the dashboard. Callback URLs can be set per-payment when initializing a payment.

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

  1. Extract the timestamp from X-ChainPal-Timestamp
  2. Extract the signature from X-ChainPal-Signature (remove the v1= prefix)
  3. Create the signed content: {timestamp}.{raw_request_body}
  4. Compute HMAC-SHA256 of the signed content using your webhook signing secret
  5. 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 the id field to detect duplicate events. Store processed event IDs and skip duplicates.

3. Verify Before Acting

Always verify the payment status via the API before fulfilling an order:

4. Use HTTPS

Always use HTTPS for your webhook endpoint to ensure the payload is encrypted in transit.

5. Validate Timestamps

Reject webhooks with timestamps that are too old (e.g., more than 5 minutes) to prevent replay attacks: