Recurring Billing & Subscriptions
Automate Monero billing with deterministic subscription lifecycle, configurable grace periods, and pre-payment support.
Last updated: 2026-04-28
Overview
GhostBill is the only Monero payment processor with a full recurring billing engine. Unlike traditional payment processors that rely on card-on-file authorization, Monero subscriptions work through a pull-based model: GhostBill generates invoices at each billing cycle, and customers pay each invoice independently.
This design preserves Monero's core privacy property — each payment uses a fresh subaddress, unlinkable to previous payments on the blockchain.
Subscription Lifecycle
Subscriptions move through 5 deterministic states:
active— billing is current, last invoice was paidpaused— billing suspended by merchant, no new invoices generatedpast_due— current invoice unpaid, within grace periodcancelled— terminated by merchant or customer, access continues until period endexpired— grace period exhausted, subscription ended
Every state transition fires a webhook event with the full subscription payload. Transitions are deterministic — the same input always produces the same output.
Create a Customer
Subscriptions require a customer record. Use external_id to link to your own user database:
curl -X POST /v1/customers \
-H "Authorization: Bearer gb_live_..." \
-H "Content-Type: application/json" \
-d '{
"external_id": "user-42",
"metadata": {"email_hash": "sha256:a1b2c3...", "plan": "pro"}
}'
# {"id": "cust_...", "external_id": "user-42", ...}Create a Subscription
curl -X POST /v1/subscriptions \
-H "Authorization: Bearer gb_live_..." \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cust_...",
"amount_xmr": "0.1",
"interval": "monthly",
"description": "Pro plan - monthly",
"grace_period_hours": 72,
"metadata": {"plan": "pro"}
}'This immediately generates the first invoice. The customer pays to the provided subaddress. On confirmation, the subscription becomes active and next_billing_atis set to exactly one interval from the billing anchor.
Supported intervals: daily, weekly, monthly, yearly. Billing anchors prevent date drift — a monthly subscription created on the 15th always renews on the 15th.
Automated Renewals
When next_billing_at arrives, GhostBill automatically:
- Creates a new invoice with a fresh subaddress
- Fires
subscription.renewedwebhook - Waits for payment within the grace period
- On payment confirmation, fires
subscription.payment_confirmed - Sets next
next_billing_atto the next interval
The renewal log is accessible via GET /v1/subscriptions/:id/renewal-log and provides the complete billing history with cursor pagination.
Grace Periods
The grace_period_hours parameter controls how long GhostBill waits for payment before expiring a subscription. When a renewal invoice goes unpaid:
- Subscription moves to
past_duestatus subscription.past_duewebhook fires — use this to warn the customer- If paid within grace period: subscription returns to
active - If grace period expires: subscription moves to
expired
A typical grace period is 72 hours (3 days). Set to 0 for immediate expiration.
Pause & Resume
# Pause
curl -X POST /v1/subscriptions/sub_.../pause \
-H "Authorization: Bearer gb_live_..."
# Resume (generates new invoice immediately)
curl -X POST /v1/subscriptions/sub_.../resume \
-H "Authorization: Bearer gb_live_..."Pausing stops invoice generation. Resuming creates a new invoice immediately and resets the billing anchor to the current date. The complete billing history is preserved.
Pre-Payment
Customers can pay for future billing periods in advance:
curl -X POST /v1/subscriptions/sub_.../prepay \
-H "Authorization: Bearer gb_live_..." \
-H "Content-Type: application/json" \
-d '{"periods": 3}'
# Creates a single invoice for 3x the monthly amount
# On payment: next_billing_at advances by 3 monthsWebhook Events
Subscription-related webhook events (10 total):
subscription.created— new subscription createdsubscription.renewed— renewal invoice generatedsubscription.payment_confirmed— renewal payment confirmedsubscription.past_due— payment overdue, within grace periodsubscription.expired— grace period exhaustedsubscription.cancelled— cancelled by merchantsubscription.updated— amount or metadata changedsubscription.paused— billing pausedsubscription.resumed— billing resumedsubscription.prepaid— pre-payment invoice created
All events include the full subscription payload with current invoice, customer reference, and billing history. See the API Reference for payload schemas.
Related Pages
- API Reference — full endpoint documentation
- Pricing — recurring billing available from Starter tier
- VPN Provider Guide — real-world subscription example
- GhostBill vs BTCPay Server — recurring billing comparison
Ready to deploy?
Open Core — backend API is free and open source. Dashboard licenses start at $49/month. Zero transaction fees.