General
What blockchain is Vowena on?
What blockchain is Vowena on?
What tokens are supported?
What tokens are supported?
How much does a transaction cost?
How much does a transaction cost?
Is Vowena a single contract or multiple contracts?
Is Vowena a single contract or multiple contracts?
Is the contract upgradeable?
Is the contract upgradeable?
What wallets are supported?
What wallets are supported?
For Subscribers
Can the merchant raise prices without my consent?
Can the merchant raise prices without my consent?
What happens if I don't have enough balance?
What happens if I don't have enough balance?
charge() call. If you fund your wallet during the grace period, the next charge succeeds and billing resumes normally. If the grace period expires, your subscription transitions to Paused. If it remains paused for another billing period, it becomes Cancelled.Can I cancel anytime?
Can I cancel anytime?
cancel() on the contract. This can be done through:- The Vowena dashboard (one-click cancel)
- The Universal Subscription Manager
- Any Soroban block explorer
- The Stellar CLI directly
What's the difference between Paused and Cancelled?
What's the difference between Paused and Cancelled?
| Status | Meaning | Can recover? |
|---|---|---|
| Paused | Billing failed and grace period expired. | Yes - call reactivate() to re-approve allowance and resume. |
| Cancelled | Terminated by you, the merchant, or auto-cancelled after extended pause. | No - cancellation is irreversible. You’d need to create a new subscription. |
What happens if the merchant's app shuts down?
What happens if the merchant's app shuts down?
Direct on-chain cancellation
cancel() function is public. Call it from any block explorer or Soroban transaction builder. No frontend needed.Universal Subscription Manager
Auto-expiry
max_periods, the subscription expires automatically when that count is reached.How do free trials work?
How do free trials work?
trial_periods count. During trial periods, the charge() function advances the period counter but does not transfer any tokens. When the trial ends, normal billing begins. If you cancel during the trial, you are never charged.How do migrations work?
How do migrations work?
- They create a new plan with the new price
- They call
request_migration()- your subscription gets flagged as “migration pending” - You see the migration in the dashboard with old vs new price compared
- You accept (signs new allowance at new price) or reject (stay on current plan at current price)
For Merchants
What is the price ceiling?
What is the price ceiling?
update_plan_amount() - subscribers continue billing at the new amount without needing to re-approve. Beyond the ceiling, you must create a new plan and migrate subscribers.Can merchants refund subscribers?
Can merchants refund subscribers?
refund(sub_id, amount) to transfer tokens from your wallet back to the subscriber. The merchant authorizes the transfer (it’s your own funds). Partial refunds are supported - specify any amount. The refund is recorded on-chain as a RefundIssued event, creating a verifiable receipt.What is a keeper?
What is a keeper?
charge() function for due subscriptions. The function is permissionless - anyone can call it, but only the merchant receives the payment. Options:- Dashboard keeper: Built-in auto-billing in the Vowena dashboard
- Standalone bot: Run the keeper from
sdk/keeper/ - Your own: Build custom billing logic using the SDK
- Third-party: Anyone can run a keeper service
Can I run my own keeper?
Can I run my own keeper?
sdk/keeper/src/index.ts. Configure it with your contract ID and a funded Stellar keypair, then run it on a schedule. See the Keeper Setup guide for details.How does the Universal Subscription Manager affect me?
How does the Universal Subscription Manager affect me?
cancel() is a public contract function anyway, this just provides a better UX for it. Transparent cancellation builds subscriber trust.Technical
Why does charge() pre-check balance and allowance?
Why does charge() pre-check balance and allowance?
transfer_from() panics (insufficient balance or allowance), the entire transaction reverts - including any state changes the contract made before the call. This means the contract couldn’t record failed_at or emit a ChargeFailed event.By checking token.balance() and token.allowance() before calling transfer_from(), the contract can:- Record the failure timestamp (
failed_at) - Emit a
ChargeFailedevent - Return
falsegracefully - Trigger the grace period state machine
How does the single-signature auth tree work?
How does the single-signature auth tree work?
subscribe(), the contract internally calls token.approve(). In Soroban’s authorization model, sub-contract calls that require the same caller’s auth are bundled into an auth tree. The subscriber’s wallet sees both authorizations (the contract call and the token approval) and signs them as a single transaction. One signature, two authorizations.What are the contract's storage limits?
What are the contract's storage limits?
- Instance storage (shared, limited): admin address, plan/subscription ID counters
- Persistent storage (per-entry, restorable): each plan, each subscription, and index vectors (merchant→plans, subscriber→subs, plan→subs)
What if a persistent entry gets archived?
What if a persistent entry gets archived?
extend_ttl() function exists to proactively prevent archival.How large is the contract?
How large is the contract?