> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rmz.gg/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook Events

> All webhook event types available in RMZ and what triggers them.

RMZ supports webhook event types for orders and subscriptions. Each webhook you create listens for a single event type.

## Available Events

| Event                         | Trigger                                                                                   |
| ----------------------------- | ----------------------------------------------------------------------------------------- |
| `order.created`               | A new order is placed in your store (after successful payment or for free orders)         |
| `order.status.changed`        | An order's status is updated (e.g., from pending to completed, or completed to cancelled) |
| `subscription.created`        | A new subscription is created for a customer                                              |
| `subscription.activated`      | A subscription transitions from trialing to active                                        |
| `subscription.renewed`        | A subscription is successfully renewed with payment                                       |
| `subscription.renewal_failed` | An auto-renewal payment attempt failed                                                    |
| `subscription.past_due`       | A subscription enters the past due state after a failed payment                           |
| `subscription.expired`        | A subscription has expired (terminal state)                                               |
| `subscription.canceled`       | A subscription has been canceled                                                          |
| `subscription.paused`         | A subscription has been paused (auto-renewal stops, access retained until period end)     |
| `subscription.unpaused`       | A paused subscription has been resumed (period extended by remaining days)                |
| `subscription.resumed`        | A canceled subscription has been resumed before the period ended                          |
| `subscription.updated`        | A subscription has been updated (variant change, extension, etc.)                         |

<Note>
  Every subscription webhook payload includes an `external_customer_id` field at `data.subscription.external_customer_id`. This is the identifier the merchant supplied when creating the checkout session — use it to correlate incoming webhooks back to your own user records. The value is `null` if it was not set at checkout, but the key is always present.
</Note>

***

## order.created

Fired when a customer successfully places an order. This includes orders from all sources: the storefront, embed checkout, and the Storefront API.

**Common use cases:**

* Send a custom notification (Slack, Telegram, email)
* Sync the order to an external system (CRM, ERP, accounting)
* Trigger a fulfillment workflow
* Update inventory in an external system
* Log the sale for analytics

**Payload:** Contains the full order object including customer, items, transaction details, and status history. See [Payload Format](/webhooks/payload-format) for the complete structure.

***

## order.status.changed

Fired when an order's status changes after the initial creation. This event is not triggered for the first status (order creation) — only for subsequent status updates.

**Common use cases:**

* Notify customers of shipping or delivery updates via your own channels
* Update external dashboards or reporting tools
* Trigger post-purchase workflows (e.g., send a review request after completion)
* Sync order status with third-party fulfillment systems

**Payload:** Contains the same full order object as `order.created`, reflecting the current state of the order after the status change. The `statuses` array includes the complete status history.

### Order Status Values

The `status` field in the payload corresponds to these values:

| Status | Meaning             |
| ------ | ------------------- |
| 1      | Waiting for Payment |
| 2      | Under Review        |
| 3      | Processing          |
| 4      | Completed           |
| 5      | Cancelled           |
| 6      | Refunded            |

<Tip>
  Use the `statuses` array in the payload to see the full history of status changes for an order, including timestamps for each transition.
</Tip>

***

## subscription.created

Fired when a new subscription is created for a customer, either through a storefront purchase or via the Merchant API checkout session.

**Common use cases:**

* Provision access to a service or SaaS product
* Send a welcome email to the new subscriber
* Sync the subscription to your billing system
* Log the event for analytics

**Payload example:**

```json theme={null}
{
  "event": "subscription.created",
  "event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "subscription": {
      "id": 501,
      "status": "active",
      "external_customer_id": "usr_abc123",
      "product_id": 102,
      "product_name": "Pro Plan",
      "variant": {
        "id": 15,
        "price": 49,
        "duration": "monthly"
      },
      "duration": "monthly",
      "current_period_start": "2025-06-01T00:00:00.000000Z",
      "current_period_end": "2025-07-01T00:00:00.000000Z",
      "auto_renew": true,
      "metadata": {
        "external_user_id": "usr_abc123"
      },
      "customer": {
        "id": 123,
        "email": "ahmed@example.com",
        "name": "Ahmed Ali"
      }
    }
  }
}
```

***

## subscription.activated

Fired when a subscription transitions from `trialing` to `active`, typically after a successful first payment at the end of a trial period.

**Common use cases:**

* Upgrade the customer from trial to full access
* Trigger a billing confirmation notification
* Update your CRM with the activation date

**Payload example:**

```json theme={null}
{
  "event": "subscription.activated",
  "event_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "data": {
    "subscription": {
      "id": 501,
      "status": "active",
      "external_customer_id": "usr_abc123",
      "product_id": 102,
      "product_name": "Pro Plan",
      "variant": {
        "id": 15,
        "price": 49,
        "duration": "monthly"
      },
      "duration": "monthly",
      "current_period_start": "2025-06-15T00:00:00.000000Z",
      "current_period_end": "2025-07-15T00:00:00.000000Z",
      "auto_renew": true,
      "metadata": {
        "external_user_id": "usr_abc123"
      },
      "customer": {
        "id": 123,
        "email": "ahmed@example.com",
        "name": "Ahmed Ali"
      }
    }
  }
}
```

***

## subscription.renewed

Fired when a subscription is successfully renewed with a payment charge.

**Common use cases:**

* Send a payment receipt to the customer
* Log the renewal for accounting
* Extend access in your external system

**Payload example:**

```json theme={null}
{
  "event": "subscription.renewed",
  "event_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
  "data": {
    "subscription": {
      "id": 501,
      "status": "active",
      "external_customer_id": "usr_abc123",
      "product_id": 102,
      "product_name": "Pro Plan",
      "variant": {
        "id": 15,
        "price": 49,
        "duration": "monthly"
      },
      "duration": "monthly",
      "current_period_start": "2025-07-01T00:00:00.000000Z",
      "current_period_end": "2025-08-01T00:00:00.000000Z",
      "auto_renew": true,
      "metadata": {
        "external_user_id": "usr_abc123"
      },
      "customer": {
        "id": 123,
        "email": "ahmed@example.com",
        "name": "Ahmed Ali"
      }
    }
  }
}
```

***

## subscription.renewal\_failed

Fired when an auto-renewal payment attempt fails. The subscription may be retried automatically.

**Common use cases:**

* Notify the customer to update their payment method
* Send a dunning email sequence
* Log the failure for monitoring

**Payload example:**

```json theme={null}
{
  "event": "subscription.renewal_failed",
  "event_id": "d4e5f6a7-b8c9-0123-defa-234567890123",
  "data": {
    "subscription": {
      "id": 501,
      "status": "past_due",
      "external_customer_id": "usr_abc123",
      "product_id": 102,
      "product_name": "Pro Plan",
      "variant": {
        "id": 15,
        "price": 49,
        "duration": "monthly"
      },
      "duration": "monthly",
      "current_period_start": "2025-06-01T00:00:00.000000Z",
      "current_period_end": "2025-07-01T00:00:00.000000Z",
      "auto_renew": true,
      "metadata": {
        "external_user_id": "usr_abc123"
      },
      "customer": {
        "id": 123,
        "email": "ahmed@example.com",
        "name": "Ahmed Ali"
      }
    }
  }
}
```

***

## subscription.past\_due

Fired when a subscription enters the `past_due` state after the first failed payment attempt.

**Common use cases:**

* Trigger a dunning workflow
* Display a warning banner in your application
* Downgrade the customer to a limited access tier

**Payload example:**

```json theme={null}
{
  "event": "subscription.past_due",
  "event_id": "e5f6a7b8-c9d0-1234-efab-345678901234",
  "data": {
    "subscription": {
      "id": 501,
      "status": "past_due",
      "external_customer_id": "usr_abc123",
      "product_id": 102,
      "product_name": "Pro Plan",
      "variant": {
        "id": 15,
        "price": 49,
        "duration": "monthly"
      },
      "duration": "monthly",
      "current_period_start": "2025-06-01T00:00:00.000000Z",
      "current_period_end": "2025-07-01T00:00:00.000000Z",
      "auto_renew": true,
      "metadata": {
        "external_user_id": "usr_abc123"
      },
      "customer": {
        "id": 123,
        "email": "ahmed@example.com",
        "name": "Ahmed Ali"
      }
    }
  }
}
```

***

## subscription.expired

Fired when a subscription reaches its terminal expired state, either after all retry attempts are exhausted or when a non-renewing subscription period ends.

**Common use cases:**

* Revoke access to your service
* Send a win-back email
* Archive the subscription in your system

**Payload example:**

```json theme={null}
{
  "event": "subscription.expired",
  "event_id": "f6a7b8c9-d0e1-2345-fabc-456789012345",
  "data": {
    "subscription": {
      "id": 501,
      "status": "expired",
      "external_customer_id": "usr_abc123",
      "product_id": 102,
      "product_name": "Pro Plan",
      "variant": {
        "id": 15,
        "price": 49,
        "duration": "monthly"
      },
      "duration": "monthly",
      "current_period_start": "2025-06-01T00:00:00.000000Z",
      "current_period_end": "2025-07-01T00:00:00.000000Z",
      "auto_renew": false,
      "metadata": {
        "external_user_id": "usr_abc123"
      },
      "customer": {
        "id": 123,
        "email": "ahmed@example.com",
        "name": "Ahmed Ali"
      }
    }
  }
}
```

***

## subscription.canceled

Fired when a subscription is canceled, either immediately or scheduled for end of period.

**Common use cases:**

* Log the cancellation reason
* Trigger a retention offer
* Schedule access revocation for end-of-period cancellations

**Payload example:**

```json theme={null}
{
  "event": "subscription.canceled",
  "event_id": "a7b8c9d0-e1f2-3456-abcd-567890123456",
  "data": {
    "subscription": {
      "id": 501,
      "status": "active",
      "external_customer_id": "usr_abc123",
      "product_id": 102,
      "product_name": "Pro Plan",
      "variant": {
        "id": 15,
        "price": 49,
        "duration": "monthly"
      },
      "duration": "monthly",
      "current_period_start": "2025-06-01T00:00:00.000000Z",
      "current_period_end": "2025-07-01T00:00:00.000000Z",
      "auto_renew": false,
      "metadata": {
        "external_user_id": "usr_abc123"
      },
      "customer": {
        "id": 123,
        "email": "ahmed@example.com",
        "name": "Ahmed Ali"
      }
    }
  }
}
```

<Note>
  When canceled with `end_of_period`, the subscription `status` remains `active` and `auto_renew` is `false` until the period ends. The subscription will transition to `expired` when the period ends.
</Note>

***

## subscription.paused

Fired when a subscription is paused by the customer or via the Merchant API. Auto-renewal is suspended, but access is retained until the period end.

**Common use cases:**

* Suspend provisioned resources or downgrade service level
* Log the pause for analytics
* Send a "we'll miss you" email

**Payload example:**

```json theme={null}
{
  "event": "subscription.paused",
  "event_id": "c9d0e1f2-a3b4-5678-cdef-789012345678",
  "data": {
    "subscription": {
      "id": 501,
      "status": "paused",
      "external_customer_id": "usr_abc123",
      "product_id": 102,
      "product_name": "Pro Plan",
      "variant": {
        "id": 15,
        "price": 49,
        "duration": "monthly"
      },
      "duration": "monthly",
      "current_period_start": "2025-06-01T00:00:00.000000Z",
      "current_period_end": "2025-07-01T00:00:00.000000Z",
      "auto_renew": false,
      "metadata": {
        "external_user_id": "usr_abc123"
      },
      "customer": {
        "id": 123,
        "email": "ahmed@example.com",
        "name": "Ahmed Ali"
      }
    }
  }
}
```

<Note>
  When a subscription is paused, `is_active` becomes `false` and auto-renewal stops. The remaining days at the time of pause are stored internally. When unpaused, the period is extended by those remaining days.
</Note>

***

## subscription.unpaused

Fired when a paused subscription is resumed. The subscription returns to `active` status and the billing period is extended by the number of days remaining when it was paused.

**Common use cases:**

* Re-provision access or restore service level
* Resume billing in your external system
* Send a "welcome back" notification

**Payload example:**

```json theme={null}
{
  "event": "subscription.unpaused",
  "event_id": "d0e1f2a3-b4c5-6789-defa-890123456789",
  "data": {
    "subscription": {
      "id": 501,
      "status": "active",
      "external_customer_id": "usr_abc123",
      "product_id": 102,
      "product_name": "Pro Plan",
      "variant": {
        "id": 15,
        "price": 49,
        "duration": "monthly"
      },
      "duration": "monthly",
      "current_period_start": "2025-06-20T00:00:00.000000Z",
      "current_period_end": "2025-07-10T00:00:00.000000Z",
      "auto_renew": true,
      "metadata": {
        "external_user_id": "usr_abc123"
      },
      "customer": {
        "id": 123,
        "email": "ahmed@example.com",
        "name": "Ahmed Ali"
      }
    }
  }
}
```

***

## subscription.resumed

Fired when a canceled subscription is resumed before the current period ends. The subscription returns to `active` status and auto-renewal is re-enabled.

**Common use cases:**

* Restore access that was scheduled for revocation
* Update your CRM to reflect the reactivation
* Cancel any scheduled access revocation

**Payload example:**

```json theme={null}
{
  "event": "subscription.resumed",
  "event_id": "e1f2a3b4-c5d6-7890-efab-901234567890",
  "data": {
    "subscription": {
      "id": 501,
      "status": "active",
      "external_customer_id": "usr_abc123",
      "product_id": 102,
      "product_name": "Pro Plan",
      "variant": {
        "id": 15,
        "price": 49,
        "duration": "monthly"
      },
      "duration": "monthly",
      "current_period_start": "2025-06-01T00:00:00.000000Z",
      "current_period_end": "2025-07-01T00:00:00.000000Z",
      "auto_renew": true,
      "metadata": {
        "external_user_id": "usr_abc123"
      },
      "customer": {
        "id": 123,
        "email": "ahmed@example.com",
        "name": "Ahmed Ali"
      }
    }
  }
}
```

***

## subscription.updated

Fired when a subscription is modified, such as a variant change (upgrade/downgrade) or a courtesy extension.

**Common use cases:**

* Update access level in your system for upgrades
* Schedule a downgrade for the next billing cycle
* Log the change for auditing

**Payload example:**

```json theme={null}
{
  "event": "subscription.updated",
  "event_id": "b8c9d0e1-f2a3-4567-bcde-678901234567",
  "data": {
    "subscription": {
      "id": 501,
      "status": "active",
      "external_customer_id": "usr_abc123",
      "product_id": 102,
      "product_name": "Pro Plan",
      "variant": {
        "id": 20,
        "price": 99,
        "duration": "monthly"
      },
      "duration": "monthly",
      "current_period_start": "2025-06-01T00:00:00.000000Z",
      "current_period_end": "2025-07-01T00:00:00.000000Z",
      "auto_renew": true,
      "metadata": {
        "external_user_id": "usr_abc123"
      },
      "customer": {
        "id": 123,
        "email": "ahmed@example.com",
        "name": "Ahmed Ali"
      }
    }
  }
}
```

***

## Choosing the Right Event

<CardGroup cols={2}>
  <Card title="order.created">
    Use when you need to react to new sales — send notifications, sync to external systems, or trigger fulfillment.
  </Card>

  <Card title="order.status.changed">
    Use when you need to track order lifecycle — notify customers of updates, sync status changes, or trigger post-purchase workflows.
  </Card>

  <Card title="subscription.created">
    Use when you need to provision access for new subscribers or sync subscriptions to your system.
  </Card>

  <Card title="subscription.renewed">
    Use when you need to confirm recurring payments, send receipts, or extend access in external systems.
  </Card>

  <Card title="subscription.paused">
    Use when you need to suspend provisioned resources or pause billing in your system.
  </Card>

  <Card title="subscription.canceled">
    Use when you need to trigger retention flows or schedule access revocation.
  </Card>

  <Card title="subscription.expired">
    Use when you need to revoke access or trigger win-back campaigns.
  </Card>
</CardGroup>

<Note>
  You can create multiple webhooks for the same event with different URLs. For example, one webhook sending `subscription.renewed` to your billing system and another sending it to a Slack channel.
</Note>

<Warning>
  In the current implementation, **all enabled webhooks** receive all events regardless of the configured event type. The `event` field stored on the webhook is included for your reference, but event filtering is not enforced server-side. Your webhook handler should check the `event` field in the payload and ignore events it does not care about.
</Warning>
