Event types
The payloads Jetron sends, and the fields on each one.
Every delivery shares the same envelope. Discriminate on eventType:
interface JetronWebhookEvent {
eventType: 'TICKET_PURCHASED' | 'WEBHOOK_TEST'
data: Record<string, unknown>
}TICKET_PURCHASED
Sent when an attendee completes a purchase.
{
"eventType": "TICKET_PURCHASED",
"data": {
"eventId": "3f8a1c62-9d47-4b1e-9c2a-7e5f0b6d8a11",
"reference": "jt_txn_01H9Z4K8",
"amount": 500000,
"formattedAmount": "NGN 5,000.00",
"paidAt": "2026-08-05T12:00:00Z",
"sentAt": "2026-08-05T12:00:01Z",
"orders": [
{
"sku": "8c1d5e90-2f3b-4a7c-8e6d-1b9f4c2a7d35",
"amount": 500000,
"formattedAmount": "NGN 5,000.00",
"quantity": 1,
"customer": {
"email": "kendall@example.com",
"firstName": "Kendall",
"lastName": "Roy",
"phone": "+2348012345678"
}
}
],
"metadata": { "seatPreference": "front" }
}
}data
Prop
Type
orders[]
Prop
Type
There is one entry per recipient, so a cart that assigns tickets to several
email addresses arrives as several orders entries with quantity: 1 rather
than one entry with a higher quantity.
Free orders have no payment timestamps
A free order is never charged, so paidAt and sentAt come back as the zero
timestamp "0001-01-01T00:00:00Z". Check amount before treating those as real
dates.
WEBHOOK_TEST
Sent only when you press Test in the dashboard. It confirms that your endpoint is reachable and that your signature verification works, before real money is involved.
{
"eventType": "WEBHOOK_TEST",
"data": {
"message": "This is a test webhook from Jetron.",
"reference": "test_ref_1754395200",
"sentAt": "2026-08-05T12:00:00Z"
}
}The test payload is a different shape
WEBHOOK_TEST carries only message, reference, and sentAt. It does not
include orders, amount, or metadata. If your handler is typed against
TICKET_PURCHASED and reads data.orders without checking eventType first,
a test delivery will crash it.
Test deliveries are never retried, so a failing test shows up as a single attempt.
Metadata
Anything you pass as metadata when creating an order is
returned here untouched, which is the simplest way to correlate a purchase with
something in your own system:
await client.createOrder(slug, {
// ...
metadata: { cartId: 'abc123', source: 'newsletter' },
}, { deviceId })"metadata": { "cartId": "abc123", "source": "newsletter" }It must be a JSON object rather than a scalar or array, and is capped at 4096 bytes.

