Create a subscription
Model products and prices, start a subscription, and handle the first invoice.
This guide creates a recurring subscription end-to-end: model a product and price, attach a customer with a saved payment method, start the subscription, and react to the first invoice. Runnable against the sandbox.
OverviewAsk
A subscription ties a customer to one or more prices and generates an invoice each cycle, collecting payment automatically. You'll fulfil access on invoice events.
This guide assumes the customer already has a saved payment method. If not, run Save & reuse cards first — Billing reuses the same stored method.
Model products & pricesAsk
Create the product once, then a recurring price for it. Prices are immutable — to change pricing, create a new price.
import { Vinr } from '@vinr/sdk';
const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });
const product = await vinr.products.create({ name: 'Pro plan' });
const price = await vinr.prices.create({
product: product.id,
amount: 2000, // €20.00
currency: 'EUR',
recurring: { interval: 'month' }, // 'day' | 'week' | 'month' | 'year'
});Create the subscriptionAsk
Attach the customer, the price, and an optional trial. VINR immediately creates the first invoice (or schedules it after the trial).
const subscription = await vinr.subscriptions.create({
customer: 'cust_abc123',
items: [{ price: price.id, quantity: 1 }],
trialPeriodDays: 14, // omit to bill immediately
metadata: { plan: 'pro' },
});
// subscription.id → "sub_..."
// subscription.status → "trialing" (or "active" with no trial)Handle the first invoiceAsk
Fulfil access from webhooks, not the API response — collection is asynchronous. The key events:
| Event | Do this |
|---|---|
invoice.paid | Grant or extend access for the period. |
invoice.payment_failed | Let dunning retry; warn the customer. |
subscription.updated | Sync plan/quantity changes. |
subscription.deleted | Revoke access. |
export async function POST(req: Request) {
const event = vinr.webhooks.verify(
await req.text(),
req.headers.get('x-vinr-signature'),
);
switch (event.type) {
case 'invoice.paid':
await grantAccess(event.data.customer, event.data.period_end);
break;
case 'subscription.deleted':
await revokeAccess(event.data.customer);
break;
}
return new Response('OK', { status: 200 });
}Manage the lifecycleAsk
- Upgrade/downgrade — change the item's price; VINR prorates automatically. See Upgrades & downgrades.
- Cancel —
vinr.subscriptions.cancel(id)immediately, orcancelAtPeriodEnd: trueto let it run out. See Cancellations. - Pause — suspend collection without losing the relationship. See Pausing & resuming.
Go liveAsk
Let customers self-serve
Enable the customer portal so customers update cards and plans without you building UI.
Configure dunning
Set retry schedules and emails in Dunning & recovery before real renewals happen.
Turn on tax
Enable automatic tax so every invoice collects the right amount.
Next stepsAsk
Bill for usage
Add metered, consumption-based pricing.
Set up dunning
Recover failed renewals.
Subscriptions reference
Every parameter and field.
Last updated on