| Where | What it does | What it holds |
| Your pages | Ask the wallet for its two signatures | Nothing secret |
| Your server | Creates subscriptions, checks access, receives webhooks | The API key |
| Mesub | Sends each charge, retries a missed one, records attempts | No funds |
| Solana | Holds the plan's terms and moves the tokens | The customer's delegation |
external_id), by the wallet that pays, or by their email.De1egAFMkMWZSN5rYXRj9CAdheBamobVNubTsi9avR44.| Account | One per | What it holds |
Plan | plan, created by you | The price, the period, who receives |
SubscriptionAuthority | wallet and token, the customer's | The right to move that token |
SubscriptionDelegation | wallet and plan, the customer's | The terms signed and the period state |
Plan account with its mint, amount, period_hours and
end_ts. amount and period_hours are immutable.
destinations lists the wallets that may receive the money, and pullers
lists who may trigger a charge besides you: Mesub's puller is one of them,
which is what lets Mesub charge on schedule without your signature. If you take it off
the plan, charges are blocked until it is back, and your subscribers are not
held to be late for it.code | The token |
mint_paused | Is paused by its issuer |
mint_frozen_by_default | Starts every new account frozen |
mint_non_transferable | Can never be transferred |
mint_transfer_hook | Runs a program of its issuer's on every transfer |
mint_confidential_only | Is held in confidential balances only |
mint_extension_unknown | Uses a Token-2022 extension Mesub does not support yet |
mint_display_scaled | Shows in wallets scaled by an interest rate or a multiplier |
end_ts in
Unix seconds. At that moment access stops for everybody. The last charge is
the one for the last period that starts before it.| Rule | What it is |
| At the earliest | One billing period from now, plus five minutes |
| At the latest | 100 years from now |
| Once created | The date cannot be removed or pushed later |
end_date_too_soon, and one too far with
end_date_too_far. A plan left unsigned until its date is too close is
refused with end_date_stale: change the date, then sign.plan_ended.SubscriptionAuthority for that token if
they have none, and a SubscriptionDelegation to your plan, which tracks
amount_pulled_in_period, current_period_start_ts and expires_at_ts. The authority is
approved as delegate on their token account; it can only move tokens when a
delegation says so, and a delegation only allows this:amount per period, counted in amount_pulled_in_period,destinations,pullers,expires_at_ts is zero or in the future.insufficient_sol, before anything is signed: the
customer adds SOL and tries again.amount, and your wallet receives it less that fee:
amount_received, on the attempt and in the subscription.created and
subscription.renewed events, says what arrived. PYUSD is such a token, with a fee of 0 today. When the issuer changes
the fee, Mesub mails you once and keeps charging the same amount. When the
issuer pauses the token or adds a transfer hook after the plan was made, Mesub
holds the charges (blocked_reason mint_paused or mint_transfer_hook),
mails you, and charges again once the issuer lifts the pause or removes the
hook.expires_at_ts to the end of the period already paid: access
runs until then, and no further charge can land. The customer signs it, through
your site or directly against the program. Resuming before that date clears it.
Closing the delegation afterwards returns its rent.hasAccess answers from that record, not from the account alone.@mesub/node
on the server and, optionally, @mesub/react
in your pages.