It looks like you're using Google Chrome - try our powerful extension! Find out more. Add to Chrome
x
Help Center SettingsWebhooks

Webhooks

ChargeDesk offers webhooks which can be used to receive notifications about events occurring on your account. Each time an event occurs in your account, ChargeDesk will send a notification to any webhooks your setup in your ChargeDesk account. There are many different kinds of events you can receive notifications about.

Setting up Webhooks

Webhooks can be configured by an administrator from Setup > API after logging into your ChargeDesk account. Each webhook you setup can either receive all possible notification events, or a subset of events. The URL for the webhook should be a valid, publicly accessible URL.

You can test your webhooks by using a service such as https://webhook.site/ to generate a temporary testing URL.

Webhook Events

A list of all possible webhook events can be found below;

charge_new (Charge Created)
Sent when a new charge is created.
charge_updated (Charge Updated)
Sent when a charge is updated.
charge_deleted (Charge Deleted)
Sent when a charge is deleted.
charge_request (Charge Requested)
Sent when a payment request is created.
charge_paid (Charge Paid)
Sent when a charge is successfully paid. Does not include payment requests.
charge_request_paid (Charge Request Paid)
Sent when a payment request is successfully paid by a customer.
charge_pending_paid (Charge Pending Paid)
Sent when a previously pending payment is successfully paid.
charge_refunded (Charge Refunded)
Sent when a charge is refunded.
charge_failed (Charge Failed)
Sent when a charge fails, often due to an issue with the customer's card.
charge_disputed (Charge Disputed)
Sent when a charge is disputed, often due to a chargeback by the customer.
charge_request_reminder (Charge Unpaid Payment Request)
Sent when a payment request hasn't been paid for X days.
customer_new (Customer Created)
Sent when a new customer is created.
customer_updated (Customer Updated)
Sent when a customer is updated.
customer_deleted (Customer Deleted)
Sent when a customer is deleted.
customer_first_paid (Customer First Payment)
Sent when a customer makes their first successful payment.
customer_delinquent (Customer Delinquent)
Sent when a customer is marked as delinquent.
subscription_new (Subscription Created)
Sent when a new subscription is created.
subscription_updated (Subscription Updated)
Sent when a subscription is updated.
subscription_upgraded (Subscription Upgraded)
Sent when a subscription is upgraded.
subscription_downgraded (Subscription Downgraded)
Sent when a subscription is downgraded.
subscription_past_due (Subscription Past Due)
Sent when a subscription goes past due.
subscription_canceled (Subscription Canceled)
Sent when a subscription is canceled or unpaid.
subscription_suspended (Subscription Suspended)
Sent when a subscription is suspended or paused.
subscription_reactivated (Subscription Reactivated)
Sent when a subscription is reactivated.
subscription_upcoming_payment (Subscription Upcoming Payment on Active Subscription)
Sent when a charge on an active subscription is due in X days.
subscription_trial_ending (Subscription Subscription Trial Ends Soon)
Sent when a charge on a trial subscription is due in X days.
agent_log_new (Agent Log Created)
Sent when a new agent log is created.

HTTP Status Codes and Retries

To acknowledge receipt of a webhook, your endpoint should return a 2xx HTTP status code (e.g. 200). This will let ChargeDesk know that the webhook has been received and no further delivery attempts will be made for that notification.

Any other response codes including 3xx will indicate to ChargeDesk that the webhook was not successfully received. If your endpoint takes more than 30 seconds to respond, it will also be considered failed. Upon failure, the webhook event will be retried once every hour for up to 3 days until a successful response code is received. If a webhooks fails for a large percentage of requests for more than 1 week, it may be disabled and further events will not be sent. You can also send a 410 response code to indicate you do not want to receive any further requests and ChargeDesk will disable the webhook immediately.

Example Payloads

The following are example webhook payloads for different types of events.

Charge Notification

{
    "event_id": "event-example-AGx2V9Re5XGVVz0XF4",
    "created": 1734792617,
    "class": "charge",
    "event": "charge_paid",
    "data": {
        "charge": {
            "amount": "34.00",
            "amount_refunded": "0.00",
            "currency": "USD",
            "payment_method": "Credit",
            "payment_method_brand": "Visa",
            "gateway_id": "",
            "charge_id": "example-THiqnN7naxZSxoN1iJVBdQFJ",
            "customer_id": "cus-example-zhuOvnzVrv",
            "product_id": "prod-example-W06KeH7JlE",
            "subscription_id": "sub-example-OVEJk56047",
            "transaction_id": "transaction-example-H6u0yjVLoZ",
            "customer_name": "Jane Customer",
            "customer_email": "jane@example.com",
            "customer_username": "janecustomer",
            "customer_country": "US",
            "description": "An example charge",
            "last_4_digits": "1234",
            "occurred": 1734792617,
            "object": "charge",
            "amount_with_commas": "34.00",
            "amount_refunded_formatted": "$0.00 USD",
            "amount_symbol": "$",
            "amount_formatted": "$34.00 USD",
            "is_paid": true,
            "status": "paid",
            "status_text": "paid",
            "support_email": "company-example+example-THiqnN7naxZSxoN1iJVBdQFJ@chargedesk.com",
            "support_url": "https://chargedesk.com/company-example/example-THiqnN7naxZSxoN1iJVBdQFJ",
            "manage_url": "https://chargedesk.com/manage/company-example/charges/example-THiqnN7naxZSxoN1iJVBdQFJ",
            "invoice_url": "https://chargedesk.com/company-example/example-THiqnN7naxZSxoN1iJVBdQFJ/invoice",
            "invoice_download_url": "https://chargedesk.com/company-example/example-THiqnN7naxZSxoN1iJVBdQFJ/invoice/download",
            "customer_phone": null,
            "methods_supported": [
                "edit",
                "remind",
                "email"
            ],
            "methods_active": [
                "email"
            ],
            "occurred_relative": "moments ago",
            "occurred_formatted": "moments ago",
            "payment_method_describe": "Visa credit card",
            "added_tax": "0.00",
            "invoice_company": null,
            "company": "company-example",
            "metadata": {
                "example_key": "Example charge metadata"
            },
            "logs": [],
            "gateway_url": "",
            "sent_invoice": "",
            "sent_invoice_reminder": "",
            "refunded_at_formatted": "",
            "product_desc": "",
            "name_email": "receipt",
            "email_last_sent": 0,
            "name_send_email": "Send Receipt"
        }
    }
}

Customer Notification

{
    "event_id": "event-example-8h1JbsmOB97hBlaky2",
    "created": 1734792617,
    "class": "customer",
    "event": "customer_first_paid",
    "data": {
        "customer": {
            "customer_id": "cus-example-xC8eko8Uk9",
            "gateway_id": "",
            "name": "Jane Customer",
            "email": "jane@example.com",
            "username": "janecustomer",
            "description": "An example customer",
            "phone": "+1 555-555-5555",
            "company": "company-example",
            "website": "https://example.com",
            "country": "US",
            "delinquent": 0,
            "edited": 0,
            "tax_number": "123456789",
            "tax_number_abr": "VAT",
            "billing_address": "123 Example Street\nExample City\nExample State, United States, 90000",
            "shipping_address": "",
            "invoice_details": "",
            "object": "customer",
            "charges": 0,
            "first_seen": 1734792617,
            "subscriptions": [],
            "readable_country": "United States",
            "methods_supported": [
                "invoice",
                "edit"
            ],
            "methods_active": [
                "invoice",
                "edit"
            ],
            "customer_company": "Example Company LTD",
            "metadata": {
                "example_key": "Example customer metadata"
            },
            "logs": [],
            "items": [],
            "first_name": "Jane",
            "manage_url": "https://chargedesk.com/manage/company-example/customers/cus-example-xC8eko8Uk9",
            "gateway_url": ""
        }
    }
}

Subscription Notification

{
    "event_id": "event-example-8yjRRlkp58TNb0qhHp",
    "created": 1734792617,
    "class": "subscription",
    "event": "subscription_upgraded",
    "data": {
        "subscription": {
            "subscription_id": "sub-example-JN17mavBUO",
            "customer_id": "cus-example-7DTZHHNckk",
            "product_id": "prod-example-pYGjmFB1nJ",
            "amount": "34.00",
            "currency": "USD",
            "gateway_id": "",
            "interval": "month",
            "interval_count": 1,
            "charges": 1,
            "quantity": 2,
            "current_period_start": 1734792617,
            "current_period_end": 1737422360,
            "trial_start": 0,
            "trial_end": 1736002217,
            "ended_at": 0,
            "canceled_at": 0,
            "has_items": 0,
            "billing_cycles_total": 0,
            "billing_cycles_current": 1,
            "trial_period_days": 14,
            "setup_amount": 10,
            "object": "subscription",
            "amount_formatted": "2x $34.00 USD",
            "amount_symbol": "$",
            "status": "active",
            "status_text": "Active",
            "first_seen": 1734792617,
            "methods_supported": [
                "edit"
            ],
            "methods_active": [
                "edit"
            ],
            "readable_interval": "Monthly",
            "product_desc": "",
            "company": "company-example",
            "logs": [],
            "items": [],
            "metadata": {
                "example_key": "Example subscription metadata"
            },
            "manage_url": "https://chargedesk.com/manage/company-example/subscriptions/sub-example-JN17mavBUO",
            "gateway_url": ""
        }
    }
}

Agent Log Notification

{
    "event_id": "event-example-qai4TPCDIybP68MvWK",
    "created": 1734792617,
    "class": "agent_log",
    "event": "agent_log_new",
    "data": {
        "agent_log": {
            "source": "web",
            "object_type": "charge",
            "object_id": "example-IhgssHKA3MZdvbRAiZI0Q4i7",
            "action_type": "refund",
            "action_reason": "Example refund",
            "event": "charge-refund",
            "ip": "1.2.3.4",
            "description": "Charge Refunded",
            "sub_description": "",
            "occurred": 1734792617,
            "context": null,
            "params": null,
            "company": "company-example",
            "action_params": false
        },
        "charge": {
            "amount": "34.00",
            "amount_refunded": "21.00",
            "currency": "USD",
            "payment_method": "Credit",
            "payment_method_brand": "Visa",
            "gateway_id": "",
            "charge_id": "example-IhgssHKA3MZdvbRAiZI0Q4i7",
            "customer_id": "cus-example-4RNgb3Ft0h",
            "product_id": "prod-example-8jzNzajLY8",
            "subscription_id": "sub-example-IrZOVquSMY",
            "transaction_id": "transaction-example-e3JW3vEbDA",
            "customer_name": "Jane Customer",
            "customer_email": "jane@example.com",
            "customer_username": "janecustomer",
            "customer_country": "US",
            "description": "An example charge",
            "last_4_digits": "1234",
            "occurred": 1734792617,
            "object": "charge",
            "amount_with_commas": "34.00",
            "amount_refunded_formatted": "$21.00 USD",
            "amount_symbol": "$",
            "amount_formatted": "$34.00 USD",
            "is_paid": true,
            "status": "partially refunded",
            "status_text": "partially refunded",
            "support_email": "company-example+example-IhgssHKA3MZdvbRAiZI0Q4i7@chargedesk.com",
            "support_url": "https://chargedesk.com/company-example/example-IhgssHKA3MZdvbRAiZI0Q4i7",
            "manage_url": "https://chargedesk.com/manage/company-example/charges/example-IhgssHKA3MZdvbRAiZI0Q4i7",
            "invoice_url": "https://chargedesk.com/company-example/example-IhgssHKA3MZdvbRAiZI0Q4i7/invoice",
            "invoice_download_url": "https://chargedesk.com/company-example/example-IhgssHKA3MZdvbRAiZI0Q4i7/invoice/download",
            "customer_phone": null,
            "methods_supported": [
                "edit",
                "remind",
                "email"
            ],
            "methods_active": [
                "email"
            ],
            "occurred_relative": "moments ago",
            "occurred_formatted": "moments ago",
            "payment_method_describe": "Visa credit card",
            "added_tax": "0.00",
            "invoice_company": null,
            "company": "company-example",
            "metadata": {
                "example_key": "Example charge metadata"
            },
            "logs": [],
            "gateway_url": "",
            "sent_invoice": "",
            "sent_invoice_reminder": "",
            "refunded_at_formatted": "",
            "product_desc": "",
            "name_email": "refund notification",
            "email_last_sent": 0,
            "name_send_email": "Send Refund Notification"
        }
    }
}

Additional Data

The charge_request_paid and charge_request events also include the following additional fields;

{
    // ...
    "data": {
        "charge": {
            // ...
            "source_ticket": "1234", // The ID of the helpdesk ticket where the request was created (where available)
            "source_customer": "5678", // The ID of the helpdesk customer where the request was created (where available)
            "source_url": "https://helpdesk.com/ticket/1234", // The URL of the page where the request was created
        }
    }
}
These fields are particularly useful along with our Zapier integration to update a ticket in your helpdesk once a request has been paid.

Verifying a Webhook

ChargeDesk includes information in the header of webhook requests which you should use to verify that the notification you receive has actually come from ChargeDesk.

There are 2 headers which ChargeDesk includes in webhook requests which are needed for verification; ChargeDesk-Signature-Time and ChargeDesk-Signature

The ChargeDesk-Signature-Time header allows you to verify that the webhook was recently sent and allows you to prevent replay attacks. This is timestamp showing seconds since epoch (unix time). We recommend verifying this time is less than 5 minutes old.

The ChargeDesk-Signature signs the timestamp along with the entire request using a unique secret key for your webhook. You can find your secret webhook key by clicking the "Edit webhook" link under Setup > API. This key is unique for each webhook you add.

To verify the signature, you should concatenate;

Then create a HMAC using your secret webhook key and the sha256 algorithm, then ensure it matches the ChargeDesk-Signature header.

The following is example PHP code which shows verification process.

$secret_key = "unique_secret_key_for_your_webhook";

$body = @file_get_contents('php://input');
$timestamp = intval($_SERVER['HTTP_CHARGEDESK_SIGNATURE_TIME']);
$signature = $_SERVER['HTTP_CHARGEDESK_SIGNATURE'];

// Verify request format
if(!$body || !$timestamp || !$signature) {
	header("HTTP/1.1 406 Not Acceptable");
	die("Invalid request");
}

// Verify that the timestamp is recent enough
if (abs(time() - $timestamp) > 300) {
	header("HTTP/1.1 406 Not Acceptable");
	die("Invalid timestamp");
}

// Verify the signature is valid
$signed_payload = $timestamp.".".$body;
if(hash_hmac('sha256', $signed_payload, $secret_key) !== $signature) {
	header("HTTP/1.1 406 Not Acceptable");
	die("Invalid signature");
}

// Parse the JSON body
$payload = json_decode((string)$body, true);

// You can now safely use the payload
print "Received event type ".$payload['event'];