---
title: Events Reference
description: All webhook event types and their payloads
---

Complete reference of all webhook events and their payloads.

## Event Types

### Transaction Events

| Event                    | Description                                  |
| ------------------------ | -------------------------------------------- |
| `transaction.pending`    | Purchase initiated, processing with provider |
| `transaction.successful` | Purchase completed successfully              |
| `transaction.failed`     | Purchase failed                              |
| `transaction.reversed`   | Payment was reversed/refunded                |

### Subscribe to All

Use `*` to subscribe to all current and future event types.

## Event Envelope

Every webhook body shares the same envelope:

| Field         | Description                                              |
| ------------- | -------------------------------------------------------- |
| `id`          | Unique event id (`evt_...`), also in `X-RizPay-Event-ID` |
| `type`        | The event type, e.g. `transaction.successful`            |
| `api_version` | Webhook payload version (currently `1.0.0`)              |
| `created_at`  | ISO 8601 timestamp when the event was created            |
| `data.object` | The resource for this event (see payloads below)         |

The transaction object is a flat object (its fields are not nested under an `attributes` key). It carries two reference fields: `reference` is the value you supplied at purchase time (your external reference), and `rizpay_reference` is the RizPay-generated reference. Use `id` (or `X-RizPay-Event-ID`) for idempotency.

## Transaction Event Payloads

### transaction.pending

Sent when a purchase is initiated:

```json
{
  "id": "evt_abc123def456",
  "type": "transaction.pending",
  "api_version": "1.0.0",
  "created_at": "2024-01-15T10:30:00Z",
  "data": {
    "object": {
      "id": "txn_1042",
      "reference": "1736234400A1B2C3",
      "rizpay_reference": "9a8edccb078b0f91a713",
      "amount": "100.00",
      "currency": "NGN",
      "status": "pending",
      "category": "purchase",
      "description": "Purchase of MTN Airtime",
      "product_type": "airtime",
      "phone_number": "08012345678",
      "meter_number": null,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z"
    }
  }
}
```

### transaction.successful

Sent when a purchase completes successfully:

```json
{
  "id": "evt_def456ghi789",
  "type": "transaction.successful",
  "api_version": "1.0.0",
  "created_at": "2024-01-15T10:30:05Z",
  "data": {
    "object": {
      "id": "txn_1042",
      "reference": "1736234400A1B2C3",
      "rizpay_reference": "9a8edccb078b0f91a713",
      "amount": "100.00",
      "currency": "NGN",
      "status": "successful",
      "category": "purchase",
      "description": "Purchase of MTN Airtime",
      "product_type": "airtime",
      "phone_number": "08012345678",
      "meter_number": null,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:05Z"
    }
  }
}
```

For electricity purchases, the object also includes the vending `token` (present once the token is available):

```json
{
  "data": {
    "object": {
      "id": "txn_1043",
      "reference": "1736234400D4E5F6",
      "rizpay_reference": "c74afbae9481256ab5b7",
      "amount": "5000.00",
      "currency": "NGN",
      "status": "successful",
      "category": "purchase",
      "description": "Purchase of Ikeja Electric (prepaid)",
      "product_type": "electricity",
      "phone_number": "08012345678",
      "meter_number": "12345678901",
      "token": "1234-5678-9012-3456-7890",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:05Z"
    }
  }
}
```

### transaction.failed

Sent when a purchase fails:

A failed purchase carries the same transaction object with `status: "failed"`. The amount is refunded to your balance:

```json
{
  "id": "evt_ghi789jkl012",
  "type": "transaction.failed",
  "api_version": "1.0.0",
  "created_at": "2024-01-15T10:30:10Z",
  "data": {
    "object": {
      "id": "txn_1042",
      "reference": "1736234400A1B2C3",
      "rizpay_reference": "9a8edccb078b0f91a713",
      "amount": "100.00",
      "currency": "NGN",
      "status": "failed",
      "category": "purchase",
      "description": "Purchase of MTN Airtime",
      "product_type": "airtime",
      "phone_number": "08012345678",
      "meter_number": null,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:10Z"
    }
  }
}
```

### transaction.reversed

Sent when a previously successful transaction is reversed. The object is the same transaction with `status: "reversed"`:

```json
{
  "id": "evt_jkl012mno345",
  "type": "transaction.reversed",
  "api_version": "1.0.0",
  "created_at": "2024-01-15T12:00:00Z",
  "data": {
    "object": {
      "id": "txn_1042",
      "reference": "1736234400A1B2C3",
      "rizpay_reference": "9a8edccb078b0f91a713",
      "amount": "100.00",
      "currency": "NGN",
      "status": "reversed",
      "category": "purchase",
      "description": "Purchase of MTN Airtime",
      "product_type": "airtime",
      "phone_number": "08012345678",
      "meter_number": null,
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T12:00:00Z"
    }
  }
}
```

## Handling Events

```javascript
app.post("/webhooks/rizpay", express.json(), async (req, res) => {
  const event = req.body;

  // Use event.id for idempotency
  if (await isEventProcessed(event.id)) {
    return res.status(200).send("Already processed");
  }

  try {
    switch (event.type) {
      case "transaction.successful":
        await fulfillOrder(event.data.object);
        break;

      case "transaction.failed":
        await notifyCustomerOfFailure(event.data.object);
        break;

      case "transaction.reversed":
        await handleReversal(event.data.object);
        break;
    }

    await markEventProcessed(event.id);
    res.status(200).send("OK");
  } catch (error) {
    console.error("Webhook processing error:", error);
    // Return 500 to trigger retry
    res.status(500).send("Processing failed");
  }
});
```

## Event Filtering

When creating a webhook, you can subscribe to specific events:

- Single event: `transaction.successful`
- Multiple events: `transaction.successful`, `transaction.failed`
- All events: `*`

Use specific subscriptions to reduce noise and processing overhead.

## Next Steps

- [Webhook Security](/docs/webhooks/security) - Verify webhook signatures
- [Webhooks Overview](/docs/webhooks/overview) - Setup and configuration