Skip to Content
GuidesSaaS Billing

Subscription billing with Inzi

Accept recurring crypto payments for your SaaS product using Inzi payment links and metadata tracking.

Automatic recurring charges are not yet supported. Use payment links with metadata to track subscriptions manually.


curl -X POST https://api.inzilink.com/api/v1/links \ -H "Authorization: Bearer sk_live_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "title": "Pro Plan — Monthly", "amount": "29.00", "currency": "USD", "type": "subscription", "metadata": { "plan": "pro", "interval": "monthly" } }'

Share on your pricing page

Embed the payment link URL on your pricing page or send it directly to customers:

<a href="https://inzilink.com/p/your-link-code" class="btn"> Pay with Crypto — $29/mo </a>

Track payments via metadata

Each payment through the link creates a checkout. Include user_id in metadata by creating individual checkouts:

const checkout = await fetch('https://api.inzilink.com/api/v1/checkouts', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.INZI_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ amount: '29.00', currency: 'USD', description: 'Pro Plan — Monthly', metadata: { user_id: userId, plan: 'pro', interval: 'monthly', billing_period: '2026-04', }, redirect_url: `https://yourapp.com/billing/success`, webhook_url: 'https://yourapp.com/webhooks/inzi', }), })

Handle subscription webhooks

app.post('/webhooks/inzi', async (req, res) => { const event = verifyWebhook(req.body, req.headers, WEBHOOK_SECRET) if (event.event === 'checkout.completed') { const { user_id, plan, billing_period } = event.data.metadata // Extend subscription await extendSubscription(user_id, plan, billing_period) // Send receipt await sendSubscriptionReceipt(user_id, event.data.amount) } res.json({ ok: true }) })

Send renewal reminders

Since auto-charge isn’t available yet, send reminders when subscriptions are expiring:

// Cron job: check for expiring subscriptions daily const expiring = await getExpiringSubscriptions() for (const sub of expiring) { // Create a new checkout for renewal const checkout = await createCheckout({ amount: sub.plan_price, metadata: { user_id: sub.user_id, plan: sub.plan, type: 'renewal' }, }) await sendRenewalEmail(sub.user_id, checkout.checkout_url) }

  1. Create checkouts per user (not shared payment links) so metadata tracks who paid
  2. Store billing_period in metadata for reconciliation
  3. Use webhooks to auto-extend subscriptions
  4. Send renewal links via email/in-app notification before expiry