ReferenceSubscriptions

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.

MethodPathPurpose
POST/v1/subscriptionsCreate a subscription.
GET/v1/subscriptions/:idFetch one subscription.
POST/v1/subscriptions/:id/pausePause an active subscription.
POST/v1/subscriptions/:id/resumeResume a paused subscription.
POST/v1/subscriptions/:id/cancelCancel 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.

MethodPathPurpose
GET/v1/tenants/:tenant/customers/:customerRef/subscriptionsList a shopper’s own subscriptions.
POST/v1/tenants/:tenant/customers/:customerRef/subscriptions/:id/cancelShopper self-serve cancel (immediate; a cancellation-confirmation email is sent).
POST/v1/tenants/:tenant/customers/:customerRef/subscriptions/:id/pauseShopper self-serve pause.
POST/v1/tenants/:tenant/customers/:customerRef/subscriptions/:id/resumeShopper 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.

MethodPathScopePurpose
GET/v1/merchant/subscriptionsmanage:own_subscriptionsList the caller’s subscriptions.
GET/v1/merchant/subscriptions/:idmanage:own_subscriptionsFetch one (cross-tenant/unknown are an indistinguishable 404).
POST/v1/merchant/subscriptions/:id/cancelmanage:own_subscriptionsCancel.
POST/v1/merchant/subscriptions/:id/pausemanage:own_subscriptionsPause.
POST/v1/merchant/subscriptions/:id/resumemanage:own_subscriptionsResume.

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.discounts maps interval-days ("30", "60") -> percent off, and behavior.subscriptions.autoEnrollBundles defaults false.
  • behavior.accounts.subscriptionSelfServe — the account-page self-serve cancel/pause surface. Defaults true.