Skip to main content
Subscriptions let you charge a customer every week, month or year in USDC or EURC. You create a plan that sets the price and how often it bills, then subscribe customers to it.
Renewals are collected, not pulled. We can’t take funds from a customer’s wallet, so at the end of every cycle Creptapay emails the subscriber their pay link and holds their access open for the grace period you set. Auto-debit — renewals charged against an on-chain allowance — is coming soon.

Why stablecoin subscriptions work differently

Card subscriptions are pull payments. You store a card and charge it whenever a period ends, without the customer doing anything. Stablecoins are push payments. Only the holder of a wallet can move funds out of it, so nothing can silently charge your customer. Creptapay handles this in two ways:

Recurring invoices

Each cycle we create a payment and send your customer a pay link. They settle it from any wallet or exchange, on any supported network.

On-chain auto-debit

Coming soon. Your customer approves a spending cap once and each cycle is pulled against it. True auto-renew, self-custody EVM wallets only.
Recurring invoices are what ships today, and collection_mode accepts "invoice" only — sending "auto_debit" or "both" is rejected rather than accepted and quietly collected some other way. Auto-debit won’t replace the pay link when it lands. An allowance can run dry or expire, and unlike a card there is no overdraft to retry into, so a failed pull falls back to exactly the flow below: past due, grace window, reminder emails, pay link. Everything you build now keeps working.

Plans

A plan is the template: the price, the cadence, and how long a late payer has to catch up.
interval and interval_count combine, so 3 and month bills quarterly. Plans are priced in fiat. Your customer pays the stablecoin equivalent at checkout, and you are credited in stablecoins.

Grace periods

grace_days is how long after a period ends a subscriber can still pay before their subscription expires. You choose it per plan — a gym might allow a day, an annual B2B contract a fortnight. The grace deadline is frozen onto the subscription when each period starts. Shortening a plan’s grace period later never moves a deadline a subscriber has already been given.

Subscribing a customer

Pass customer_id instead to subscribe someone you already have on file. The response carries a checkout_url. Send your customer there to take the first payment:
This link is permanent and it is the only one you ever need. It resolves to whichever cycle is currently due, so the same URL takes the first payment in January and the renewal the following December. A few things follow from that:
  • The quote is minted when they arrive, not when the bill was raised. A customer opening the link gets a fresh address and a rate good for 15 minutes, so a link sitting in an inbox for a week never settles at a stale rate.
  • An expired attempt doesn’t kill the link. If they walk away mid-payment they can open it again and start a new attempt.
  • Opening it early is safe. A subscriber who arrives mid-period sees what they’ll owe and when, with nothing to pay — paying early would end the period they’ve already bought.
You don’t have to send it yourself. We email it to the subscriber at each of the points below.

How renewals are collected

At the end of each cycle the subscription moves to past_due and the grace window you set on the plan begins. Access is yours to control — the webhooks tell you when to cut it off. Three emails go to the subscriber per cycle, one of each at most, however often the billing job runs: Pay before the deadline and the next period starts where the last one ended — paying four days late does not push every future renewal four days later. Miss it and the subscription moves to expired. A first payment is treated a little differently: a brand new subscription gets at least 7 days to be paid, even on a plan with no grace, so a signup doesn’t lapse while the customer is still reading the email.

Webhooks

Every payment also fires the usual payment.* events, so an existing integration keeps working — a subscription renewal arrives as an ordinary payment.paid with type: "subscription", the subscription’s id in subscription, and the cycle it covers in billing_period_start and billing_period_end. Full payloads, delivery behaviour and how to register endpoints are in Webhooks.

Changing a plan’s price

Plans are fully editable, price and cadence included. Existing subscribers are never affected. When a customer subscribes, the plan’s terms are copied onto their subscription. Billing reads that copy, never the plan. So a plan is a template for new sign-ups rather than a live price that reaches backwards into people who already signed up.
on_legacy_terms tells you the plan has since been repriced and this subscriber has not moved. To move them onto current pricing, call apply-plan-terms — it takes effect from the next period and leaves the period they have already paid for alone.
Nothing moves a subscriber’s price unless you ask for it.

Subscription statuses

Canceling

Canceling defaults to the end of the paid-for period. The subscription stays active with cancel_at_period_end: true until then, so a customer keeps what they paid for.
Pass at_period_end: false to end it immediately.
When you list subscriptions for a dashboard, treat cancel_at_period_end as its own state. Those subscriptions are still active and still paying — showing them as canceled hides revenue you still have.

Billing dates

Periods are measured from a fixed anchor: the start of the first paid period. Period N ends at anchor plus N intervals. This matters at month ends. A subscription anchored on 31 January bills 28 February, then 31 March, then 30 April, then 31 May — the anchor day comes back whenever the month is long enough. Chaining each period off the previous one would clamp to the 28th and stay there, quietly shortening every future cycle.