Підготовка контенту платформи Ring
Підготовка контенту платформи Ring
Підготовка контенту платформи Ring
Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Filter this page with Founder / Developer in the docs sidebar. Founders learn what each provider costs and how to set fees; developers get the architecture, provider module contracts, and cron pipeline details.
SubscriptionConductor (v1, Phase S4) is Ring Platform's multi-provider membership subscription billing system. One SSOT ledger (subscription_ledger) tracks all subscriber state regardless of payment method. Six provider modules implement a shared SubscriptionProviderModule contract, and five cron pipelines keep subscriptions current.
Implementation: lib/payments/subscription/.
Your platform earns recurring revenue through membership subscriptions — with zero platform fees on internal methods (credit balance, RING token, NFT gate). Choose which gateways to enable, set fee pass-through, and watch net revenue in the admin dashboard.
| Provider | Details | Gateway | Status |
|---|---|---|---|
| Credit Balance | auto-deduct from internal fiat USD credits | Credit Points | ✅ Live |
| WayForPay | Card (hosted page) + recToken recurring (regularApi) | WayForPay (UAH) | ✅ Live |
| Stripe | Stripe Subscriptions API (Phase S3) | Stripe (USD) | ✅ Live (Phase S3) |
| Native Token | on-chain Solana recurring via Membership.sol | Native Token (RING) | ✅ Live (Phase S6) |
| NFT Gate | soulbound certificate 12-month gate | NFT Certificate | 🟡 Phase S7 (stub) |
| PayPal | PayPal recurring billing | PayPal (USD) | 🟡 Phase S8 (stub) |
Each gateway deducts its own fee. Internal methods (credit balance, RING token, NFT gate) charge 0% — every dollar goes to your platform.
| Provider | Fee % | Fixed Fee | Currency |
|---|---|---|---|
| WayForPay | 2.5% | — | UAH |
| Stripe | 2.9% | $0.30 | USD |
| Credit Balance | 0% | — | USD |
| Native Token | 0% | — | RING (Tokens) |
| NFT Gate | 0% | — | RING |
| PayPal | 2.9% | $0.30 | USD |
Net revenue formula: net = gross - (gross × feePercent / 100) - feeFixed. The calculateNetRevenue() function in subscription-config.ts computes this server-side; the admin dashboard displays gross, fee, and net per subscription.
All provider settings live in ring-config.json under payment.gateways:
cardPaymentProcessor — default card gateway (wayforpay or stripe). Override per-deployment with PAYMENT_MEMBERSHIP_PROCESSOR=stripe.supportedMethods — providers shown to users at checkout.futureMethods — providers tagged as "Coming Soon" in the UI.gateways.<provider>.feePercent — percentage fee deducted before your net revenue.Superadmins access /admin/subscriptions for:
/api/admin/subscriptions/stats returns total_active, due_for_payment, breakdowns by_provider and by_method.calculateNetRevenue() is called per row so founders see real take-home amounts after gateway fees.Filter this page with Founder / Developer in the docs sidebar. Founders learn what each provider costs and how to set fees; developers get the architecture, provider module contracts, and cron pipeline details.
SubscriptionConductor (v1, Phase S4) is Ring Platform's multi-provider membership subscription billing system. One SSOT ledger (subscription_ledger) tracks all subscriber state regardless of payment method. Six provider modules implement a shared SubscriptionProviderModule contract, and five cron pipelines keep subscriptions current.
Implementation: lib/payments/subscription/.
Your platform earns recurring revenue through membership subscriptions — with zero platform fees on internal methods (credit balance, RING token, NFT gate). Choose which gateways to enable, set fee pass-through, and watch net revenue in the admin dashboard.
| Provider | Details | Gateway | Status |
|---|---|---|---|
| Credit Balance | auto-deduct from internal fiat USD credits | Credit Points | ✅ Live |
| WayForPay | Card (hosted page) + recToken recurring (regularApi) | WayForPay (UAH) | ✅ Live |
| Stripe | Stripe Subscriptions API (Phase S3) | Stripe (USD) | ✅ Live (Phase S3) |
| Native Token | on-chain Solana recurring via Membership.sol | Native Token (RING) | ✅ Live (Phase S6) |
| NFT Gate | soulbound certificate 12-month gate | NFT Certificate | 🟡 Phase S7 (stub) |
| PayPal | PayPal recurring billing | PayPal (USD) | 🟡 Phase S8 (stub) |
Each gateway deducts its own fee. Internal methods (credit balance, RING token, NFT gate) charge 0% — every dollar goes to your platform.
| Provider | Fee % | Fixed Fee | Currency |
|---|---|---|---|
| WayForPay | 2.5% | — | UAH |
| Stripe | 2.9% | $0.30 | USD |
| Credit Balance | 0% | — | USD |
| Native Token | 0% | — | RING (Tokens) |
| NFT Gate | 0% | — | RING |
| PayPal | 2.9% | $0.30 | USD |
Net revenue formula: net = gross - (gross × feePercent / 100) - feeFixed. The calculateNetRevenue() function in subscription-config.ts computes this server-side; the admin dashboard displays gross, fee, and net per subscription.
All provider settings live in ring-config.json under payment.gateways:
cardPaymentProcessor — default card gateway (wayforpay or stripe). Override per-deployment with PAYMENT_MEMBERSHIP_PROCESSOR=stripe.supportedMethods — providers shown to users at checkout.futureMethods — providers tagged as "Coming Soon" in the UI.gateways.<provider>.feePercent — percentage fee deducted before your net revenue.Superadmins access /admin/subscriptions for:
/api/admin/subscriptions/stats returns total_active, due_for_payment, breakdowns by_provider and by_method.calculateNetRevenue() is called per row so founders see real take-home amounts after gateway fees.Filter this page with Founder / Developer in the docs sidebar. Founders learn what each provider costs and how to set fees; developers get the architecture, provider module contracts, and cron pipeline details.
SubscriptionConductor (v1, Phase S4) is Ring Platform's multi-provider membership subscription billing system. One SSOT ledger (subscription_ledger) tracks all subscriber state regardless of payment method. Six provider modules implement a shared SubscriptionProviderModule contract, and five cron pipelines keep subscriptions current.
Implementation: lib/payments/subscription/.
Your platform earns recurring revenue through membership subscriptions — with zero platform fees on internal methods (credit balance, RING token, NFT gate). Choose which gateways to enable, set fee pass-through, and watch net revenue in the admin dashboard.
| Provider | Details | Gateway | Status |
|---|---|---|---|
| Credit Balance | auto-deduct from internal fiat USD credits | Credit Points | ✅ Live |
| WayForPay | Card (hosted page) + recToken recurring (regularApi) | WayForPay (UAH) | ✅ Live |
| Stripe | Stripe Subscriptions API (Phase S3) | Stripe (USD) | ✅ Live (Phase S3) |
| Native Token | on-chain Solana recurring via Membership.sol | Native Token (RING) | ✅ Live (Phase S6) |
| NFT Gate | soulbound certificate 12-month gate | NFT Certificate | 🟡 Phase S7 (stub) |
| PayPal | PayPal recurring billing | PayPal (USD) | 🟡 Phase S8 (stub) |
Each gateway deducts its own fee. Internal methods (credit balance, RING token, NFT gate) charge 0% — every dollar goes to your platform.
| Provider | Fee % | Fixed Fee | Currency |
|---|---|---|---|
| WayForPay | 2.5% | — | UAH |
| Stripe | 2.9% | $0.30 | USD |
| Credit Balance | 0% | — | USD |
| Native Token | 0% | — | RING (Tokens) |
| NFT Gate | 0% | — | RING |
| PayPal | 2.9% | $0.30 | USD |
Net revenue formula: net = gross - (gross × feePercent / 100) - feeFixed. The calculateNetRevenue() function in subscription-config.ts computes this server-side; the admin dashboard displays gross, fee, and net per subscription.
All provider settings live in ring-config.json under payment.gateways:
cardPaymentProcessor — default card gateway (wayforpay or stripe). Override per-deployment with PAYMENT_MEMBERSHIP_PROCESSOR=stripe.supportedMethods — providers shown to users at checkout.futureMethods — providers tagged as "Coming Soon" in the UI.gateways.<provider>.feePercent — percentage fee deducted before your net revenue.Superadmins access /admin/subscriptions for:
/api/admin/subscriptions/stats returns total_active, due_for_payment, breakdowns by_provider and by_method.calculateNetRevenue() is called per row so founders see real take-home amounts after gateway fees.paypalSubscriptionProviderproviders/subscription-provider-stubs.ts |
Credit Balance, Stripe, WayForPay, and Native Token have full implementations. NFT Gate and PayPal are stubs.
Phase S7 (planned): NFT Gate — soulbound 12-month membership certificate.
Phase S8 (planned): PayPal recurring billing integration.
SSOT collection: subscription_ledger. Schema defined in lib/payments/subscription/subscription-ledger-schema.ts (Zod).
Key fields:
| Field | Type | Description |
|---|---|---|
id | string | Ledger row ID (sub_<ts>_<userIdSuffix>) |
user_id | string | Owner user ID |
provider | enum | stripe, wayforpay, credit_balance, native_token, nft_gate, paypal |
gateway | string | Human-readable label (e.g. "Stripe", "WayForPay") |
method | enum | card, credit_balance, crypto, nft |
status | enum | active, expired, cancelled, suspended, grace_period |
amount | number | Subscription price (minor units) |
currency | string | Billing currency |
gateway_fee_percent | number | Percentage fee (e.g. 2.9) |
gateway_fee_fixed | number | Fixed fee in minor units (e.g. 30 for Stripe) |
stripe_subscription_id | string? | Stripe reference (if Stripe provider) |
wayforpay_rec_token | string? | WayForPay recurring token |
solana_tx_signature | string? | On-chain transaction signature |
nft_mint_address | string? | NFT certificate mint address |
start_time | number | Subscription start (ms epoch) |
next_payment_due | number | Next payment due timestamp |
failed_attempts | number | Consecutive payment failures (max 3 → auto-expiry) |
auto_renew | boolean | Auto-renew flag |
total_paid | string | Lifetime total paid |
payments_count | number | Successful payment count |
SubscriptionConductor (lib/payments/subscription/subscription-conductor.ts) exposes:
| Operation | Signature | Description |
|---|---|---|
createSubscription | (input: CreateSubscriptionInput) → CreateSubscriptionResult | Route to provider module, insert ledger row |
cancelSubscription | (userId, provider, gatewayRef?) → CancelSubscriptionResult | Cancel at provider + mark ledger rows cancelled |
renewSubscription | (userId, provider, gatewayRef?) → RenewSubscriptionResult | Renew at provider + update ledger |
getSubscription | (userId) → SubscriptionLedgerRow | null | Latest active subscription for user |
getSubscriptions | (filter) → SubscriptionLedgerRow[] | Query by user, provider, status, method, due window |
getStats | () → SubscriptionStats | Aggregate counts by status, provider, method |
calculateNetRevenue | (row) → { gross, fee, net, currency } | Per-row net revenue |
| Method | Path | Purpose | Auth |
|---|---|---|---|
POST | /api/membership/subscription/create | Create subscription via conductor | Session |
GET | /api/membership/subscription/status | Get subscription status + balance | Session |
POST | /api/membership/subscription/cancel | Cancel subscription | Session |
POST | /api/membership/payment/token | Process native token payment | Session |
POST | /api/membership/payment/credit | Process credit balance payment | Session |
GET | /api/membership/payment/credit | Get credit balance pricing info | Session |
GET | /api/admin/subscriptions | List all subscriptions | Superadmin |
GET | /api/admin/subscriptions/stats | Aggregated stats | Superadmin |
Five cron pipelines registered in lib/processes/registry.ts under the membership category:
| Pipeline ID | Cron Path | Handler | Schedule |
|---|---|---|---|
subscription-expiry-check | /api/cron/subscription-expiry | runSubscriptionExpiryCheck | Daily midnight |
credit-balance-monthly | /api/cron/credit-balance-monthly | runCreditBalanceMonthly | Hourly |
subscription-payment | /api/cron/subscription-payment | runSubscriptionPaymentCheck | Daily 2am |
solana-batch-payment | /api/cron/solana-batch-payment | runSolanaBatchPayment | Daily 3am |
nft-gate-expiry | /api/cron/nft-gate-expiry | runNftGateExpiry | Daily 4am |
Pipelines are triggered via HTTP cron jobs hitting the cronPath endpoints. Handlers import from lib/processes/subscription/:
expiry-check.ts — marks overdue subscriptions as expired and downgrades user rolescredit-balance-monthly.ts — deducts monthly fee from user credit balancesubscription-payment.ts — processes Stripe/WayForPay recurring chargessolana-nft-stubs.ts — batch RING token transfers and NFT gate expirySubscriptionProviderModule contract in providers/<name>-subscription.tssubscription-conductor.ts providerRegistry Mapring-config.json payment.gateways.<provider>SUBSCRIPTION_PROVIDERS array in subscription-ledger-schema.tsgetMembershipPaymentOptions() in subscription-config.tslib/processes/subscription/5 smoke test suites exercise the full subscription pipeline (AI-RING/scripts/):
| Suite | Prefix | Coverage |
|---|---|---|
smoke-subscription-conductor.cts | smk39_ | 13 pipelines (conductor create/cancel/renew, ledger SSOT, Stripe API, WayForPay, config) |
smoke-subscription-cron.cts | smk40_ | 5 cron pipelines (expiry, credit, payment, solana, nft) |
smoke-subscription-cron-http.cts | smk41_ | 5 HTTP cron routes with CRON_SECRET auth |
smoke-subscription-stripe.cts | smk39_ | Stripe API + webhook (customer, price, subscription, cancel, dispatch, zod) |
smoke-subscription-admin.cts | smk42_ | Admin dashboard list + stats endpoints |
Run via scripts/run-all-smokes.sh. Canonical pipeline registry: PIPELINES.md.
{
"payment": {
"cardPaymentProcessor": "wayforpay",
"supportedMethods": ["wayforpay", "credit_balance", "native_token"],
"futureMethods": ["stripe", "paypal", "nft_gate"],
"gateways": {
"wayforpay": { "enabled": true, "feePercent": 2.5, "currency": "UAH" },
"stripe": { "enabled": false, "feePercent": 2.9, "feeFixedCents": 30, "currency": "USD" },
"credit_balance": { "enabled": true, "feePercent": 0, "currency": "USD" },
"native_token": { "enabled": true, "feePercent": 0, "currency": "RING", "label": "Tokens" },
"paypal": { "enabled": false, "feePercent": 2.9, "feeFixedCents": 30, "currency": "USD" },
"nft_gate": { "enabled": false, "feePercent": 0, "currency": "RING", "label": "NFT Certificate" }
}
}
}
Membership upgrade / checkout
↓
lib/payments/subscription/subscription-conductor.ts
↓
Provider modules: stripe | wayforpay | credit_balance | native_token | nft_gate | paypal
↓
subscription_ledger (PostgreSQL — provider-agnostic SSOT)
↓
Cron pipelines: expiry + payment + credit-balance + solana-batch + nft-gate
PAYMENT_MEMBERSHIP_PROCESSOR=wayforpay # Override card gateway for membership
WAYFORPAY_MERCHANT_ACCOUNT=your_merchant
WAYFORPAY_SECRET_KEY=your_secret
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...paypalSubscriptionProviderproviders/subscription-provider-stubs.ts |
Credit Balance, Stripe, WayForPay, and Native Token have full implementations. NFT Gate and PayPal are stubs.
Phase S7 (planned): NFT Gate — soulbound 12-month membership certificate.
Phase S8 (planned): PayPal recurring billing integration.
SSOT collection: subscription_ledger. Schema defined in lib/payments/subscription/subscription-ledger-schema.ts (Zod).
Key fields:
| Field | Type | Description |
|---|---|---|
id | string | Ledger row ID (sub_<ts>_<userIdSuffix>) |
user_id | string | Owner user ID |
provider | enum | stripe, wayforpay, credit_balance, native_token, nft_gate, paypal |
gateway | string | Human-readable label (e.g. "Stripe", "WayForPay") |
method | enum | card, credit_balance, crypto, nft |
status | enum | active, expired, cancelled, suspended, grace_period |
amount | number | Subscription price (minor units) |
currency | string | Billing currency |
gateway_fee_percent | number | Percentage fee (e.g. 2.9) |
gateway_fee_fixed | number | Fixed fee in minor units (e.g. 30 for Stripe) |
stripe_subscription_id | string? | Stripe reference (if Stripe provider) |
wayforpay_rec_token | string? | WayForPay recurring token |
solana_tx_signature | string? | On-chain transaction signature |
nft_mint_address | string? | NFT certificate mint address |
start_time | number | Subscription start (ms epoch) |
next_payment_due | number | Next payment due timestamp |
failed_attempts | number | Consecutive payment failures (max 3 → auto-expiry) |
auto_renew | boolean | Auto-renew flag |
total_paid | string | Lifetime total paid |
payments_count | number | Successful payment count |
SubscriptionConductor (lib/payments/subscription/subscription-conductor.ts) exposes:
| Operation | Signature | Description |
|---|---|---|
createSubscription | (input: CreateSubscriptionInput) → CreateSubscriptionResult | Route to provider module, insert ledger row |
cancelSubscription | (userId, provider, gatewayRef?) → CancelSubscriptionResult | Cancel at provider + mark ledger rows cancelled |
renewSubscription | (userId, provider, gatewayRef?) → RenewSubscriptionResult | Renew at provider + update ledger |
getSubscription | (userId) → SubscriptionLedgerRow | null | Latest active subscription for user |
getSubscriptions | (filter) → SubscriptionLedgerRow[] | Query by user, provider, status, method, due window |
getStats | () → SubscriptionStats | Aggregate counts by status, provider, method |
calculateNetRevenue | (row) → { gross, fee, net, currency } | Per-row net revenue |
| Method | Path | Purpose | Auth |
|---|---|---|---|
POST | /api/membership/subscription/create | Create subscription via conductor | Session |
GET | /api/membership/subscription/status | Get subscription status + balance | Session |
POST | /api/membership/subscription/cancel | Cancel subscription | Session |
POST | /api/membership/payment/token | Process native token payment | Session |
POST | /api/membership/payment/credit | Process credit balance payment | Session |
GET | /api/membership/payment/credit | Get credit balance pricing info | Session |
GET | /api/admin/subscriptions | List all subscriptions | Superadmin |
GET | /api/admin/subscriptions/stats | Aggregated stats | Superadmin |
Five cron pipelines registered in lib/processes/registry.ts under the membership category:
| Pipeline ID | Cron Path | Handler | Schedule |
|---|---|---|---|
subscription-expiry-check | /api/cron/subscription-expiry | runSubscriptionExpiryCheck | Daily midnight |
credit-balance-monthly | /api/cron/credit-balance-monthly | runCreditBalanceMonthly | Hourly |
subscription-payment | /api/cron/subscription-payment | runSubscriptionPaymentCheck | Daily 2am |
solana-batch-payment | /api/cron/solana-batch-payment | runSolanaBatchPayment | Daily 3am |
nft-gate-expiry | /api/cron/nft-gate-expiry | runNftGateExpiry | Daily 4am |
Pipelines are triggered via HTTP cron jobs hitting the cronPath endpoints. Handlers import from lib/processes/subscription/:
expiry-check.ts — marks overdue subscriptions as expired and downgrades user rolescredit-balance-monthly.ts — deducts monthly fee from user credit balancesubscription-payment.ts — processes Stripe/WayForPay recurring chargessolana-nft-stubs.ts — batch RING token transfers and NFT gate expirySubscriptionProviderModule contract in providers/<name>-subscription.tssubscription-conductor.ts providerRegistry Mapring-config.json payment.gateways.<provider>SUBSCRIPTION_PROVIDERS array in subscription-ledger-schema.tsgetMembershipPaymentOptions() in subscription-config.tslib/processes/subscription/5 smoke test suites exercise the full subscription pipeline (AI-RING/scripts/):
| Suite | Prefix | Coverage |
|---|---|---|
smoke-subscription-conductor.cts | smk39_ | 13 pipelines (conductor create/cancel/renew, ledger SSOT, Stripe API, WayForPay, config) |
smoke-subscription-cron.cts | smk40_ | 5 cron pipelines (expiry, credit, payment, solana, nft) |
smoke-subscription-cron-http.cts | smk41_ | 5 HTTP cron routes with CRON_SECRET auth |
smoke-subscription-stripe.cts | smk39_ | Stripe API + webhook (customer, price, subscription, cancel, dispatch, zod) |
smoke-subscription-admin.cts | smk42_ | Admin dashboard list + stats endpoints |
Run via scripts/run-all-smokes.sh. Canonical pipeline registry: PIPELINES.md.
{
"payment": {
"cardPaymentProcessor": "wayforpay",
"supportedMethods": ["wayforpay", "credit_balance", "native_token"],
"futureMethods": ["stripe", "paypal", "nft_gate"],
"gateways": {
"wayforpay": { "enabled": true, "feePercent": 2.5, "currency": "UAH" },
"stripe": { "enabled": false, "feePercent": 2.9, "feeFixedCents": 30, "currency": "USD" },
"credit_balance": { "enabled": true, "feePercent": 0, "currency": "USD" },
"native_token": { "enabled": true, "feePercent": 0, "currency": "RING", "label": "Tokens" },
"paypal": { "enabled": false, "feePercent": 2.9, "feeFixedCents": 30, "currency": "USD" },
"nft_gate": { "enabled": false, "feePercent": 0, "currency": "RING", "label": "NFT Certificate" }
}
}
}
Membership upgrade / checkout
↓
lib/payments/subscription/subscription-conductor.ts
↓
Provider modules: stripe | wayforpay | credit_balance | native_token | nft_gate | paypal
↓
subscription_ledger (PostgreSQL — provider-agnostic SSOT)
↓
Cron pipelines: expiry + payment + credit-balance + solana-batch + nft-gate
PAYMENT_MEMBERSHIP_PROCESSOR=wayforpay # Override card gateway for membership
WAYFORPAY_MERCHANT_ACCOUNT=your_merchant
WAYFORPAY_SECRET_KEY=your_secret
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...paypalSubscriptionProviderproviders/subscription-provider-stubs.ts |
Credit Balance, Stripe, WayForPay, and Native Token have full implementations. NFT Gate and PayPal are stubs.
Phase S7 (planned): NFT Gate — soulbound 12-month membership certificate.
Phase S8 (planned): PayPal recurring billing integration.
SSOT collection: subscription_ledger. Schema defined in lib/payments/subscription/subscription-ledger-schema.ts (Zod).
Key fields:
| Field | Type | Description |
|---|---|---|
id | string | Ledger row ID (sub_<ts>_<userIdSuffix>) |
user_id | string | Owner user ID |
provider | enum | stripe, wayforpay, credit_balance, native_token, nft_gate, paypal |
gateway | string | Human-readable label (e.g. "Stripe", "WayForPay") |
method | enum | card, credit_balance, crypto, nft |
status | enum | active, expired, cancelled, suspended, grace_period |
amount | number | Subscription price (minor units) |
currency | string | Billing currency |
gateway_fee_percent | number | Percentage fee (e.g. 2.9) |
gateway_fee_fixed | number | Fixed fee in minor units (e.g. 30 for Stripe) |
stripe_subscription_id | string? | Stripe reference (if Stripe provider) |
wayforpay_rec_token | string? | WayForPay recurring token |
solana_tx_signature | string? | On-chain transaction signature |
nft_mint_address | string? | NFT certificate mint address |
start_time | number | Subscription start (ms epoch) |
next_payment_due | number | Next payment due timestamp |
failed_attempts | number | Consecutive payment failures (max 3 → auto-expiry) |
auto_renew | boolean | Auto-renew flag |
total_paid | string | Lifetime total paid |
payments_count | number | Successful payment count |
SubscriptionConductor (lib/payments/subscription/subscription-conductor.ts) exposes:
| Operation | Signature | Description |
|---|---|---|
createSubscription | (input: CreateSubscriptionInput) → CreateSubscriptionResult | Route to provider module, insert ledger row |
cancelSubscription | (userId, provider, gatewayRef?) → CancelSubscriptionResult | Cancel at provider + mark ledger rows cancelled |
renewSubscription | (userId, provider, gatewayRef?) → RenewSubscriptionResult | Renew at provider + update ledger |
getSubscription | (userId) → SubscriptionLedgerRow | null | Latest active subscription for user |
getSubscriptions | (filter) → SubscriptionLedgerRow[] | Query by user, provider, status, method, due window |
getStats | () → SubscriptionStats | Aggregate counts by status, provider, method |
calculateNetRevenue | (row) → { gross, fee, net, currency } | Per-row net revenue |
| Method | Path | Purpose | Auth |
|---|---|---|---|
POST | /api/membership/subscription/create | Create subscription via conductor | Session |
GET | /api/membership/subscription/status | Get subscription status + balance | Session |
POST | /api/membership/subscription/cancel | Cancel subscription | Session |
POST | /api/membership/payment/token | Process native token payment | Session |
POST | /api/membership/payment/credit | Process credit balance payment | Session |
GET | /api/membership/payment/credit | Get credit balance pricing info | Session |
GET | /api/admin/subscriptions | List all subscriptions | Superadmin |
GET | /api/admin/subscriptions/stats | Aggregated stats | Superadmin |
Five cron pipelines registered in lib/processes/registry.ts under the membership category:
| Pipeline ID | Cron Path | Handler | Schedule |
|---|---|---|---|
subscription-expiry-check | /api/cron/subscription-expiry | runSubscriptionExpiryCheck | Daily midnight |
credit-balance-monthly | /api/cron/credit-balance-monthly | runCreditBalanceMonthly | Hourly |
subscription-payment | /api/cron/subscription-payment | runSubscriptionPaymentCheck | Daily 2am |
solana-batch-payment | /api/cron/solana-batch-payment | runSolanaBatchPayment | Daily 3am |
nft-gate-expiry | /api/cron/nft-gate-expiry | runNftGateExpiry | Daily 4am |
Pipelines are triggered via HTTP cron jobs hitting the cronPath endpoints. Handlers import from lib/processes/subscription/:
expiry-check.ts — marks overdue subscriptions as expired and downgrades user rolescredit-balance-monthly.ts — deducts monthly fee from user credit balancesubscription-payment.ts — processes Stripe/WayForPay recurring chargessolana-nft-stubs.ts — batch RING token transfers and NFT gate expirySubscriptionProviderModule contract in providers/<name>-subscription.tssubscription-conductor.ts providerRegistry Mapring-config.json payment.gateways.<provider>SUBSCRIPTION_PROVIDERS array in subscription-ledger-schema.tsgetMembershipPaymentOptions() in subscription-config.tslib/processes/subscription/5 smoke test suites exercise the full subscription pipeline (AI-RING/scripts/):
| Suite | Prefix | Coverage |
|---|---|---|
smoke-subscription-conductor.cts | smk39_ | 13 pipelines (conductor create/cancel/renew, ledger SSOT, Stripe API, WayForPay, config) |
smoke-subscription-cron.cts | smk40_ | 5 cron pipelines (expiry, credit, payment, solana, nft) |
smoke-subscription-cron-http.cts | smk41_ | 5 HTTP cron routes with CRON_SECRET auth |
smoke-subscription-stripe.cts | smk39_ | Stripe API + webhook (customer, price, subscription, cancel, dispatch, zod) |
smoke-subscription-admin.cts | smk42_ | Admin dashboard list + stats endpoints |
Run via scripts/run-all-smokes.sh. Canonical pipeline registry: PIPELINES.md.
{
"payment": {
"cardPaymentProcessor": "wayforpay",
"supportedMethods": ["wayforpay", "credit_balance", "native_token"],
"futureMethods": ["stripe", "paypal", "nft_gate"],
"gateways": {
"wayforpay": { "enabled": true, "feePercent": 2.5, "currency": "UAH" },
"stripe": { "enabled": false, "feePercent": 2.9, "feeFixedCents": 30, "currency": "USD" },
"credit_balance": { "enabled": true, "feePercent": 0, "currency": "USD" },
"native_token": { "enabled": true, "feePercent": 0, "currency": "RING", "label": "Tokens" },
"paypal": { "enabled": false, "feePercent": 2.9, "feeFixedCents": 30, "currency": "USD" },
"nft_gate": { "enabled": false, "feePercent": 0, "currency": "RING", "label": "NFT Certificate" }
}
}
}
Membership upgrade / checkout
↓
lib/payments/subscription/subscription-conductor.ts
↓
Provider modules: stripe | wayforpay | credit_balance | native_token | nft_gate | paypal
↓
subscription_ledger (PostgreSQL — provider-agnostic SSOT)
↓
Cron pipelines: expiry + payment + credit-balance + solana-batch + nft-gate
PAYMENT_MEMBERSHIP_PROCESSOR=wayforpay # Override card gateway for membership
WAYFORPAY_MERCHANT_ACCOUNT=your_merchant
WAYFORPAY_SECRET_KEY=your_secret
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...