Subscriptions
Recurring billing with automatic invoice generation
Subscriptions represent ongoing recurring billing relationships with customers. RevKeen automatically generates invoices, processes payments, and handles the complete subscription lifecycle.
Subscription Lifecycle
┌─────────┐ ┌──────────┐ ┌────────┐
│ PENDING │────▶│ TRIALING │────▶│ ACTIVE │
└─────────┘ └──────────┘ └───┬────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ PAST_DUE │ │ PAUSED │ │ CANCELED │
└────┬─────┘ └──────────┘ └──────────┘
│
▼
┌──────────┐
│ UNPAID │
└──────────┘Subscription Statuses
| Status | Description | Billing |
|---|---|---|
pending | Subscription created, awaiting first payment | Not billing |
trialing | In free trial period | Not billing |
active | Active and billing normally | Billing |
past_due | Payment failed, retrying | Attempting |
paused | Temporarily paused by customer or merchant | Not billing |
canceled | Subscription ended | Not billing |
unpaid | All payment retries exhausted | Stopped |
Subscription Items
A subscription can contain multiple items, similar to Stripe's model. This allows you to bundle multiple products in a single subscription.
// Subscription with multiple items
const subscription = await client.subscriptions.create({
customerId: 'cus_xxxxxxxx',
items: [
{
priceId: 'price_pro_monthly', // Pro plan at $49/mo
quantity: 1,
},
{
priceId: 'price_extra_users', // Extra users at $10/mo each
quantity: 5,
},
],
});
// Each item generates its own line on invoicesCreating Subscriptions
Via Checkout
The most common way to create subscriptions is through checkout links:
- Create a checkout link with a recurring price
- Customer completes checkout
- Subscription is automatically created
- First invoice is generated and charged
Via API
const subscription = await client.subscriptions.create({
customerId: 'cus_xxxxxxxx',
items: [
{
priceId: 'price_xxxxxxxx',
quantity: 1,
},
],
// Optional: Start with a trial
trialPeriodDays: 14,
// Optional: Custom billing anchor
billingCycleAnchor: new Date('2025-02-01'),
// Optional: Default payment method
defaultPaymentMethodId: 'pm_xxxxxxxx',
});
console.log(subscription.data.status); // 'trialing' or 'active'Trial Periods
Trials allow customers to try your product before paying:
- Subscription status is
trialing - Customer has full access during the trial
- No payment is collected
- At trial end, first invoice is created and charged
- If payment fails, subscription enters
past_due
Trial periods can be set on the Price or overridden when creating the subscription.
Billing Cycle
Each subscription has a billing cycle that determines when invoices are generated:
| Field | Description |
|---|---|
current_period_start | Start of current billing period |
current_period_end | End of current billing period |
billing_cycle_anchor | Day of month/year for billing (e.g., 1st of each month) |
Managing Subscriptions
Pause a Subscription
await client.subscriptions.pause('sub_xxxxxxxx', {
// Optional: Auto-resume after a period
resumeAt: new Date('2025-03-01'),
});Resume a Subscription
await client.subscriptions.resume('sub_xxxxxxxx');Cancel a Subscription
// Cancel immediately
await client.subscriptions.cancel('sub_xxxxxxxx');
// Cancel at end of current period
await client.subscriptions.cancel('sub_xxxxxxxx', {
cancelAtPeriodEnd: true,
});Canceling immediately stops billing and may require prorated refunds. Use
cancelAtPeriodEnd for a graceful end.Dunning (Payment Recovery)
When a subscription payment fails, RevKeen automatically enters the dunning process:
- Subscription status changes to
past_due - Payment is retried according to your retry schedule
- Customer receives reminder emails
- If all retries fail, subscription becomes
unpaidorcanceled
Configure dunning behavior at Settings → Dunning including retry intervals, email templates, and end behavior.
Subscription Events
| Event | When Triggered |
|---|---|
subscription.created | Subscription is created |
subscription.activated | Trial ends or first payment succeeds |
subscription.renewed | Billing period renews successfully |
subscription.paused | Subscription is paused |
subscription.resumed | Paused subscription resumes |
subscription.canceled | Subscription is cancelled |
subscription.trial_ended | Trial period ends |