Repository navigation
[Payments] : Support Subscription Billing and Tier-Based Relay Access #673
Description
Problem
Nostream currently supports one-time pay-to-relay admission, not recurring subscription billing.
Today, a user pays a Lightning invoice once, gets is_admitted = true permanently, and keeps write access forever. There is no plan lifecycle, no renewal flow, no grace period, and no tiered benefits tied to payment.
What exists but is incomplete:
- One-time admission invoices only (
feeSchedule: admission) - Permanent admission flag in
users.is_admitted - Global retention and rate limits not tied to paid status
- Kind 402 notifications only on payment, not for renewal or expiry
- No admin view for subscribers, revenue, or dunning ([Admin Console] Phase 6: Payments and Admissions View #636)
This is enough for a simple paid relay gate, but not for relay operators who want recurring billing with plans, renewals, and tiered access.
This is relay-operator billing (users pay the relay for access). It is not the same as creator subscriptions (NIP-88).
Solution
Add a subscription billing layer on top of the existing Lightning payment flow:
- Define subscription plans in settings
- Store subscription state in PostgreSQL (
user_subscriptions, extendedinvoices) - Reuse
PaymentsServicefor renewal invoices - Add a
SubscriptionWorkerfor renewals, expiry, and grace handling - Enforce write access, retention, and rate limits based on active plan
- Notify subscribers via extended kind 402 events
- Expose plan and status info through NIP-11 and HTTP API
- Extend the admin console for subscriber and payment operations ([Admin Console] Phase 6: Payments and Admissions View #636, [Admin Console] Phase 7: Webhooks and Notifications #637)
Existing admitted users will be migrated to a grandfathered plan so current access is preserved.
Scope
Database and settings
- Add
subscription_plansanduser_subscriptionstables - Extend
invoiceswithplan_id,period_start,period_end,subscription_id - Add
payments.subscriptionPlans[]to settings (amount, interval, grace, benefits) - Migration for existing
is_admittedusers
Subscription core
SubscriptionServicefor subscribe, renew, cancel, and status transitionsSubscriptionWorkerfor renewal invoice generation and expiry handling- Subscription lifecycle:
active -> renewal_pending -> past_due -> expired(+ cancel at period end)
Enforcement
- Replace boolean
is_admittedcheck with active subscription inevent-message-handler - Tier-based retention, rate limits, and connection limits per plan
- Tier-aware purge in maintenance worker
API and user-facing
POST /subscriptions,GET /subscriptions/status- Extend kind 402 with subscription tags (
status,plan_id,period_end,bolt11) - Extend NIP-11 relay info with plans and access requirements
- Extend
resources/invoices.htmlfor subscription checkout and status
Admin console
- Subscriber list, invoice status, and manual override ([Admin Console] Phase 6: Payments and Admissions View #636)
- Webhooks for renewal due, past due, and expired ([Admin Console] Phase 7: Webhooks and Notifications #637)
- Settings editor support for
subscriptionPlans[]([Admin Console] Phase 3: Visual Settings Editor #633)
NIPs involved
Reuse (already in Nostream):
- NIP-01 — base protocol, NOTICE/CLOSED messages
- NIP-11 — relay info, plans, payment requirements
- NIP-40 — expiration on membership events
- NIP-47 — NWC invoice creation
- Kind 402 — invoice and subscription status events
Align with drafts:
Out of scope for v1:
- NIP-88 (creator zap subscriptions)
- NIP-57 (zap renewals)
- NIP-61 / Cashu
- Publication metering via
charge_user()
Key files to extend
payments-service.ts— extend period on invoice confirm, not permanent admitevent-message-handler.ts— subscription write gatemaintenance-worker.ts— renewal/expiry cronuser-repository.ts— subscription CRUDroot-request-handler.ts— NIP-11 plan advertisementresources/invoices.html— subscription UI
Success criteria
- Operator can define multiple plans with different benefits
- Subscriber gets a renewal invoice before period ends
- Expired subscriptions lose write access
- Kind 402 notifies renewal due, past due, and expired states
- NIP-11 advertises available plans
- Admin can view and manage subscribers
- Existing admitted users migrate without losing access
CC: @cameri
Activity
Ferryx349 commentedon Jul 8, 2026
@cameri does this plan to looks good, or I have missed something??
Priyanshubhartistm commentedon Jul 8, 2026
Hi @Ferryx349 , Cameri and I actually discussed this exact feature recently, and it's already in my project scope. I'll be starting work on the subscription billing layer soon.
Anshumancanrock commentedon Jul 8, 2026
Hi @Ferryx349 , this idea is already included in my SoB project proposal as a bonus deliverable. I discussed it with mentor, and he approved the scope. I've actually already started working on it for Phase 2.
Ferryx349 commentedon Jul 8, 2026
@Anshumancanrock @Priyanshubhartistm I think there may have been a misunderstanding somewhere. I’ve just pushed the initial groundwork that I had already completed in #674. It’s only the basic foundation, and we can build on top of it once it’s decided who will be taking this forward.
Until then, I’ll hold off on any further work to avoid any overlap.
Thanks :)