Challanwala logo
Challanwala
Challanwala API Docs

Webhooks

Configure signed webhook delivery for challan search and payment-link events.

What webhooks are for

Webhooks let your integration receive lifecycle updates without polling every workflow step. They are particularly useful for:

  • challan search completion or failure monitoring
  • payment-link creation notifications
  • payment success, failure, and expiry handling

Configure your webhook

From the organization API settings area, your admin can:

  1. Save a webhook URL.
  2. Activate or deactivate delivery.
  3. Rotate the webhook secret.
  4. Send a test event.

Store the webhook secret securely

When the webhook secret is rotated, update your receiver before relying on new deliveries. Use the latest secret to verify every signed payload.

Delivery headers

Webhook headers
FieldTypeRequiredDescription
content-typestringRequiredAlways sent as application/json.
x-cms-eventstringRequiredEvent type, such as payment_link.paid or challan_search.completed.
x-cms-timestampstringRequiredUnix timestamp used in signature verification.
x-cms-signaturestringRequiredHMAC SHA-256 signature in the format sha256=HEX_DIGEST.

Payload envelope

Every webhook body uses the same top-level shape:

Webhook envelope
{"id": "a8e97bbf-0ba5-4ea7-b7cb-11b29efdf641","type": "payment_link.paid","createdAt": "2026-05-13T11:42:08.000Z","data": {  "...": "event-specific fields"}}

Verify the signature

Use the raw request body exactly as received and compute the signature over:

${x-cms-timestamp}.${rawRequestBody}

Example in Node.js:

import crypto from 'node:crypto';

function verifyWebhook({
  timestamp,
  rawBody,
  signatureHeader,
  secret,
}: {
  timestamp: string;
  rawBody: string;
  signatureHeader: string;
  secret: string;
}) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex');

  const received = signatureHeader.replace(/^sha256=/, '');

  return crypto.timingSafeEqual(
    Buffer.from(expected, 'hex'),
    Buffer.from(received, 'hex'),
  );
}

Supported event types

StatusMeaningNotes
webhook.testTest event queued from the CMS settings screen.Use this to verify connectivity and signature handling.
challan_search.completedA challan search completed successfully.Includes rcNumber, challanCount, and newChallansCount.
challan_search.failedA challan search failed.Includes rcNumber, statusCode, and errorMessage.
payment_link.createdA payment link was created.Includes paymentLinkId, vehicleNumber, amount summary, and expiresAt.
payment_link.paidA payment link was paid successfully.Includes paymentLinkId, transactionId, paymentMode, and amount.
payment_link.failedA payment attempt failed.Includes paymentLinkId, orderId, and errorMessage.
payment_link.expiredA payment link expired before payment.Includes paymentLinkId and expiredAt metadata.

Example event payloads

webhook.test
{"id": "8803f57d-6814-41e5-a3da-97f349acf698","type": "webhook.test","createdAt": "2026-05-13T09:02:21.000Z","data": {  "orgId": "bf4cc07b-d395-456a-8aac-e419d9ef10ff",  "sentAt": "2026-05-13T09:02:21.000Z"}}
challan_search.completed
{"id": "418b94b6-74e8-4d82-a474-773e3aeae0c6","type": "challan_search.completed","createdAt": "2026-05-13T09:10:11.000Z","data": {  "rcNumber": "DL01AB1234",  "apiKeyId": "4e4984c0-16c2-4b33-b831-fcbf5485f95d",  "challanCount": 2,  "newChallansCount": 2}}
payment_link.created
{"id": "e398c607-d52d-4828-9755-9351fef99871","type": "payment_link.created","createdAt": "2026-05-13T10:20:00.000Z","data": {  "paymentLinkId": "17de2557-58d6-4f8d-aa2b-fb60074c6a6d",  "vehicleNumber": "DL01AB1234",  "status": "ACTIVE",  "challanCount": 2,  "amount": {    "baseAmount": 1500,    "legalFee": 100,    "gst": 18,    "convenienceFee": 0,    "totalAmount": 1618  },  "expiresAt": "2026-05-15T14:20:00.000Z"}}
payment_link.paid
{"id": "b58bc6f3-8384-4db9-aa7b-40c418ccb4b1","type": "payment_link.paid","createdAt": "2026-05-13T11:42:08.000Z","data": {  "paymentLinkId": "17de2557-58d6-4f8d-aa2b-fb60074c6a6d",  "status": "PAID",  "orderId": "ORD-20260513-0011",  "transactionId": "TXN-845012193",  "paymentMode": "UPI",  "amount": 1618}}

Delivery expectations

  • Treat any non-2xx response as a failed delivery attempt.
  • Validate the signature before trusting the payload.
  • Store webhook event IDs if you want an idempotency layer in your own system.

On this page