Subscription
Recurring payment subscriptions with automatic renewal
Pending
Anchor 0.32
Program ID
AqkVLdxNgW5Hw7BEzzTiKME3rnWLLspWhMqKcWsgiqGR
Repository
ExpertVagabond/solana-subscription
Binary Size
246K
Cluster
Devnet
Instructions
IX
create_plan
Creates a new subscription plan with a price, billing duration, and name.
| Parameter | Type | Description |
|---|---|---|
price | u64 | Token amount charged per billing period |
duration | i64 | Length of each billing period in seconds |
name | String | Plan name (max 32 characters) |
IX
subscribe
Subscribes to a plan, paying the first billing period and creating a subscription record.
| Parameter | Type | Description |
|---|---|---|
| No parameters | ||
IX
renew
Renews an expired subscription by paying for the next billing period.
| Parameter | Type | Description |
|---|---|---|
| No parameters | ||
IX
cancel
Cancels an active subscription. The subscription remains valid until the current period expires.
| Parameter | Type | Description |
|---|---|---|
| No parameters | ||
Accounts
Plan
| Field | Type | Description |
|---|---|---|
authority | Pubkey | Plan creator who receives payments |
mint | Pubkey | Token mint used for payments |
name | String | Name of the subscription plan |
price | u64 | Cost per billing period |
duration | i64 | Billing period length in seconds |
active_subs | u64 | Number of currently active subscriptions |
bump | u8 | PDA bump seed |
Subscription
| Field | Type | Description |
|---|---|---|
plan | Pubkey | The plan this subscription is for |
subscriber | Pubkey | Wallet of the subscriber |
start_ts | i64 | Timestamp when the subscription started |
expires_at | i64 | Timestamp when the current period expires |
active | bool | Whether the subscription is active |
bump | u8 | PDA bump seed |
PDA Derivation
plan
seeds = [b"plan", authority, mint]
subscription
seeds = [b"subscription", plan, subscriber]
vault
seeds = [b"vault", plan]
Error Codes
NameTooLong
Plan name exceeds the maximum 32 character limit
AlreadyActive
The subscription is still active and cannot be renewed yet
SubscriptionExpired
The subscription has expired and must be renewed
NotExpired
Cannot renew a subscription that has not yet expired
Overflow
Arithmetic overflow in billing calculation
Usage Example
import { Program, BN } from "@coral-xyz/anchor"; import { PublicKey } from "@solana/web3.js"; // Create a monthly plan at 10 USDC const [planPda] = PublicKey.findProgramAddressSync( [Buffer.from("plan"), authority.publicKey.toBuffer(), usdcMint.toBuffer()], program.programId ); await program.methods .createPlan( new BN(10_000_000), // 10 USDC (6 decimals) new BN(30 * 86400), // 30 days "Pro Monthly" ) .accounts({ plan: planPda, authority: authority.publicKey, mint: usdcMint, }) .signers([authority]) .rpc(); // Subscribe to the plan const [subPda] = PublicKey.findProgramAddressSync( [Buffer.from("subscription"), planPda.toBuffer(), subscriber.publicKey.toBuffer()], program.programId ); await program.methods .subscribe() .accounts({ plan: planPda, subscription: subPda, subscriber: subscriber.publicKey, mint: usdcMint, }) .signers([subscriber]) .rpc();