Skip to main content
This guide walks through building a subscription payment system where the subscriber authorizes once and the service provider collects each billing cycle automatically via EIP-7702 account abstraction.
Concept: For the subscription model, trade-offs, and comparison to card-on-file billing, see Subscription billing.

What you’ll build

A full subscription lifecycle: the subscriber delegates and subscribes once, the provider collects on schedule (second cycle shown to prove repeat behavior), and the subscriber cancels.

Demo

Overview

Subscriber:
Service provider:

Delegate contract

Subscription billing works by delegating the subscriber’s EOA to a contract that enforces billing terms. Through EIP-7702, the subscriber’s account temporarily gains contract logic, allowing a service provider to collect payments at each billing cycle without requiring the subscriber to sign every time. You can use an existing deployed contract or deploy your own. The example below is a minimal SubscriptionManager contract that supports three operations:
  • subscribe: register billing terms for a subscriptionId.
  • collect: provider pulls the next scheduled payment for that subscriptionId.
  • cancelSubscription: subscriber revokes a specific subscription.
This contract is provided as a reference implementation for testing purposes. A delegate contract has full execution authority over the subscriber’s EOA, so in production, use an audited and verified contract. For more context on EIP-7702 delegation and security, see EIP-7702.

Configuration

Step 1: Delegate the subscriber’s EOA (EIP-7702)

The subscriber signs an EIP-7702 authorization to delegate their EOA to the SubscriptionManager. After this, the subscriber’s EOA executes the delegate contract’s logic.

Step 2: Register a subscription (subscriber)

The subscriber calls subscribe() on their own EOA. Since the EOA is delegated, this executes SubscriptionManager.subscribe.

Step 3: Collect a payment (service provider)

Each billing cycle, the service provider calls collect(subscriptionId) on the subscriber’s EOA. The delegate logic verifies the caller, billing schedule, and amount before transferring USDT0.
A collect() call costs roughly 50k-55k gas on Stable (21k base + 7702 delegation overhead + ERC-20 transfer). At a 1 gwei base fee, that’s approximately 0.000050 USDT0 per billing cycle paid by the provider.

Step 4: Cancel a subscription (subscriber)

The subscriber calls cancelSubscription(subscriptionId) on their own EOA to revoke billing access for that specific subscription.

Security model

The subscriber is authorizing the delegate contract to pull funds from their EOA. Understand exactly what that authorization covers and how to limit exposure. What the subscriber is authorizing. By delegating to SubscriptionManager, the subscriber grants the contract’s logic full execution authority over their EOA. The delegate can only transfer funds under the conditions coded into it: caller is the registered provider, the interval has elapsed, the amount matches the stored subscription. It cannot transfer to other addresses or bypass the interval check, because the contract code doesn’t allow those actions. Failure modes to mitigate.
  • Malicious delegate upgrade: if the SubscriptionManager is a proxy whose implementation can be changed by an admin, the authorization effectively trusts that admin. Delegate only to immutable contracts or proxies with transparent, time-locked upgrades.
  • Provider compromise: if the provider’s key leaks, an attacker can collect early payments up to the per-cycle amount. Subscribers should set a spendingLimit per subscription and monitor for unauthorized SubscriptionCollected events.
  • Delegation replacement: subscribing again with a different delegate wipes the subscription state. Use a modular delegate that supports multiple functions (subscription, batch payments, spending limits) under a single delegation, rather than one delegate per feature.
  • Replayable signatures: all signatures use EIP-7702 nonces tied to the subscriber’s EOA, so they can’t replay across chains or across delegations.
Recommended guardrails.
  • Audit the delegate contract before production use.
  • Keep per-subscription amounts small relative to the subscriber’s balance.
  • Monitor SubscriptionCreated / SubscriptionCollected events and surface them to the subscriber.
  • Offer the subscriber a clear “cancel” UI that calls cancelSubscription(subscriptionId) on their own EOA.

Important considerations

  • Persistent delegation: the EIP-7702 delegation persists until the subscriber explicitly changes or clears it. No re-delegation needed each billing cycle.
  • Single delegation per EOA: if the subscriber later delegates to a different contract, the subscription delegate logic is replaced and collection fails. Use a modular delegate contract that supports multiple functions (subscriptions, batch payments, spending limits, session keys) under a single delegation.
  • Schedule behavior: this example advances nextChargeAt by one interval on each successful collection. If more than one billing period has elapsed, repeated collect() calls can catch up one period at a time. Extend the logic if your product requires a different policy.
  • Use audited delegates: only delegate to contracts that have been audited.

Subscription billing concept

Understand the pull-based billing model.

Account abstraction

See how batch payments, spending limits, and session keys combine under one delegation.

EIP-7702 concept

Review the delegation model that makes this possible.
Last modified on April 23, 2026