Subscriptions
Throttle subscriptions turn a one-time embed payment into a recurring billing relationship. The card vaulted during checkout is reused on a 5-minute renewal cron, with built-in dunning and a webhook stream that lets your backend stay in sync.
What ships in v1
- Recurring on the embed. Pass a
recurringblock on a checkout session, the embed vaults the card, and (whencreate: 'auto'is set) Throttle creates the subscription on your behalf. - Lifecycle API. Cancel, pause, resume, change plan, list, and fetch
subscriptions through
@usethrottle/subscriptions/serverfrom your backend, or through the React hooks routed via your backend proxy. - Mid-period proration. A plan or seat change sent with
effective: 'now'credits the unused portion of the period the buyer already paid for, then charges the net — and skips the charge entirely when the credit covers it. The response carries aprorationbreakdown (creditCents,chargedCents,fullAmount). Sendeffective: 'period_end'to schedule the change for the next renewal instead, with no charge now. - React management package.
@usethrottle/subscriptionsexposes hooks and primitive components so your buyer-facing portal does not have to re-derive the API plumbing. - Any cadence, and installment plans. Send
intervalfor the five named intervals, orintervalUnit+intervalCountfor any cadence from 1 hour to 1 year. AddtotalPayments(2–60) to make it an installment plan that completes itself after N payments and emitssubscription.completed. See Lifecycle and States . - Built-in dunning. Retry
nwaitsmin(n × cadence, [1, 3, 7][n − 1])days — weekly and longer cadences always land on the original[1, 3, 7]days; shorter custom cadences retry proportionally faster. The first failed attempt moves the subscription topast_due; if all three retries also fail it auto-cancels with adunning_exhaustedreason. - Trial-fraud protection. Auto-create checks the card fingerprint against
prior subscriptions on this merchant; same card already used for a trial → new
subscription is created without a trial and a
subscription.trial_blockedwebhook fires. Pre-flight viaPOST /api/v1/subscriptions/eligibility-check. See Trial Fraud Protection . - Webhook stream.
subscription.created,.updated,.activated,.renewed,.past_due,.payment_failed,.paused,.resumed,.cancelled,.completed.
What is intentionally out of v1
- No-card free trials. Trials always require a vaulted card up front; the
embed does not yet support a "subscribe now, add card later" flow. Trials with a card
behave the way you expect — Throttle delays the first charge until
trialEnd. - Net30 recurring. Renewals charge a stored card via the payment provider. Net30 is supported for one-time orders today; Net30 recurring (invoice every period) is not part of the current subscription package surface.
- Customer-scoped JWTs. The React package authenticates by proxying through your backend. Direct browser → Throttle calls require a customer token system that is not yet built. See Buyer Portal for the proxy pattern documented for v1.
- Throttle-sent emails. All notifications flow through your webhook
endpoint; you decide which emails to send. Subscribing to
subscription.payment_failedis enough to wire the standard "your card was declined" copy. - Recurring discounts. Promotion codes apply to cart-backed checkout totals today. Ongoing subscription-cycle discounts are deferred.
- Configurable dunning curve. The retry schedule scales down automatically for cadences shorter than a week, but merchants cannot configure their own multipliers or caps. Per-merchant or per-subscription overrides are deferred.
How the pieces fit
- Subscribe. Your backend creates a checkout session with a
recurringblock, or putsrecurringon cart lines, one subscription per line, up to ten. Buyer pays through<PaymentEmbed />. Card is vaulted. Throttle auto-creates the subscriptions.onSucceededreturnssubscriptionIds. - Renew. A cron runs every 5 minutes. For any subscription whose
currentPeriodEndhas passed, it charges the stored card with an idempotentchargeStoredcall and advances the period. On failure it follows the cadence-scaled[1, 3, 7]-day retry curve. - Manage. Your buyer portal calls your backend, which proxies to the Throttle API. The React package gives you hooks for the common flows.
- React. Your webhook handler stays in sync — record renewals, send
dunning emails, gate access on
past_due.
Tax on renewals
A renewal has no cart and no shipping address, so there is nothing for a tax provider to quote against. Throttle solves that by freezing an address on the subscription at signup and reusing it on every renewal.
-
taxAddressSnapshot— the address renewals are quoted against. A subscription created through checkout inherits the address the buyer was taxed on: the billing address when the checkout had no shipping step. Each renewal is quoted with it as both the shipping and the billing address, whichever one your tax trigger reads. The renewal order carries it as its shipping address, and also as its billing address when your trigger isbilling_address, so the filed document uses it too. -
taxAddressSource—checkoutwhen it came from the buyer's session,manualonce a merchant has edited it. A later checkout never overwrites a manual correction.
To correct it, PATCH /api/v1/subscriptions/:id with a taxAddress object (countryCode
is required; the rest are optional). Merchants can do the same from the Tax card on the
subscription detail page in the dashboard. Sending null clears the snapshot, which leaves renewals untaxed.
Sequence: auto-subscribe on card capture
When a session ships with a recurring block and create: 'auto', Throttle vaults the card
during the embed's capture, runs the trial-fraud check, and creates the subscription
before returning to the parent page.
sequenceDiagram
participant B as Buyer
participant F as Throttle Iframe
participant P as Payment Provider
participant T as Throttle Backend
participant H as Webhook Endpoint
B->>F: fills card details
F->>P: authorize + tokenize
P-->>F: paymentMethodId
F->>T: POST /complete (recurring + create:auto)
T->>P: capture + vault payment method
P-->>T: vaulted token
T->>T: checkTrialEligibility(card fingerprint)
alt eligible for trial
T->>T: set trialEnd = now + trialDays
else fingerprint already used
T->>H: subscription.trial_blocked
end
T->>T: subscriptionService.create(...)
T-->>F: { orderId, paymentId, subscriptionIds }
T->>H: subscription.created
F->>B: throttle.completed Pages in this section
- Quickstart — five-minute end-to-end.
- Creating Subscriptions — auto, manual, and webhook patterns.
- Mixed Carts — goods and several subscriptions in one checkout.
- Customer Identity — externalCustomerId pattern + alternates.
- Lifecycle and States — state machine, trials, dunning.
- Trial Fraud Protection — card-fingerprint check + eligibility-check API.
- Testing — sandbox smoke tests and webhook assertions.
- Managing Subscriptions — pause, resume, cancel, change plan.
- Buyer Portal — the proxy pattern with templates.
- React Package —
@usethrottle/subscriptionsreference. - Subscription Webhooks — event types and payloads.
- Usage Reporting —
metered usage via
POST/GET .../usage; billed at renewal.