Marlin’s recurring billing works differently from card-based systems. Instead of storing payment credentials, the customer signs a single on-chain transaction that delegates token authority to the Marlin program for up to a specified spending cap. After that, Marlin charges automatically on schedule — no further action required from the customer. This guide walks through creating a plan, sharing the subscription checkout URL, handling lifecycle webhooks, and managing subscriptions via the API.Documentation Index
Fetch the complete documentation index at: https://yanhgming.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Create a subscription plan
A plan defines the billing amount, currency, and interval. The
slug you provide becomes part of the hosted checkout URL, so choose something URL-safe.trialPeriodDays delays the first charge by that many days. The customer still signs the authorization transaction immediately, but the Marlin program will not attempt the first charge until the trial ends.Share the plan checkout URL
Every plan automatically has a hosted subscription checkout page. The URL follows this pattern:You can find the
publicSlug on the plan object returned by the API, or set it in the dashboard. Share this URL anywhere — email, marketing page, in-app button — and the customer can subscribe with any Solana wallet.When the customer subscribes, they:- Connect their wallet
- Choose a spending cap authorization period (6 months, 1 year, or 2 years)
- Sign one transaction on-chain
Handle subscription webhooks
Marlin posts events to your webhook endpoint as subscriptions move through their lifecycle. Use The full set of subscription event types:
verifyWebhook to validate every incoming event before acting on it.| Event | When it fires |
|---|---|
subscription.created | Customer completes the on-chain subscribe transaction |
subscription.activated | First charge succeeds (or trial starts) |
subscription.paused | Subscription is paused via API or by the customer |
subscription.resumed | Subscription resumes from paused state |
subscription.past_due | A charge attempt fails |
subscription.canceled | Subscription is canceled |
How automatic charging works
When a billing period is due, Marlin processes the charge automatically on-chain. Because the charge is triggered by a permissionless on-chain instruction, it proceeds independently — even if your server is temporarily unavailable. The payment splits atomically: 99.5% settles directly to your wallet, and 0.5% goes to the Marlin protocol fee. If a charge fails because the customer’s balance is insufficient or their authorization cap is reached, Marlin transitions the subscription topast_due and fires the subscription.past_due webhook.