Creating subscriptions
Start a subscription with prices, trials, and a payment method.
Create a subscription by attaching a customer, one or more prices, and a payment method, with optional trial and proration behavior. Once created, the subscription becomes the engine that generates invoices each cycle — so getting the first call right means recurring revenue collects itself.
What you need firstAsk
A subscription ties three things together. Have each ready before you call the API:
| Ingredient | Prefix | Created where |
|---|---|---|
| A customer | cust_ | Customers |
| One or more recurring prices | price_ | Products & prices |
| A default payment method | pm_ | Attached to the customer or passed at creation |
Prices must be recurring (have a recurring.interval). A one-time price belongs on an invoice item, not a subscription.
Create your first subscriptionAsk
The minimal call attaches a customer to a price. VINR uses the customer's default payment method and anchors the billing cycle to the creation time.
import { Vinr } from '@vinr/sdk';
const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });
const subscription = await vinr.subscriptions.create({
customer: 'cust_8Hk2pQ',
items: [{ price: 'price_pro_monthly', quantity: 1 }],
});
console.log(subscription.id); // "sub_..."
console.log(subscription.status); // "active"If the customer has no default payment method, pass one explicitly. The method is attached to the customer and set as default for future cycles:
const subscription = await vinr.subscriptions.create({
customer: 'cust_8Hk2pQ',
items: [{ price: 'price_pro_monthly' }],
default_payment_method: 'pm_card_visa',
});What happens on creationAsk
VINR validates and creates the subscription
The customer, prices, and payment method are checked. The subscription is created with a billing_cycle_anchor (defaults to now).
The first invoice is generated and finalized
Unless the subscription is in a trial, VINR immediately creates a draft invoice, applies any discounts and tax, and finalizes it.
The first invoice is collected
The finalized invoice is paid against the default method. This may require SCA — handle the requires_action outcome client-side.
Status settles
On success the subscription becomes active and VINR emits subscription.created and invoice.paid. If collection fails, the subscription enters past_due and dunning begins.
Adding a trialAsk
A trial delays the first charge. The subscription is trialing until the trial ends, then VINR collects the first real invoice automatically. Use either a duration or an explicit end timestamp.
const subscription = await vinr.subscriptions.create({
customer: 'cust_8Hk2pQ',
items: [{ price: 'price_pro_monthly' }],
trial_period_days: 14,
});
// status: "trialing" — no invoice collected yetconst subscription = await vinr.subscriptions.create({
customer: 'cust_8Hk2pQ',
items: [{ price: 'price_pro_monthly' }],
trial_end: 1751328000, // Unix seconds; first charge lands here
});Collecting a payment method up front during a trial is strongly recommended. Without one, the subscription lapses into past_due the moment the trial ends and no card is on file. See Trials & proration.
Key parametersAsk
Prop
Type
Aligning the billing cycleAsk
By default each subscription bills on its own creation date. To align many customers to a single date (for example, everyone on the 1st), set an explicit billing_cycle_anchor. VINR prorates the partial first period unless you pass proration_behavior: 'none'.
const subscription = await vinr.subscriptions.create({
customer: 'cust_8Hk2pQ',
items: [{ price: 'price_pro_monthly' }],
billing_cycle_anchor: 1751328000, // first day of next month, 00:00 UTC
proration_behavior: 'create_prorations',
});React with webhooks, not the responseAsk
The create call returns the subscription, but collection can complete asynchronously (SCA, bank delays). Provision access on the event, not the API return value.
const event = vinr.webhooks.verify(payload, request.headers['x-vinr-signature']);
switch (event.type) {
case 'subscription.created':
// subscription exists — may still be collecting its first invoice
break;
case 'invoice.paid':
grantAccess(event.data.object.customer); // safe to fulfil here
break;
case 'invoice.payment_failed':
// dunning has begun; surface a recovery prompt
break;
}Edge casesAsk
Next stepsAsk
Trials & proration
Free trials, partial periods, and mid-cycle changes.
Managing subscriptions
Upgrade, pause, cancel, and the full lifecycle.
Dunning & recovery
What happens when a recurring charge fails.
Last updated on