Skip to main content
Subscribes a user to an existing plan. In a single transaction the contract sets the SEP-41 token allowance and creates the subscription record. The subscriber signs once and both operations are authorized. If the plan has no trial (trial_periods = 0), the contract charges the first period atomically during subscribe — Stripe-style semantics. If the plan has a trial, no funds move until the trial ends. Returns the chain-assigned sub_id.

Parameters

Both expiration_ledger and allowance_periods are passed in rather than computed inside the contract. This is intentional: the nested token.approve() call’s args must match exactly between simulation and submission, otherwise Soroban’s auth tree rejects the invocation.

Authorization

The subscriber’s single signature covers both the subscribe() contract call and the nested token.approve() call. Soroban’s auth tree bundles both operations into one authorization.
The subscriber signs once. Their wallet shows exactly what is being authorized: the Vowena contract call and the token allowance (amount = price_ceiling * allowance_periods, spender = Vowena contract).

Allowance calculation

Where effective_periods is:
  • min(allowance_periods, plan.max_periods) if plan.max_periods > 0
  • min(allowance_periods, 120) if the plan is unlimited
The allowance is set against the plan’s price_ceiling, not the current amount. This way the merchant can adjust pricing within the ceiling without requiring re-authorization.

Return value

u64 — the newly created subscription ID.

Events emitted


Error cases


Examples

If the plan has trial periods, the subscription starts immediately but billing begins after the trial ends. The next_billing_time is set to now + plan.period and the trial periods are advanced without charging.