Pausing & resuming
Temporarily suspend billing without cancelling.
Pause collection on a subscription to retain the relationship while stopping invoices, then resume when the customer returns. Pausing is the right tool for seasonal customers, payment-recovery holds, and "skip a month" flows — it keeps the sub_ and its history intact instead of forcing a cancel-and-recreate.
Pause vs. cancelAsk
A pause is reversible and preserves the subscription's identity, billing cycle anchor, and metadata. A cancel ends the relationship: the subscription transitions to canceled and cannot be reactivated.
| Pause | Cancel | |
|---|---|---|
| Subscription status | active, with pause_collection set | canceled |
| Invoices during the period | Suspended (per behavior below) | None |
| Reversible | Yes — clear pause_collection to resume | No — create a new subscription |
| Keeps billing anchor | Yes | N/A |
Pause behaviorsAsk
When you pause, you choose what happens to invoices that would otherwise be generated. This is the behavior field on pause_collection.
Prop
Type
Pausing only affects invoices generated during the pause. Any invoice already finalized and open before you paused is unaffected — collect or void it explicitly.
Pause a subscriptionAsk
Set pause_collection on the subscription. Optionally schedule an automatic resume with resumes_at (a Unix timestamp in seconds).
import { Vinr } from '@vinr/sdk';
const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });
const subscription = await vinr.subscriptions.update('sub_8Qd2Rk1', {
pauseCollection: {
behavior: 'void',
// Resume automatically on 2026-09-01; omit to pause indefinitely.
resumesAt: 1756684800,
},
});
console.log(subscription.status); // "active"
console.log(subscription.pauseCollection); // { behavior: "void", resumesAt: 1756684800 }The subscription stays active — pausing is a collection setting, not a status. Inspect pause_collection to know whether a subscription is currently paused.
// Indefinite pause: omit resumesAt and resume manually later.
await vinr.subscriptions.update('sub_8Qd2Rk1', {
pauseCollection: { behavior: 'keep_as_draft' },
});curl -X POST https://api.vinr.com/v1/subscriptions/sub_8Qd2Rk1 \
-H "X-Api-Key: $VINR_SECRET_KEY" \
-d "pause_collection[behavior]=keep_as_draft"Resume a subscriptionAsk
To resume, clear pause_collection by setting it to null. VINR realigns billing to the original cycle anchor and prorates the first invoice for the time elapsed during the pause.
const resumed = await vinr.subscriptions.update('sub_8Qd2Rk1', {
pauseCollection: null,
// Optional: reset the anchor to now instead of the original cycle.
billingCycleAnchor: 'now',
});
console.log(resumed.pauseCollection); // nullBy default, resuming keeps the original billing cycle anchor, so a long pause can produce a large prorated catch-up charge. Pass billingCycleAnchor: 'now' to start a fresh full period from the resume date and avoid surprise proration.
Resulting eventsAsk
| Event | When it fires |
|---|---|
subscription.paused | pause_collection is set on a previously unpaused subscription. |
subscription.resumed | pause_collection is cleared, manually or by resumes_at. |
subscription.updated | Any change to pause_collection, including behavior swaps. |
invoice.created | Each cycle during a pause, when behavior is keep_as_draft. |
// Gate access in your webhook handler.
const event = vinr.webhooks.verify(payload, req.headers['x-vinr-signature']);
if (event.type === 'subscription.paused') {
await revokeAccess(event.data.object.customer);
} else if (event.type === 'subscription.resumed') {
await grantAccess(event.data.object.customer);
}Edge casesAsk
Next stepsAsk
Subscriptions
The full subscription lifecycle.
Trials & proration
How VINR computes partial-period charges.
Dunning & recovery
Recover failed payments before cancelling.
Last updated on