Prerequisites
- An RMZ store with an RMZ+ subscription plan
- At least one subscription product created in your store dashboard
- API keys from Dashboard > Settings > API Keys
- A webhook endpoint to receive subscription events
Overview
RMZ subscriptions support:- Multiple billing cycles: monthly, quarterly, semi-annual, annual, biennial, and more
- Free trials: optional trial periods before the first charge
- Auto-renewal: automatic charging via saved payment cards
- Dunning: retry logic for failed payments (up to 3 attempts over 7 days)
- Plan changes: upgrades (immediate with proration) and downgrades (at next period)
- Customer portal: hosted self-service portal for subscription management
Subscription Lifecycle
SubscriptionStatus::canTransitionTo()):
| From | Allowed Next States |
|---|---|
trialing | active, past_due, canceled, expired |
active | past_due, paused, canceled, expired |
past_due | active, canceled, expired |
paused | active, canceled, expired |
canceled | active (resume while period still valid) |
expired | — (terminal) |
Status Reference
| Status | Access Granted | Description |
|---|---|---|
trialing | Yes | Customer is in a free trial period |
active | Yes | Subscription is active and paid |
past_due | Yes | Payment failed, retries in progress (grace period) |
paused | No | Subscription is on hold (“freeze time”). Access is suspended while paused and auto-renewal is halted. At pause time, the days remaining in the current period are banked in metadata.paused_remaining_days. When the subscription is unpaused back to active, those banked days are added to the new period end, so the customer does not lose any paid time. |
canceled | No | Subscription was canceled immediately. Can be resumed back to active while the originally paid period has not yet ended. |
expired | No | Subscription period ended or all retries exhausted. Terminal state. |
Storefront Flow
If you are building a custom storefront (headless), customers purchase subscription products through the standard checkout flow.1. Display Subscription Products
Fetch products with typesubscription and display their variants:
2. Add to Cart and Checkout
3. After Purchase
Once payment completes, a subscription is automatically created. Listen for thesubscription.created webhook to provision access in your system.
4. View Customer Subscriptions
Authenticated customers can view their subscriptions:SaaS Integration Flow
If you are building a SaaS product and want to use RMZ for subscription billing, use the Merchant API to create checkout sessions programmatically.1. Create a Checkout Session
When a user wants to subscribe in your application, create a checkout session on your server:2. Handle the Webhook
Set up a webhook to handle subscription events:3. Manage Subscriptions via API
Cancel, extend, or query subscriptions from your server:Webhook Events Reference
Subscribe to these events to keep your system in sync:| Event | When to Use |
|---|---|
subscription.created | Provision access for new subscribers |
subscription.activated | Upgrade trial users to full access |
subscription.renewed | Confirm recurring payment and extend access |
subscription.renewal_failed | Alert customer about payment issues |
subscription.past_due | Show warning banners, send dunning emails |
subscription.expired | Revoke access |
subscription.canceled | Trigger retention flows |
subscription.updated | Handle plan changes and extensions |
Customer Billing Portal
The billing portal is a hosted page where customers can self-manage their subscriptions. You do not need to build any subscription management UI.Create a Portal Session
Portal Capabilities
In the portal, customers can:- View all their subscriptions and status
- Cancel a subscription (end of period or immediately)
- Change subscription plan (upgrade or downgrade)
- Update their payment method
- View payment history and invoices
Auto-Renewal and Dunning
When a customer has a saved payment card andauto_renew is enabled, RMZ automatically charges the card before the subscription period ends.
Renewal Process
- 3 days before period end: RMZ attempts to charge the saved card
- If payment succeeds: Subscription is renewed,
subscription.renewedwebhook fires - If payment fails: Subscription enters
past_due, retry schedule begins
Retry Schedule
| Attempt | Timing | Webhook Event |
|---|---|---|
| 1st | Immediately (at period end) | subscription.renewal_failed |
| 2nd | 3 days after first failure | subscription.renewal_failed |
| 3rd | 7 days after first failure | subscription.renewal_failed |
| Final | After 3rd failure | subscription.expired |
past_due status. Access is still granted during this grace period to avoid disrupting the customer.
Managing Subscriptions via API
List Subscriptions
Get Subscription Details
Cancel a Subscription
Extend a Subscription
Best Practices
Use webhooks for state changes
Never rely solely on API polling. Subscribe to webhook events and process them to keep your system in sync with subscription state.
Handle idempotency
Your webhook handler may receive the same event more than once. Use the
X-RMZ-REQUEST-ID header to deduplicate.Graceful degradation for past_due
Do not immediately revoke access when a subscription enters
past_due. The customer still has access during the retry period.Use end_of_period cancellation
Default to
end_of_period cancellation to preserve the customer experience. Only use immediate when necessary (e.g., policy violations).Next Steps
Webhook Events
Full list of subscription webhook events with payload examples.
Merchant API
Complete API reference for subscription management.
Billing Portal
Create portal sessions for customer self-service.
Webhook Integration Guide
Learn how to set up and verify webhooks.

