Jetron TicketFluid

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.

On this page