Subscriptions
Subscriptions is a recurring-billing engine: a billing schedule, an automatic renewal cycle, and a dunning ladder that retries declines on a stored payment credential. Renewals charge through the platform’s payment processing and record revenue automatically.
Exactly-once renewal is a guarantee you can rely on: each billing period
is charged at most once, next_bill_at advances only after a renewal settles,
and an indeterminate (transport-failure) charge is never treated as a decline.
See Money invariants.
Subscription lifecycle (operator-managed)
Subscription creation and lifecycle management are operator/console-managed. Merchants read and act on their own subscriptions through the merchant routes below.
| Method | Path | Purpose |
|---|---|---|
POST | /v1/subscriptions | Create a subscription. |
GET | /v1/subscriptions/:id | Fetch one subscription. |
POST | /v1/subscriptions/:id/pause | Pause an active subscription. |
POST | /v1/subscriptions/:id/resume | Resume a paused subscription. |
POST | /v1/subscriptions/:id/cancel | Cancel a subscription. |
An invalid lifecycle transition returns 409 invalid_transition; a failed
write returns 503, never a false success. The renewal, reconcile, and
renewal-reminder cycles run automatically.
Shopper-scoped routes
Scoped to (tenant, customer_ref) and ownership-checked on every mutation, so
a shopper can only touch their own subscription.
| Method | Path | Purpose |
|---|---|---|
GET | /v1/tenants/:tenant/customers/:customerRef/subscriptions | List a shopper’s own subscriptions. |
POST | /v1/tenants/:tenant/customers/:customerRef/subscriptions/:id/cancel | Shopper self-serve cancel (immediate; a cancellation-confirmation email is sent). |
POST | /v1/tenants/:tenant/customers/:customerRef/subscriptions/:id/pause | Shopper self-serve pause. |
POST | /v1/tenants/:tenant/customers/:customerRef/subscriptions/:id/resume | Shopper self-serve resume (next_bill_at recomputes forward — never back-bills). |
Renewal reminders (auto-renewal law)
Every store sends a pre-billing renewal reminder; the sweep covers active
and past_due subscriptions. renewalReminderDaysBeforeBilling is
per-store (default 7) with an enforced floor of 3 — values below the floor
clamp to the default and are logged; reminders cannot be configured off. A
shopper’s marketing unsubscribe never blocks these (they are transactional);
a hard bounce records the reminder as undeliverable, visibly, never as
sent. Subscription creation at storefront checkout requires recorded consent
evidence (subscriptionConsent — disclosure version, content hash, IP hash,
user agent), persisted on the subscription row.
Merchant routes
fdk_ credential (Authorization: Bearer), tenant resolved from the
credential per credential-carries-ownership, scope manage:own_subscriptions.
The portal’s Subscriptions page. A failed read is a 503, never
an empty list.
| Method | Path | Scope | Purpose |
|---|---|---|---|
GET | /v1/merchant/subscriptions | manage:own_subscriptions | List the caller’s subscriptions. |
GET | /v1/merchant/subscriptions/:id | manage:own_subscriptions | Fetch one (cross-tenant/unknown are an indistinguishable 404). |
POST | /v1/merchant/subscriptions/:id/cancel | manage:own_subscriptions | Cancel. |
POST | /v1/merchant/subscriptions/:id/pause | manage:own_subscriptions | Pause. |
POST | /v1/merchant/subscriptions/:id/resume | manage:own_subscriptions | Resume. |
Manifest gates
Two behavior keys in the store manifest gate the storefront subscription surfaces:
behavior.subscriptions.enabled— the Subscribe & Save switch . Default false;behavior.subscriptions.discountsmaps interval-days ("30","60") -> percent off, andbehavior.subscriptions.autoEnrollBundlesdefaults false.behavior.accounts.subscriptionSelfServe— the account-page self-serve cancel/pause surface. Defaults true.