Webhooks & Events
Copperx uses webhooks to send real-time notifications to your server whenever important events occur in your account. This enables you to automate backend actions.
โ
What is a Webhook?
A webhook is a POST request sent from Copperx to your serverโs endpoint whenever a specific event occurs. It carries a JSON payload describing the event and its associated data.
Why Use Webhooks? Instead of continuously calling the API to check for payment status updates, Copperx sends real-time events to your backend. This reduces overhead and ensures your app stays in sync.
Typical Flow:
User completes a payment (e.g., Checkout Session).
Copperx sends a webhook event (
checkout_session.completed
) to your endpoint.Your backend verifies the webhook and updates the userโs plan or access.
๐ Webhook Security & Signature Verification
For security, Copperx signs every webhook payload using an HMAC-SHA256 signature.
Headers in the Webhook Request:
HeaderDescriptionx-webhook-signature
HMAC-SHA256 signature of the raw payload
x-webhook-token
Your webhook secret key (from dashboard)
How to Verify the Signature:
Retrieve the
x-webhook-signature
header from the request.Compute your own HMAC-SHA256 hash of the raw request body using your webhook secret key.
Compare your hash with the
x-webhook-signature
. If they match, the webhook is valid.
You can find your webhook secret key in the Copperx dashboard settings.
๐ Common Webhook Events
Below are the most commonly used events in Copperxโs payment flows:
checkout_session.completed
User successfully completed the checkout.
checkout_session.expired
Checkout session expired before payment completion.
checkout_session.canceled
User canceled the checkout session.
invoice.paid
An invoice was paid successfully.
invoice.finalized
An invoice was finalized (ready to be paid).
invoice.payment_failed
Payment for an invoice failed.
customer.subscription.created
A new subscription was created.
customer.subscription.started
Subscription started.
customer.subscription.deleted
Subscription was canceled/deleted.
customer.subscription.past_due
Subscription payment is past due.
customer.subscription.unpaid
Subscription payment is unpaid.
payment_intent.succeeded
PaymentIntent was successfully completed.
payment_intent.failed
PaymentIntent failed.
๐จ Example Webhook Payload: Checkout Session Completed
When a checkout session is completed, hereโs an example of the JSON payload you will receive:
{
"id": "00b6d1b6-93ce-4d6d-86b4-a7ab8fe14d87",
"apiVersion": "2023-01-11",
"created": 1748329965626,
"object": "checkoutSession",
"type": "checkout_session.completed",
"data": {
"object": {
"id": "fe6b7b01-1c4b-4b35-a5a5-a23b0a089cc6",
"createdAt": "2025-05-27T07:12:19.165Z",
"updatedAt": "2025-05-27T07:12:45.582Z",
"mode": "payment",
"paymentMethodTypes": ["wallet"],
"paymentSetting": {
"allowedChains": [
{ "chainId": 137 },
{ "chainId": 8453 },
{ "chainId": 42161 }
],
"paymentMethodTypes": ["wallet"],
"preferredChainId": 137,
"allowSwap": true
},
"currency": "usdc",
"amountSubtotal": "10000000",
"amountTotal": "10100000",
"status": "complete",
"paymentStatus": "paid",
"paymentLinkId": "769a890b-5664-49f8-8f68-c9b688bcf60f",
"url": "https://buy.copperx.tech/payment/checkout-session/fe6b7b01-1c4b-4b35-a5a5-a23b0a089cc6",
"lineItems": {
"object": "list",
"data": [
{
"description": null,
"quantity": 1,
"price": {
"id": "ebc48921-0171-4f37-9070-2906d0da2f51",
"currency": "usdc",
"productId": "b1d2476f-b5cf-47d7-99ee-3d8123ae9ab5",
"type": "one_time",
"unitAmount": "10000000",
"product": {
"id": "b1d2476f-b5cf-47d7-99ee-3d8123ae9ab5",
"name": "Demo test",
"isActive": true
},
"isActive": true
},
"amountTotal": "10000000",
"currency": "usdc"
}
]
},
"addresses": [/* ... multiple supported crypto assets and addresses ... */],
"paymentIntent": {
"id": "3b7bc615-a04d-49e1-98c4-8612f785484d",
"amount": "10100000",
"amountReceived": "10100000",
"currency": "usdc",
"status": "requires_payment_method",
"paymentMethod": {
"id": "88cbd77a-84f1-422a-8ac6-fa6f498142b1",
"asset": {
"id": "13056880-798b-4bd4-a555-c1c71de017fa",
"name": "USDC.e",
"chainId": 137,
"address": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174",
"currency": "usdc"
},
"type": "wallet",
"accountAddress": "0xd2b59f3a9575a90a44e5627cda4ed98ecb5e5d20",
"options": {
"frontend": {
"transactionHash": "0x54d164f9807060445614ece882603fd4b2a7858ac1394451cf1f07715a183def"
},
"wallet": {
"assetId": "13056880-798b-4bd4-a555-c1c71de017fa",
"transactionHash": "0x54d164f9807060445614ece882603fd4b2a7858ac1394451cf1f07715a183def",
"contractAddress": "0x146db67792092eaa92a51961946b50f89277a975"
}
}
}
},
"amountDetails": {
"amountTotal": "10100000",
"amountSubtotal": "10000000",
"amountFee": "100000",
"currency": "usdc",
"feePercentage": 1
},
"amountNet": "10000000"
}
}
}
๐ก How to Use This Event
When you receive this event:
โ
Verify the signature (for security).
โ
Check the paymentStatus (paid
).
โ
Activate the userโs plan, send a confirmation email, or update their account.
โ๏ธ Best Practices for Webhooks
โ
Always verify the signature to avoid spoofed requests.
โ
Respond quickly to webhook POST requests with a 200
OK to acknowledge receipt.
โ
Retry Behavior
Max Attempts: 10
Initial Delay: 30 seconds
Backoff Strategy: Exponential (delay doubles with each retry)
No Delay Cap: Delay continues to double up to the 10th attempt
Total Retry Window: ~4 hours 16 minutes from initial delivery attempt
๐ Retry Schedule
1st
30
0.5 min
0:00:30
2nd
60
1 min
0:01:30
3rd
120
2 min
0:03:30
4th
240
4 min
0:07:30
5th
480
8 min
0:15:30
6th
960
16 min
0:31:30
7th
1920
32 min
1:03:30
8th
3840
64 min
2:07:30
9th
7680
128 min
4:15:30
10th
15,360
256 min
8:31:30*
Notes:
A maximum of 10 retry attempts will be made.
If all retries fail, the webhook delivery is marked as unsuccessful.
โ Log webhook events for debugging and auditing. โ Use HTTPS for secure communication.
Last updated