Recurring crypto billing without holding customer funds
Subscriptions assume a merchant can charge a customer later. Blockchains have no such primitive. Here is the design that makes recurring billing work without custody.
Card subscriptions rest on a capability we rarely examine: after the customer agrees once, the merchant can initiate charges later, without the customer being present. The card network provides that pull mechanism, and the issuer arbitrates when it is abused.
Blockchains have no pull. A transfer requires the holder's signature at the moment it happens. So a naive crypto subscription becomes either 'the customer manually pays every month' — which churns badly — or 'the customer deposits a balance with the merchant', which is custody with extra steps.
The vault approach
There is a third option. The customer funds a contract that only they own, and that contract is constrained in advance about what may be withdrawn from it.
- The subscription terms — amount, cycle length, recipients — are hashed into the contract's address. The address is a commitment to those exact terms.
- A keeper process triggers each charge on schedule and pays the gas. It cannot change the amount, shorten the cycle, or redirect funds; the contract rejects anything that does not match the committed terms.
- The customer can withdraw the remaining balance or cancel at any time, without asking anyone.
The customer is not trusting the merchant with a balance. They are funding a container whose rules were fixed before they put money in, and which they can empty whenever they like.
What that constraint costs
It makes upgrades and downgrades harder than they are on cards, and it is worth being upfront about that.
You cannot edit a price field. A plan change has to close the old vault and open a new one, in a single atomic transaction the customer signs once. Unused time on the old plan is credited toward the first cycle of the new one.
The interesting part is who computes that credit. The backend proposes a number, and the contract recomputes it independently and reverts if they disagree. So the customer does not have to trust the platform's arithmetic — a mistake or a manipulation simply fails to execute.
Failure modes you should design for
| Situation | What happens | What you should do |
|---|---|---|
| Vault balance runs low | An insufficient-balance event fires before the charge fails. | Prompt the customer to top up. This is your main retention lever. |
| Customer cancels | Charges stop; the remaining balance stays theirs to withdraw. | Revoke access at period end, not immediately — they paid for the cycle. |
| Customer withdraws everything | Future charges fail. | Treat it as an intent to cancel and confirm with them. |
| Plan price changes | Existing subscriptions keep their original terms until each customer migrates. | Grandfather existing subscribers, or invite them to migrate explicitly. |
That third row is genuinely different from cards. A customer can defund a subscription unilaterally and without notice. In exchange, they are far more willing to start one, because they are never handing you an open-ended claim on their wallet.
When this is the wrong tool
Usage-based billing that varies unpredictably each cycle fits this model poorly, because the committed amount is fixed in advance. Metered billing with a hard cap works; genuinely open-ended metering does not.
If your pricing changes frequently, the migration requirement will be a recurring friction rather than a one-time one. That is a real cost, not a detail.
The subscriptions reference covers plans, vaults, proration, and the full set of subscription events.
Read the subscriptions guide →