FEATURES

Subscriptions

Recurring stablecoin charges. Publish a plan, share a link, the subscriber approves the router once — Tab's executor handles every charge after that. Useful for paid Discord communities, creator memberships, SaaS billing, and recurring tips.

How it works

  1. Creator publishes a plan. From /dashboard/subscriptions, you set name, price, period (daily / weekly / monthly / quarterly / yearly) and chain. One tx publishes it on TabSubscriptionRouter.
  2. Subscriber visits the share link. At /subscribe/[planKey] they see the plan card and tap subscribe. Their wallet signs two txs: anapprove() for the lifetime allowance and one subscribe() that charges the first period.
  3. Tab cron charges each period. POST /api/cron/chargewalks active subs and submits the contract's charge(planKey, subscriber). The contract enforces lastChargedAt + period <= now so double-charging is impossible.
  4. Subscriber can cancel anytime. One on-chain tx flips the sub to inactive. Allowance revocation or zero balance also halts charges — Tab catches the revert and marks the subhalted.

Trust model

  • Funds never leave the subscriber's wallet until each charge fires. There's no escrow and no custody by Tab.
  • The router can never increase the price. Planamount and period are immutable on-chain — to change pricing, the creator publishes a new plan and migrates subscribers.
  • Anyone can call charge.The schedule, allowance check, and active-sub check live in the contract, so a malicious caller can't over-charge — only settle a legitimately-due period.
  • Protocol fee. Each charge takes a 1% fee (capped at 5% by the contract). Net goes to the creator.

Plan lifecycle

  • pending_create — staged off-chain, on-chain createPlan tx in flight.
  • active — accepting new subscribers and charges.
  • deactivated— no new subscribers; existing subscribers can still cancel but the cron won't advance their charges.

Subscription lifecycle

  • active — being charged each period.
  • cancelled — subscriber or creator stopped it. No further charges; allowance left in place until the subscriber revokes manually.
  • halted — last cron pass reverted (allowance or balance insufficient). The dashboard surfaces this so the creator can ping the subscriber to top up + resume.

Webhooks

Each lifecycle transition fires a webhook to any subscription registered for it:

  • subscription.plan_created
  • subscription.started
  • subscription.charged
  • subscription.cancelled
  • subscription.halted

Contract reference

See TabSubscriptionRouter for the full surface and audit notes.