How It Works

The full lifecycle of a Cron Protocol subscription.

Overview

Cron Protocol replaces the traditional pull-payment model (where merchants custody funds) with an on-chain approval model. Subscribers grant a token allowance to CronRegistry. When a charge is due, any keeper can call charge() to execute the payment atomically.

Step 1 — Merchant Creates a Plan

The merchant calls CronRegistry.createPlan() (or uses the SDK/dashboard) to register a plan on-chain. A plan defines:

  • Token — ERC-20 to charge (e.g. USDC)
  • Amount — charge amount per interval
  • Interval — billing period in seconds
  • Grace period — days before expiry after a failed charge
  • Metadata URI — JSON with name, description, features
  • Agent compatible — whether AI agents can subscribe autonomously

Plans are identified by a uint256 planId and are owned by the merchant's address. Plans can be paused but not deleted.

Step 2 — Subscriber Approves & Subscribes

To subscribe, the user approves a token allowance to CronRegistry and callssubscribe(planId). This records their subscription on-chain and optionally mints a CronNFT as a subscription identity token.

The subscriber's funds stay in their wallet — no deposit is taken at subscription time.

[i] Allowance strategy

The reference implementation approves type(uint256).max so the keeper can charge on schedule without re-approval. You can also set a finite allowance if you prefer.

Step 3 — Keepers Charge On Schedule

Any wallet running the keeper software monitors the chain for subscriptions whosenextChargeAt timestamp has passed. The keeper calls charge(planId, subscriber)or batches multiple charges via CronKeeper.batchCharge().

The charge flow is atomic:

  1. Verify subscription is active and charge is due
  2. Transfer amount from subscriber to PaymentRouter
  3. PaymentRouter distributes: 98.5% to merchant, 1% to treasury, 0.5% to keeper
  4. Update lastChargedAt and emit Charged event

Step 4 — Failed Charges & Grace Period

If a subscriber has insufficient balance or has revoked their allowance, the charge fails. The subscription enters a PastDue state. The keeper retries within the grace period. After the grace period expires with no successful charge, the subscription becomes Expired.

Step 5 — Cancellation

Subscribers cancel at any time by calling cancel(planId). This sets their subscription to Cancelled and they will not be charged again. Revoking the token allowance also effectively stops future charges.

Contract Architecture

ContractRole
CronRegistryCore: stores plans, subscriptions, executes charges
PaymentRouterSplits each charge between merchant, treasury, keeper
CronNFTERC-721 subscription identity token (optional)
PlanFactoryValidated plan creation helper
AgentBudgetManagerSpending caps for AI agent wallets
CronKeeperOn-chain batch charge helper
PaymentLinkOne-time payment links with optional MPP charge support