Webhooks
Webhooks allow you to build or set up integrations, such as Make or Pabbly workflows or Slack notifications, when certain events occur in your CheckoutJoy account.
When one of those events is triggered, we'll send a HTTP POST payload to the webhook's configured URL.
Creating a webhook
Webhooks are configured in Settings > Webhooks (opens in a new tab) in your CheckoutJoy Dashboard.
Webhook Security
To verify that a webhook was sent by CheckoutJoy, you can check the request signature that is sent with each webhook.
The signature is sent in a HTTP header named x-cj-signature
, and it's an HMAC hash of the request payload hashed using your secret key.
To verify the signature, you need to:
- Get the
x-cj-signature
header from the webhook request - Hash the request payload using
sha256
and your secret key - Compare the hash with the signature from
x-cj-signature
Here is an example of how to verify the signature in your app:
Verifying a request
const signature = req.headers['x-cj-signature'] const hash = require("crypto") .createHmac("sha256", SECRET_KEY) .update(JSON.stringify(req.body)) .digest("hex") if (hash === signature) { // Request is verified } else { // Request could not be verified }
Events
Purchase Completed
The purchase.completed
event is triggered when an order is completed.
The order is completed and product access can be granted to the customer.
{
"event": "purchase.completed",
"data": {
"id": "1685958796591237c8f84-7c5a-405e-8961-02a691deffc7",
"affiliate_code": null,
"status": "COMPLETED",
"country_code": "ZA",
"completed_at": "2023-06-05T09:53:34.991Z",
"customer": {
"email": "mollie@checkoutjoy.com",
"first_name": "Koos",
"last_name": "Mollie",
"billing_address": {
"first_name": "Koos",
"last_name": "Mollie"
}
},
"products": [
{
"id": "27bPgEHKrwtHlaP2JsyNt9rb6z9",
"name": "My First Digital Product",
"total": 21.8,
"sub_total": 20,
"tax_total": 1.8,
"discount_total": 0,
"charge_type": "immediate",
"price": {
"id": "price_id",
"currency": "USD",
"amount": 20,
"billing_type": "once",
"recurring": {
"type": "once",
"interval": null,
"period": "month",
"cycles": null,
"trial_period_days": null
}
},
"tax": {
"name": "BTW",
"rate": 9,
"region": null,
"country": "NL",
"tax_class": "reduced",
"behaviour": "exclusive"
}
}
],
"ref": "000186",
"payment": {
"id": "1aceda64-5a4b-4741-a2b0-4c933a600b09",
"status": "COMPLETED",
"currency": "USD",
"amount": 21.8,
"amount_fee": 0,
"total_net": 21.8,
"processor_id": "123456789",
"created_at": "2023-06-05T09:53:29.086Z"
},
"processor_id": "Stripe",
"currency": "USD",
"total": 21.8,
"discount_total": 0,
"tax_total": 1.8
}
}
Recurring Payment Received
This event is triggered when a recurring subscription payment is processed and completed.
{
"event": "subscription.payment_received",
"data": {
"purchase_id": "1685958796591237c8f84-7c5a-405e-8961-02a691deffc7",
"id": "1aceda64-5a4b-4741-a2b0-4c933a600b09",
"status": "COMPLETED",
"currency": "USD",
"amount": 21.8,
"amount_fee": 0,
"amount_net": 21.8,
"created_at": "2023-06-05T09:53:29.086Z",
"processor_id": "pi_3NFa1IIocmTNbZyh2aEImwUE",
"processor": "Stripe"
}
}
Subscription Cancelled
The subscription.cancelled
event is triggered when a payment subscription failed or is cancelled by the merchant or the customer.
A cancelled subscription is final and can’t be fixed or restarted.
All product access must be revoked when this event is received.
{
"event": "purchase.completed",
"data": {
"id": "1685958796591237c8f84-7c5a-405e-8961-02a691deffc7",
"affiliate_code": null,
"status": "CANCELLED",
"country_code": "ZA",
"completed_at": "2023-06-05T09:53:34.991Z",
"customer": {
"email": "mollie@checkoutjoy.com",
"first_name": "Koos",
"last_name": "Koekies",
"billing_address": {
"first_name": "Koos",
"last_name": "Mollie"
}
},
"products": [
{
"id": "27bPgEHKrwtHlaP2JsyNt9rb6z9",
"name": "My First Digital Product",
"total": 21.8,
"sub_total": 20,
"tax_total": 1.8,
"discount_total": 0,
"charge_type": "immediate",
"price": {
"id": "price_id",
"currency": "USD",
"amount": 20,
"billing_type": "once",
"recurring": {
"type": "once",
"interval": null,
"period": "month",
"cycles": null,
"trial_period_days": null
}
},
"tax": {
"name": "BTW",
"rate": 9,
"region": null,
"country": "NL",
"tax_class": "reduced",
"behaviour": "exclusive"
}
}
],
"ref": "000186",
"payment": {
"id": "1aceda64-5a4b-4741-a2b0-4c933a600b09",
"status": "COMPLETED",
"currency": "USD",
"amount": 21.8,
"amount_fee": 0,
"total_net": 21.8,
"processor_id": "123456789",
"created_at": "2023-06-05T09:53:29.086Z"
},
"processor_id": "Stripe",
"currency": "USD",
"total": 21.8,
"discount_total": 0,
"tax_total": 1.8
}
}