TillsafeDocstillsafe.comRequest early access

Subscriptions

Plans, customers and recurring billing where every period is an ordinary invoice, with retries and prepaid credit.

Subscriptions bill in advance, one invoice per period: the payer pays each renewal from a wallet or an exchange, exactly like any invoice. Nothing is pulled from anyone's wallet.

  1. Create a plan: POST /v1/plans (price per period, interval, trial, grace, payment attempts).
  2. Create a customer: POST /v1/customers (name, email and metadata).
  3. Subscribe them: POST /v1/subscriptions. Without a trial it starts incomplete with its first invoice; with a trial it is active at once.
  4. Fulfil on subscription.renewed and stop service on subscription.cancelled. Every renewal invoice also sends the ordinary invoice.* webhooks.

Pause with POST /v1/subscriptions/{id}/pause, resume with POST /v1/subscriptions/{id}/resume, and cancel now or at the period end with POST /v1/subscriptions/{id}/cancel.

Plans

A plan has a price per period in fiat, an interval (day, week, month or year, times a count), an optional trial in days, a grace period in days (3 by default), the number of payment attempts per period (1 to 7), the assets it accepts (or your account's defaults) and a billing time zone. Archive a plan you no longer offer with POST /v1/plans/{id}/archive.

Periods are counted from an anchor: the start, or the end of the trial. Each period starts at the anchor's wall-clock time in the plan's time zone plus a whole number of intervals, always counted from the anchor, so a subscription that started on 31 January renews on 28 February and then on 31 March, never drifting to the 28th. Local midnight stays midnight across daylight-saving changes.

Statuses

StatusMeaning
incompleteWaiting for the first payment.
activePaid up (or in its trial).
past_dueA renewal is still unpaid after the grace period. Retries continue.
pausedYou paused it. Resuming after the paid time ran out starts a new period at the resume.
cancelledFinal: you cancelled it, or every payment attempt for a period closed unpaid.

The renewal cycle

WhenWhat happens
1 day before the due datePrepaid credit pays what it can; the rest becomes a renewal invoice (subscription.invoice_created).
1, 3, 5, 7, 10 and 14 days after itRetries, up to the plan's attempts: a fresh invoice, but only once the previous one has closed unpaid. A payer in the middle of paying never gets a second invoice.
After the grace periodStill unpaid: active becomes past_due (subscription.past_due). Retries continue.
The last attempt closed unpaidcancelled, with cancellation_reason: "unpaid".
Any attempt is paidThe period is paid, the subscription is active, and you get subscription.renewed.

A stablecoin invoice stays open for 24 hours, so the one-day lead keeps a renewal payable until its due date.

Prepaid credit

A customer can hold credit, in the tokens that actually arrived:

  • An overpayment of a renewal becomes credit.
  • POST /v1/customers/{id}/top_up creates a top-up invoice; paying it adds credit.
  • A renewal uses credit first. Credit that covers a whole period renews it without an invoice (subscription.renewed without invoice); partial credit lowers the invoice (metadata.credit_applied).
  • Credit is granted only once the payment is final, so a chain reorganisation cannot take it back. Money that became credit is no longer refundable through the invoice.

Reminders

Renewal reminders by email are not sent yet. Until they are, send the payer the renewal invoice yourself when you receive subscription.invoice_created (the top-level invoice_id names it).

Not supported yet

Proration and plan changes, coupons, quantities, a customer portal, and crediting partial payments of expired renewal invoices (they stay ordinary refundable payments).