OpportunitiesEntities
Docs
    Ring Platform

    Decentralized Self-building Future

    Sign In
    Entities
    Opportunities
    Store
    Docs
    Platform Concepts
    RING EconomySonoratek LLCGlobal ImpactAI Meets Web3
    Get Started
    Quick StartCalculatorRoadmap
    Privacy|Contact
    v1.104.17|Sonoratek LLC

    Documentation

    Concepts, value, and typical clone scenarios — less code.

    Welcome to Ring
    Quick Reference
    Getting Started
    Prerequisites
    Installation
    First Success Validation
    Next Steps
    Features
    Multi-Vendor Store
    Inventory & Stock
    Vendor Management
    Commissions & Settlements
    SubscriptionConductor
    PaymentConductor
    Ring Oracle
    Payments Overview
    Public Pools & DAO Jars
    WayForPay Payment Integration
    Wallet & Credit System
    WalletConductor
    Affiliate & Referral Enablement
    Referral Codes (Refcodes)
    NFT Exhibition Marketplace
    Solana NFT Gates
    Token Staking System
    Owner Project Lab
    Entities
    Opportunities
    Real-Time Messaging
    Ring Tasks
    WebRTC Calls & STUNner TURN
    Peer Games
    News Module
    Member Blogs
    Public Profile Pages
    Profile Account Widgets
    Ring File Cabinet
    Username Reservation System
    Scientific Editor
    Notifications
    Push Notifications with FCM (Ring-Powered)
    Email AI-CRM
    Ring Mailer & RingdomX Mail
    Tunnel Protocol
    VideoConductor
    MediaConductor
    Generative Gallery
    Authentication
    Security & Compliance
    Admin console
    Admin Wiki
    Manage via Telegram
    Locale System
    Mobile Experience
    Performance Optimization Patterns
    Examples
    Quick Start
    Basic Setup
    White Label
    Custom Branding
    Web3 Integration
    Real World
    Advanced Features
    Customization
    Quick Start — Your First Ring Clone
    Customization Guide
    Vertical Presets (SSOT)
    Ringization playbook
    Branding
    Themes
    Features
    Localization
    Token Economics Setup
    Payment Gateway Integration
    Reference Ring deployments
    Project configuration
    Public environment variables
    Order Lab secrets
    WalletConnect Project ID (Reown Cloud)
    Supported services
    NODUS wiki (project knowledge)
    Configuration playbook
    Web3
    Token launch jurisdictions
    Wallet
    Wallet Security Tips
    Integrations
    Ethereum wallets (Wagmi v3)
    RingFileBase (object storage API)
    Ring CDN (RingFileBase edge)
    Deployment
    Self-hosted deployment
    Vercel Deployment
    Docker
    Environment Configuration
    Monitoring & Analytics
    Performance Optimization
    Backup & Recovery
    Architecture
    Data Model
    Security
    Real Time
    Discovery Mutation Sync
    PaymentConductor architecture
    WalletConductor architecture
    Backend Services
    Firebase Integration
    Development
    Ring MCP Server

    Quick entry (CTOs · auditors · agents)

    Welcome — mission & audiences
    Quick Reference
    Getting started
    Architecture & Auth.js
    Backend modes & databases (DB_BACKEND_MODE)
    Self-hosted
    Ring MCP Tools
    Ring MCP Server
    Token economics
    Token launch jurisdictions
    Deploy (Docker · k8s)
    Security & compliance reads
    ringdom.org — LegioX homebase
    Source — MIT license (GitHub)

    Documentation

    Concepts, value, and typical clone scenarios — less code.

    Welcome to Ring
    Quick Reference
    Getting Started
    Prerequisites
    Installation
    First Success Validation
    Next Steps
    Features
    Multi-Vendor Store
    Inventory & Stock
    Vendor Management
    Commissions & Settlements
    SubscriptionConductor
    PaymentConductor
    Ring Oracle
    Payments Overview
    Public Pools & DAO Jars
    WayForPay Payment Integration
    Wallet & Credit System
    WalletConductor
    Affiliate & Referral Enablement
    Referral Codes (Refcodes)
    NFT Exhibition Marketplace
    Solana NFT Gates
    Token Staking System
    Owner Project Lab
    Entities
    Opportunities
    Real-Time Messaging
    Ring Tasks
    WebRTC Calls & STUNner TURN
    Peer Games
    News Module
    Member Blogs
    Public Profile Pages
    Profile Account Widgets
    Ring File Cabinet
    Username Reservation System
    Scientific Editor
    Notifications
    Push Notifications with FCM (Ring-Powered)
    Email AI-CRM
    Ring Mailer & RingdomX Mail
    Tunnel Protocol
    VideoConductor
    MediaConductor
    Generative Gallery
    Authentication
    Security & Compliance
    Admin console
    Admin Wiki
    Manage via Telegram
    Locale System
    Mobile Experience
    Performance Optimization Patterns
    Examples
    Quick Start
    Basic Setup
    White Label
    Custom Branding
    Web3 Integration
    Real World
    Advanced Features
    Customization
    Quick Start — Your First Ring Clone
    Customization Guide
    Vertical Presets (SSOT)
    Ringization playbook
    Branding
    Themes
    Features
    Localization
    Token Economics Setup
    Payment Gateway Integration
    Reference Ring deployments
    Project configuration
    Public environment variables
    Order Lab secrets
    WalletConnect Project ID (Reown Cloud)
    Supported services
    NODUS wiki (project knowledge)
    Configuration playbook
    Web3
    Token launch jurisdictions
    Wallet
    Wallet Security Tips
    Integrations
    Ethereum wallets (Wagmi v3)
    RingFileBase (object storage API)
    Ring CDN (RingFileBase edge)
    Deployment
    Self-hosted deployment
    Vercel Deployment
    Docker
    Environment Configuration
    Monitoring & Analytics
    Performance Optimization
    Backup & Recovery
    Architecture
    Data Model
    Security
    Real Time
    Discovery Mutation Sync
    PaymentConductor architecture
    WalletConductor architecture
    Backend Services
    Firebase Integration
    Development
    Ring MCP Server

    Quick entry (CTOs · auditors · agents)

    Welcome — mission & audiences
    Quick Reference
    Getting started
    Architecture & Auth.js
    Backend modes & databases (DB_BACKEND_MODE)
    Self-hosted
    Ring MCP Tools
    Ring MCP Server
    Token economics
    Token launch jurisdictions
    Deploy (Docker · k8s)
    Security & compliance reads
    ringdom.org — LegioX homebase
    Source — MIT license (GitHub)

    Documentation

    Concepts, value, and typical clone scenarios — less code.

    Welcome to Ring
    Quick Reference
    Getting Started
    Prerequisites
    Installation
    First Success Validation
    Next Steps
    Features
    Multi-Vendor Store
    Inventory & Stock
    Vendor Management
    Commissions & Settlements
    SubscriptionConductor
    PaymentConductor
    Ring Oracle
    Payments Overview
    Public Pools & DAO Jars
    WayForPay Payment Integration
    Wallet & Credit System
    WalletConductor
    Affiliate & Referral Enablement
    Referral Codes (Refcodes)
    NFT Exhibition Marketplace
    Solana NFT Gates
    Token Staking System
    Owner Project Lab
    Entities
    Opportunities
    Real-Time Messaging
    Ring Tasks
    WebRTC Calls & STUNner TURN
    Peer Games
    News Module
    Member Blogs
    Public Profile Pages
    Profile Account Widgets
    Ring File Cabinet
    Username Reservation System
    Scientific Editor
    Notifications
    Push Notifications with FCM (Ring-Powered)
    Email AI-CRM
    Ring Mailer & RingdomX Mail
    Tunnel Protocol
    VideoConductor
    MediaConductor
    Generative Gallery
    Authentication
    Security & Compliance
    Admin console
    Admin Wiki
    Manage via Telegram
    Locale System
    Mobile Experience
    Performance Optimization Patterns
    Examples
    Quick Start
    Basic Setup
    White Label
    Custom Branding
    Web3 Integration
    Real World
    Advanced Features
    Customization
    Quick Start — Your First Ring Clone
    Customization Guide
    Vertical Presets (SSOT)
    Ringization playbook
    Branding
    Themes
    Features
    Localization
    Token Economics Setup
    Payment Gateway Integration
    Reference Ring deployments
    Project configuration
    Public environment variables
    Order Lab secrets
    WalletConnect Project ID (Reown Cloud)
    Supported services
    NODUS wiki (project knowledge)
    Configuration playbook
    Web3
    Token launch jurisdictions
    Wallet
    Wallet Security Tips
    Integrations
    Ethereum wallets (Wagmi v3)
    RingFileBase (object storage API)
    Ring CDN (RingFileBase edge)
    Deployment
    Self-hosted deployment
    Vercel Deployment
    Docker
    Environment Configuration
    Monitoring & Analytics
    Performance Optimization
    Backup & Recovery
    Architecture
    Data Model
    Security
    Real Time
    Discovery Mutation Sync
    PaymentConductor architecture
    WalletConductor architecture
    Backend Services
    Firebase Integration
    Development
    Ring MCP Server

    Quick entry (CTOs · auditors · agents)

    Welcome — mission & audiences
    Quick Reference
    Getting started
    Architecture & Auth.js
    Backend modes & databases (DB_BACKEND_MODE)
    Self-hosted
    Ring MCP Tools
    Ring MCP Server
    Token economics
    Token launch jurisdictions
    Deploy (Docker · k8s)
    Security & compliance reads
    ringdom.org — LegioX homebase
    Source — MIT license (GitHub)
    Ring Logo

    Loading documentation...

    Preparing Ring content

    Ring Logo

    Loading documentation...

    Preparing Ring content

    Ring Logo

    Loading documentation...

    Preparing Ring content

    Payments Overview

    Status: PaymentConductor is the live money SSOT for store, membership one-shots, news promotion, wallet credit top-up, confidential native onramp, and public-pool (DAO jar) card/PayPal chip-ins. Recurring membership PayPal uses SubscriptionConductor (Subscriptions v1) — not a separate cart API. Use Founder / Developer tabs in the docs sidebar to filter this page.

    Ring routes buyer rails (card | paypal | credit_balance | native_token) through PaymentConductor (lib/payments/conductor/). The card rail settles via WayForPay or Stripe (payment.cardPaymentProcessor / purpose env) — UI never picks a PSP id. Browser handoff is Conductor CheckoutRedirect (navigate | form_post) via followCheckoutResult. Rates and presentment come from Ring Oracle.

    Previous / common assumptionRing equivalent
    Brand-named checkout buttons (WayForPay / Stripe) in UIRail card → Conductor resolves processor
    Generic /api/cart/* checkout RESTNo cart payment REST — store UI uses Server Action placeAndPayStoreOrder → PaymentConductor.createCheckout
    Optional REST by railPOST /api/store/payments/{card|wayforpay|stripe|credit|token|paypal} (same Conductor SSOT)
    Hosted PSP “Donate” products for jarsPurpose public_pool_contribution + desk oracle — see Public Pools
    Recurring membership on PaymentConductor Orders onlyOne-shot Orders here; Subscriptions v1 on SubscriptionConductor

    Rails comparison

    RailTypical processorStore entryGateway fee (config)Notes
    cardWayForPay or StripeAction + POST …/card (alias) / …/wayforpay / …/stripeWFP ~2.5% · Stripe ~2.9% + fixedPrimary Ukraine = WayForPay HPP (form_post)
    paypalPayPal Orders v2Action + POST …/paypal~2.9% + fixed when enabledNeeds NEXT_PUBLIC_PAYMENT_STORE_ALLOW_PAYPAL=true + gateways.paypal.enabled + PAYPAL_*
    credit_balanceInternalAction + POST …/credit0%Fiat credit ledger; gated by PAYMENT_STORE_ALLOW_CREDIT / gateway

    Canonical PSP webhooks (settlement): POST /api/payments/{wayforpay,stripe,paypal}/webhook. Money truth for WayForPay: serviceUrl Approved settles — browser returnUrl is UX only.

    What PaymentConductor covers

    PurposeBuyer outcomeTypical rails / PSP
    store_orderCart → paid ordercard / credit / native_token / paypal
    membership_upgradeRole upgrade one-shotcard / native / paypal (recurring → SubscriptionConductor)
    news_promotionSponsored newscard (WFP / Stripe)
    wallet_topupFiat credit pointscard (PAYMENT_WALLET_TOPUP_PROCESSOR) or paypal
    native_token_onrampCard/PayPal → treasury nativeConfidential+ when CONFIDENTIAL_TOKEN_ONRAMP=true
    public_pool_contributionDAO jar chip-in

    Extended purposes (project_order, task_escrow, collective_order_slot, scheduled_service_slot) share the same Conductor — details on PaymentConductor.

    Membership native pay is membership_upgrade + native_token through PaymentConductor (soft launch: treasury SPL + ledger; deployed: on-chain RingMembership), then SubscriptionConductor ledger-only via metadata.tx_hash — see SubscriptionConductor. Its gate is payment.supportedMethods (isPaymentMethodEnabled('native_token')), not PAYMENT_STORE_ALLOW_TOKEN.

    Idempotency: native pay (store + membership) follows the shared contract — one client idempotencyKey per intent; paid rows replay (same txHash), in-flight rows return 409 IDEMPOTENCY_IN_FLIGHT.

    Native refunds: POST /api/admin/payments/[orderReference]/refund (platform admin or owning vendor; full-amount, idempotent, marks payment_transactions refunded).

    Not PSP donation products

    WayForPay hosted Донати, Stripe submit_type=donate, and PayPal Donate SDK are not Ring jar SSOT. Use Public Pools.

    Recommended path

    Skill / desk: Cursor + Ring docs cluster — start from operator checklist Payment Gateway Integration, then deep-dive PaymentConductor.

    Starter prompt (does not mutate until you approve env/config changes):

    Configure this clone’s PaymentConductor: set PAYMENT_DEFAULT_PROCESSOR, WayForPay or Stripe credentials from env.local.template, enable store rails (card + optional credit/token/PayPal flags), register https://YOUR_HOST/api/payments/{processor}/webhook, and verify store checkout uses placeAndPayStoreOrder + CheckoutRedirect — no /api/cart payment routes.

    Inputs checklist: clone host · ring-config.json payment.* · PSP cabinet credentials · webhook URL reachable from the internet · data/migrations/004_payment_transactions.sql applied.

    Manual path

    1. 1

      Choose card processor and rails

      Set payment.cardPaymentProcessor (wayforpay or stripe) and payment.gateways.*.enabled in ring-config.json. Optional per-purpose env: PAYMENT_STORE_PROCESSOR, PAYMENT_MEMBERSHIP_PROCESSOR, PAYMENT_NEWS_PROCESSOR, PAYMENT_WALLET_TOPUP_PROCESSOR, PAYMENT_PUBLIC_POOL_CONTRIBUTION_PROCESSOR, PAYMENT_NATIVE_TOKEN_ONRAMP_PROCESSOR.

    2. 2

      Fill credentials from templates

      Copy WayForPay / Stripe / PayPal keys from env.local.template (also docker.env.template). WayForPay SSOT: WAYFORPAY_MERCHANT_ACCOUNT, WAYFORPAY_SECRET_KEY, WAYFORPAY_MERCHANT_PASSWORD, WAYFORPAY_DOMAIN, WAYFORPAY_API_URL — no WAYFORPAY_MERCHANT_ID.

    3. 3

      Enable optional store rails

      • Credit: keep PAYMENT_STORE_ALLOW_CREDIT / NEXT_PUBLIC_PAYMENT_STORE_ALLOW_CREDIT from disabling credit.
      • Native token: PAYMENT_STORE_ALLOW_TOKEN=true and NEXT_PUBLIC_PAYMENT_STORE_ALLOW_TOKEN=true.
      • PayPal: NEXT_PUBLIC_PAYMENT_STORE_ALLOW_PAYPAL=true, gateways.paypal.enabled: true, plus PAYPAL_CLIENT_ID / PAYPAL_CLIENT_SECRET / PAYPAL_WEBHOOK_ID / PAYPAL_MODE.
    4. 4

      Register webhooks and migrate ledger

      Register cabinet callbacks to /api/payments/wayforpay/webhook (and Stripe/PayPal twins). Apply 004_payment_transactions.sql before production traffic.

    5. 5

      Smoke-test browser handoff

      Place a store order (card rail). Expect CheckoutRedirect — WayForPay HPP via POST form, not a GET query URL. Confirm settlement only after webhook Approved / capture — not on return URL alone.

    Why this matters for your clone

    One ledger

    payment_transactions covers store, membership one-shots, news, wallet top-up, and DAO jar chip-ins.

    Ukraine-first card

    WayForPay HPP keeps PCI scope at the PSP; Stripe for international clones.

    Wallet credit vs RING

    Card top-up adds fiat credit points — not on-chain RING. Desk / onramp are separate paths.

    Membership recurring

    PayPal Subscriptions v1 + manage page at .

    Implementation

    Store place-and-pay → Conductor → webhook

    Key modules

    ModulePathRole
    Conductorlib/payments/conductor/payment-conductor.tscreateCheckout by purpose + rail/processor
    Types (rail vs PSP)lib/payments/conductor/types.tsPaymentRail, PaymentPurpose, CheckoutRedirect
    Configlib/payments/payment.config.tsgetPaymentProvider, isRailEnabled, purpose env map
    Checkout handofflib/payments/checkout-redirect.ts

    Frequently asked questions

    Impact

    Will my clone need a separate cart payment microservice?

    No. Store checkout places the order and pays through PaymentConductor (Server Action or the store payment routes above). There is no fabricated cart checkout REST API.

    Does enabling PayPal change the card processor?

    No. PayPal is its own rail. Card still resolves to WayForPay or Stripe independently.

    Migration

    We used to document brand buttons in the UI — what now?

    Switch copy and components to rails (card / paypal / credit_balance / native_token). Keep processor selection in config/env. See PaymentConductor.

    How do recurring memberships migrate off one-shot Orders?

    Use SubscriptionConductor (PayPal Subscriptions v1, Stripe Subscriptions, WayForPay regularApi, credit, native, NFT gate). PaymentConductor still owns one-shot membership upgrades and store Orders.

    Ops

    Why did the member return from HPP without credit/order paid?

    For WayForPay, settlement is serviceUrl webhook Approved — not returnUrl. Check cabinet webhook URL, HMAC secrets, and dispatcher logs.

    Where do founders see payments in admin?

    User detail Payments tab → GET /api/admin/users/[id]/payments (membership / wallet top-up and other ledger rows).

    Related documentation

    Related documentation

    PaymentConductor

    Deep-dive: purposes, rails vs processors, handlers, and module paths.

    WayForPay Payment Integration

    Depends-on: WayForPay HPP env SSOT, HMAC, and returnUrl vs serviceUrl money truth.

    Wallet & Credit System

    Same-workflow: wallet_topup credit points vs desk/onramp native paths.

    SubscriptionConductor

    Next-step: recurring membership SubscriptionConductor (PayPal Subscriptions v1).

    Payments Overview

    Status: PaymentConductor is the live money SSOT for store, membership one-shots, news promotion, wallet credit top-up, confidential native onramp, and public-pool (DAO jar) card/PayPal chip-ins. Recurring membership PayPal uses SubscriptionConductor (Subscriptions v1) — not a separate cart API. Use Founder / Developer tabs in the docs sidebar to filter this page.

    Ring routes buyer rails (card | paypal | credit_balance | native_token) through PaymentConductor (lib/payments/conductor/). The card rail settles via WayForPay or Stripe (payment.cardPaymentProcessor / purpose env) — UI never picks a PSP id. Browser handoff is Conductor CheckoutRedirect (navigate | form_post) via followCheckoutResult. Rates and presentment come from Ring Oracle.

    Previous / common assumptionRing equivalent
    Brand-named checkout buttons (WayForPay / Stripe) in UIRail card → Conductor resolves processor
    Generic /api/cart/* checkout RESTNo cart payment REST — store UI uses Server Action placeAndPayStoreOrder → PaymentConductor.createCheckout
    Optional REST by railPOST /api/store/payments/{card|wayforpay|stripe|credit|token|paypal} (same Conductor SSOT)
    Hosted PSP “Donate” products for jarsPurpose public_pool_contribution + desk oracle — see Public Pools
    Recurring membership on PaymentConductor Orders onlyOne-shot Orders here; Subscriptions v1 on SubscriptionConductor

    Rails comparison

    RailTypical processorStore entryGateway fee (config)Notes
    cardWayForPay or StripeAction + POST …/card (alias) / …/wayforpay / …/stripeWFP ~2.5% · Stripe ~2.9% + fixedPrimary Ukraine = WayForPay HPP (form_post)
    paypalPayPal Orders v2Action + POST …/paypal~2.9% + fixed when enabledNeeds NEXT_PUBLIC_PAYMENT_STORE_ALLOW_PAYPAL=true + gateways.paypal.enabled + PAYPAL_*
    credit_balanceInternalAction + POST …/credit0%Fiat credit ledger; gated by PAYMENT_STORE_ALLOW_CREDIT / gateway

    Canonical PSP webhooks (settlement): POST /api/payments/{wayforpay,stripe,paypal}/webhook. Money truth for WayForPay: serviceUrl Approved settles — browser returnUrl is UX only.

    What PaymentConductor covers

    PurposeBuyer outcomeTypical rails / PSP
    store_orderCart → paid ordercard / credit / native_token / paypal
    membership_upgradeRole upgrade one-shotcard / native / paypal (recurring → SubscriptionConductor)
    news_promotionSponsored newscard (WFP / Stripe)
    wallet_topupFiat credit pointscard (PAYMENT_WALLET_TOPUP_PROCESSOR) or paypal
    native_token_onrampCard/PayPal → treasury nativeConfidential+ when CONFIDENTIAL_TOKEN_ONRAMP=true
    public_pool_contributionDAO jar chip-in

    Extended purposes (project_order, task_escrow, collective_order_slot, scheduled_service_slot) share the same Conductor — details on PaymentConductor.

    Membership native pay is membership_upgrade + native_token through PaymentConductor (soft launch: treasury SPL + ledger; deployed: on-chain RingMembership), then SubscriptionConductor ledger-only via metadata.tx_hash — see SubscriptionConductor. Its gate is payment.supportedMethods (isPaymentMethodEnabled('native_token')), not PAYMENT_STORE_ALLOW_TOKEN.

    Idempotency: native pay (store + membership) follows the shared contract — one client idempotencyKey per intent; paid rows replay (same txHash), in-flight rows return 409 IDEMPOTENCY_IN_FLIGHT.

    Native refunds: POST /api/admin/payments/[orderReference]/refund (platform admin or owning vendor; full-amount, idempotent, marks payment_transactions refunded).

    Not PSP donation products

    WayForPay hosted Донати, Stripe submit_type=donate, and PayPal Donate SDK are not Ring jar SSOT. Use Public Pools.

    Recommended path

    Skill / desk: Cursor + Ring docs cluster — start from operator checklist Payment Gateway Integration, then deep-dive PaymentConductor.

    Starter prompt (does not mutate until you approve env/config changes):

    Configure this clone’s PaymentConductor: set PAYMENT_DEFAULT_PROCESSOR, WayForPay or Stripe credentials from env.local.template, enable store rails (card + optional credit/token/PayPal flags), register https://YOUR_HOST/api/payments/{processor}/webhook, and verify store checkout uses placeAndPayStoreOrder + CheckoutRedirect — no /api/cart payment routes.

    Inputs checklist: clone host · ring-config.json payment.* · PSP cabinet credentials · webhook URL reachable from the internet · data/migrations/004_payment_transactions.sql applied.

    Manual path

    1. 1

      Choose card processor and rails

      Set payment.cardPaymentProcessor (wayforpay or stripe) and payment.gateways.*.enabled in ring-config.json. Optional per-purpose env: PAYMENT_STORE_PROCESSOR, PAYMENT_MEMBERSHIP_PROCESSOR, PAYMENT_NEWS_PROCESSOR, PAYMENT_WALLET_TOPUP_PROCESSOR, PAYMENT_PUBLIC_POOL_CONTRIBUTION_PROCESSOR, PAYMENT_NATIVE_TOKEN_ONRAMP_PROCESSOR.

    2. 2

      Fill credentials from templates

      Copy WayForPay / Stripe / PayPal keys from env.local.template (also docker.env.template). WayForPay SSOT: WAYFORPAY_MERCHANT_ACCOUNT, WAYFORPAY_SECRET_KEY, WAYFORPAY_MERCHANT_PASSWORD, WAYFORPAY_DOMAIN, WAYFORPAY_API_URL — no WAYFORPAY_MERCHANT_ID.

    3. 3

      Enable optional store rails

      • Credit: keep PAYMENT_STORE_ALLOW_CREDIT / NEXT_PUBLIC_PAYMENT_STORE_ALLOW_CREDIT from disabling credit.
      • Native token: PAYMENT_STORE_ALLOW_TOKEN=true and NEXT_PUBLIC_PAYMENT_STORE_ALLOW_TOKEN=true.
      • PayPal: NEXT_PUBLIC_PAYMENT_STORE_ALLOW_PAYPAL=true, gateways.paypal.enabled: true, plus PAYPAL_CLIENT_ID / PAYPAL_CLIENT_SECRET / PAYPAL_WEBHOOK_ID / PAYPAL_MODE.
    4. 4

      Register webhooks and migrate ledger

      Register cabinet callbacks to /api/payments/wayforpay/webhook (and Stripe/PayPal twins). Apply 004_payment_transactions.sql before production traffic.

    5. 5

      Smoke-test browser handoff

      Place a store order (card rail). Expect CheckoutRedirect — WayForPay HPP via POST form, not a GET query URL. Confirm settlement only after webhook Approved / capture — not on return URL alone.

    Why this matters for your clone

    One ledger

    payment_transactions covers store, membership one-shots, news, wallet top-up, and DAO jar chip-ins.

    Ukraine-first card

    WayForPay HPP keeps PCI scope at the PSP; Stripe for international clones.

    Wallet credit vs RING

    Card top-up adds fiat credit points — not on-chain RING. Desk / onramp are separate paths.

    Membership recurring

    PayPal Subscriptions v1 + manage page at .

    Implementation

    Store place-and-pay → Conductor → webhook

    Key modules

    ModulePathRole
    Conductorlib/payments/conductor/payment-conductor.tscreateCheckout by purpose + rail/processor
    Types (rail vs PSP)lib/payments/conductor/types.tsPaymentRail, PaymentPurpose, CheckoutRedirect
    Configlib/payments/payment.config.tsgetPaymentProvider, isRailEnabled, purpose env map
    Checkout handofflib/payments/checkout-redirect.ts

    Frequently asked questions

    Impact

    Will my clone need a separate cart payment microservice?

    No. Store checkout places the order and pays through PaymentConductor (Server Action or the store payment routes above). There is no fabricated cart checkout REST API.

    Does enabling PayPal change the card processor?

    No. PayPal is its own rail. Card still resolves to WayForPay or Stripe independently.

    Migration

    We used to document brand buttons in the UI — what now?

    Switch copy and components to rails (card / paypal / credit_balance / native_token). Keep processor selection in config/env. See PaymentConductor.

    How do recurring memberships migrate off one-shot Orders?

    Use SubscriptionConductor (PayPal Subscriptions v1, Stripe Subscriptions, WayForPay regularApi, credit, native, NFT gate). PaymentConductor still owns one-shot membership upgrades and store Orders.

    Ops

    Why did the member return from HPP without credit/order paid?

    For WayForPay, settlement is serviceUrl webhook Approved — not returnUrl. Check cabinet webhook URL, HMAC secrets, and dispatcher logs.

    Where do founders see payments in admin?

    User detail Payments tab → GET /api/admin/users/[id]/payments (membership / wallet top-up and other ledger rows).

    Related documentation

    Related documentation

    PaymentConductor

    Deep-dive: purposes, rails vs processors, handlers, and module paths.

    WayForPay Payment Integration

    Depends-on: WayForPay HPP env SSOT, HMAC, and returnUrl vs serviceUrl money truth.

    Wallet & Credit System

    Same-workflow: wallet_topup credit points vs desk/onramp native paths.

    SubscriptionConductor

    Next-step: recurring membership SubscriptionConductor (PayPal Subscriptions v1).

    Payments Overview

    Status: PaymentConductor is the live money SSOT for store, membership one-shots, news promotion, wallet credit top-up, confidential native onramp, and public-pool (DAO jar) card/PayPal chip-ins. Recurring membership PayPal uses SubscriptionConductor (Subscriptions v1) — not a separate cart API. Use Founder / Developer tabs in the docs sidebar to filter this page.

    Ring routes buyer rails (card | paypal | credit_balance | native_token) through PaymentConductor (lib/payments/conductor/). The card rail settles via WayForPay or Stripe (payment.cardPaymentProcessor / purpose env) — UI never picks a PSP id. Browser handoff is Conductor CheckoutRedirect (navigate | form_post) via followCheckoutResult. Rates and presentment come from Ring Oracle.

    Previous / common assumptionRing equivalent
    Brand-named checkout buttons (WayForPay / Stripe) in UIRail card → Conductor resolves processor
    Generic /api/cart/* checkout RESTNo cart payment REST — store UI uses Server Action placeAndPayStoreOrder → PaymentConductor.createCheckout
    Optional REST by railPOST /api/store/payments/{card|wayforpay|stripe|credit|token|paypal} (same Conductor SSOT)
    Hosted PSP “Donate” products for jarsPurpose public_pool_contribution + desk oracle — see Public Pools
    Recurring membership on PaymentConductor Orders onlyOne-shot Orders here; Subscriptions v1 on SubscriptionConductor

    Rails comparison

    RailTypical processorStore entryGateway fee (config)Notes
    cardWayForPay or StripeAction + POST …/card (alias) / …/wayforpay / …/stripeWFP ~2.5% · Stripe ~2.9% + fixedPrimary Ukraine = WayForPay HPP (form_post)
    paypalPayPal Orders v2Action + POST …/paypal~2.9% + fixed when enabledNeeds NEXT_PUBLIC_PAYMENT_STORE_ALLOW_PAYPAL=true + gateways.paypal.enabled + PAYPAL_*
    credit_balanceInternalAction + POST …/credit0%Fiat credit ledger; gated by PAYMENT_STORE_ALLOW_CREDIT / gateway

    Canonical PSP webhooks (settlement): POST /api/payments/{wayforpay,stripe,paypal}/webhook. Money truth for WayForPay: serviceUrl Approved settles — browser returnUrl is UX only.

    What PaymentConductor covers

    PurposeBuyer outcomeTypical rails / PSP
    store_orderCart → paid ordercard / credit / native_token / paypal
    membership_upgradeRole upgrade one-shotcard / native / paypal (recurring → SubscriptionConductor)
    news_promotionSponsored newscard (WFP / Stripe)
    wallet_topupFiat credit pointscard (PAYMENT_WALLET_TOPUP_PROCESSOR) or paypal
    native_token_onrampCard/PayPal → treasury nativeConfidential+ when CONFIDENTIAL_TOKEN_ONRAMP=true
    public_pool_contributionDAO jar chip-in

    Extended purposes (project_order, task_escrow, collective_order_slot, scheduled_service_slot) share the same Conductor — details on PaymentConductor.

    Membership native pay is membership_upgrade + native_token through PaymentConductor (soft launch: treasury SPL + ledger; deployed: on-chain RingMembership), then SubscriptionConductor ledger-only via metadata.tx_hash — see SubscriptionConductor. Its gate is payment.supportedMethods (isPaymentMethodEnabled('native_token')), not PAYMENT_STORE_ALLOW_TOKEN.

    Idempotency: native pay (store + membership) follows the shared contract — one client idempotencyKey per intent; paid rows replay (same txHash), in-flight rows return 409 IDEMPOTENCY_IN_FLIGHT.

    Native refunds: POST /api/admin/payments/[orderReference]/refund (platform admin or owning vendor; full-amount, idempotent, marks payment_transactions refunded).

    Not PSP donation products

    WayForPay hosted Донати, Stripe submit_type=donate, and PayPal Donate SDK are not Ring jar SSOT. Use Public Pools.

    Recommended path

    Skill / desk: Cursor + Ring docs cluster — start from operator checklist Payment Gateway Integration, then deep-dive PaymentConductor.

    Starter prompt (does not mutate until you approve env/config changes):

    Configure this clone’s PaymentConductor: set PAYMENT_DEFAULT_PROCESSOR, WayForPay or Stripe credentials from env.local.template, enable store rails (card + optional credit/token/PayPal flags), register https://YOUR_HOST/api/payments/{processor}/webhook, and verify store checkout uses placeAndPayStoreOrder + CheckoutRedirect — no /api/cart payment routes.

    Inputs checklist: clone host · ring-config.json payment.* · PSP cabinet credentials · webhook URL reachable from the internet · data/migrations/004_payment_transactions.sql applied.

    Manual path

    1. 1

      Choose card processor and rails

      Set payment.cardPaymentProcessor (wayforpay or stripe) and payment.gateways.*.enabled in ring-config.json. Optional per-purpose env: PAYMENT_STORE_PROCESSOR, PAYMENT_MEMBERSHIP_PROCESSOR, PAYMENT_NEWS_PROCESSOR, PAYMENT_WALLET_TOPUP_PROCESSOR, PAYMENT_PUBLIC_POOL_CONTRIBUTION_PROCESSOR, PAYMENT_NATIVE_TOKEN_ONRAMP_PROCESSOR.

    2. 2

      Fill credentials from templates

      Copy WayForPay / Stripe / PayPal keys from env.local.template (also docker.env.template). WayForPay SSOT: WAYFORPAY_MERCHANT_ACCOUNT, WAYFORPAY_SECRET_KEY, WAYFORPAY_MERCHANT_PASSWORD, WAYFORPAY_DOMAIN, WAYFORPAY_API_URL — no WAYFORPAY_MERCHANT_ID.

    3. 3

      Enable optional store rails

      • Credit: keep PAYMENT_STORE_ALLOW_CREDIT / NEXT_PUBLIC_PAYMENT_STORE_ALLOW_CREDIT from disabling credit.
      • Native token: PAYMENT_STORE_ALLOW_TOKEN=true and NEXT_PUBLIC_PAYMENT_STORE_ALLOW_TOKEN=true.
      • PayPal: NEXT_PUBLIC_PAYMENT_STORE_ALLOW_PAYPAL=true, gateways.paypal.enabled: true, plus PAYPAL_CLIENT_ID / PAYPAL_CLIENT_SECRET / PAYPAL_WEBHOOK_ID / PAYPAL_MODE.
    4. 4

      Register webhooks and migrate ledger

      Register cabinet callbacks to /api/payments/wayforpay/webhook (and Stripe/PayPal twins). Apply 004_payment_transactions.sql before production traffic.

    5. 5

      Smoke-test browser handoff

      Place a store order (card rail). Expect CheckoutRedirect — WayForPay HPP via POST form, not a GET query URL. Confirm settlement only after webhook Approved / capture — not on return URL alone.

    Why this matters for your clone

    One ledger

    payment_transactions covers store, membership one-shots, news, wallet top-up, and DAO jar chip-ins.

    Ukraine-first card

    WayForPay HPP keeps PCI scope at the PSP; Stripe for international clones.

    Wallet credit vs RING

    Card top-up adds fiat credit points — not on-chain RING. Desk / onramp are separate paths.

    Membership recurring

    PayPal Subscriptions v1 + manage page at .

    Implementation

    Store place-and-pay → Conductor → webhook

    Key modules

    ModulePathRole
    Conductorlib/payments/conductor/payment-conductor.tscreateCheckout by purpose + rail/processor
    Types (rail vs PSP)lib/payments/conductor/types.tsPaymentRail, PaymentPurpose, CheckoutRedirect
    Configlib/payments/payment.config.tsgetPaymentProvider, isRailEnabled, purpose env map
    Checkout handofflib/payments/checkout-redirect.ts

    Frequently asked questions

    Impact

    Will my clone need a separate cart payment microservice?

    No. Store checkout places the order and pays through PaymentConductor (Server Action or the store payment routes above). There is no fabricated cart checkout REST API.

    Does enabling PayPal change the card processor?

    No. PayPal is its own rail. Card still resolves to WayForPay or Stripe independently.

    Migration

    We used to document brand buttons in the UI — what now?

    Switch copy and components to rails (card / paypal / credit_balance / native_token). Keep processor selection in config/env. See PaymentConductor.

    How do recurring memberships migrate off one-shot Orders?

    Use SubscriptionConductor (PayPal Subscriptions v1, Stripe Subscriptions, WayForPay regularApi, credit, native, NFT gate). PaymentConductor still owns one-shot membership upgrades and store Orders.

    Ops

    Why did the member return from HPP without credit/order paid?

    For WayForPay, settlement is serviceUrl webhook Approved — not returnUrl. Check cabinet webhook URL, HMAC secrets, and dispatcher logs.

    Where do founders see payments in admin?

    User detail Payments tab → GET /api/admin/users/[id]/payments (membership / wallet top-up and other ledger rows).

    Related documentation

    Related documentation

    PaymentConductor

    Deep-dive: purposes, rails vs processors, handlers, and module paths.

    WayForPay Payment Integration

    Depends-on: WayForPay HPP env SSOT, HMAC, and returnUrl vs serviceUrl money truth.

    Wallet & Credit System

    Same-workflow: wallet_topup credit points vs desk/onramp native paths.

    SubscriptionConductor

    Next-step: recurring membership SubscriptionConductor (PayPal Subscriptions v1).

    native_token
    On-chain
    Action + POST …/token
    0%
    Needs PAYMENT_STORE_ALLOW_TOKEN=true (+ public twin for UI)
    card / paypal → desk FX → pledged_native_token
    /membership/manage

    Operator scenarios

    • Launch UA store — WayForPay credentials + default processor; keep credit on for members; defer PayPal until PAYPAL_* is ready.
    • International card — set PAYMENT_DEFAULT_PROCESSOR=stripe (or purpose overrides); same rails UI.
    • DAO jar fundraising — enable public-pool card checkout; fees via publicPools.platformFeePercentByRole — not donation products.
    • Admin visibility — user detail Payments tab lists ledger rows (GET /api/admin/users/[id]/payments).

    ring-config.json payment section

    Symbols are examples — replace with your clone’s store.mainCurrency and tokens.nativeToken.symbol.

    UI store rails are driven by getClientStorePaymentRails() (env + gateways) — not by inventing PSP buttons.

    followCheckoutResult / followCheckoutRedirect
    Store actionapp/_actions/store-checkout-payment.tsPrimary store UI path
    Client railslib/ring-config-client.ts → getClientStorePaymentRailsCard / credit / token / paypal toggles
    Processorslib/payments/processors/*.processor.tswayforpay, stripe, paypal, credit-balance, native-token
    Dispatcherlib/payments/conductor/webhook-dispatcher.tsPurpose → handlers
    Webhooksapp/api/payments/{wayforpay,stripe,paypal}/webhookCanonical PSP callbacks

    Verified store payment routes (not cart REST)

    MethodPathRole
    —Server Action placeAndPayStoreOrderPrimary checkout UI
    POST/api/store/payments/cardCard rail alias → wayforpay route
    POST/api/store/payments/wayforpayCard via WFP processor path
    POST/api/store/payments/stripeCard via Stripe
    POST/api/store/payments/creditCredit rail
    POST/api/store/payments/tokenNative token rail
    POST/api/store/payments/paypalPayPal Orders v2
    GET/api/store/payments/[orderId]/statusProcessing poll

    There is no /api/cart/... payment surface. Cart state stays client/feature-store; money always enters via Conductor.

    Environment (excerpt)

    Templates: env.local.template, docker.env.template, docker-compose.template.yml. Ledger: data/migrations/004_payment_transactions.sql.

    PaymentConductor architecture

    Deep-dive: CheckoutRedirect DTO, idempotency, and webhook dispatcher.

    Payment Gateway Integration

    Next-step: operator PSP setup checklist for a new clone.

    Ring Oracle

    Depends-on: main_currency / native_token rates for presentment and jar FX.

    Public Pools & DAO Jars

    See-also: public_pool_contribution desk oracle — not PSP donate products.

    json
    
    {
      "payment": {
        "cardPaymentProcessor": "wayforpay",
        "supportedMethods": ["wayforpay", "credit_balance", "native_token"],
        "futureMethods": ["stripe", "paypal", "nft_gate"],
        "gateways": {
          "wayforpay": { "enabled": true, "feePercent": 2.5, "currency": "<main_currency>" },
          "stripe": { "enabled": false, "feePercent": 2.9, "feeFixedCents": 30, "currency": "<main_currency>" },
          "credit_balance": { "enabled": true, "feePercent": 0, "currency": "<main_currency>" },
          "native_token": { "enabled": true, "feePercent": 0, "currency": "<native_token_symbol>", "label": "Tokens" },
          "paypal": { "enabled": false, "feePercent": 2.9, "feeFixedCents": 30, "currency": "USD" }
        }
      }
    }
    native_token
    On-chain
    Action + POST …/token
    0%
    Needs PAYMENT_STORE_ALLOW_TOKEN=true (+ public twin for UI)
    card / paypal → desk FX → pledged_native_token
    /membership/manage

    Operator scenarios

    • Launch UA store — WayForPay credentials + default processor; keep credit on for members; defer PayPal until PAYPAL_* is ready.
    • International card — set PAYMENT_DEFAULT_PROCESSOR=stripe (or purpose overrides); same rails UI.
    • DAO jar fundraising — enable public-pool card checkout; fees via publicPools.platformFeePercentByRole — not donation products.
    • Admin visibility — user detail Payments tab lists ledger rows (GET /api/admin/users/[id]/payments).

    ring-config.json payment section

    Symbols are examples — replace with your clone’s store.mainCurrency and tokens.nativeToken.symbol.

    UI store rails are driven by getClientStorePaymentRails() (env + gateways) — not by inventing PSP buttons.

    followCheckoutResult / followCheckoutRedirect
    Store actionapp/_actions/store-checkout-payment.tsPrimary store UI path
    Client railslib/ring-config-client.ts → getClientStorePaymentRailsCard / credit / token / paypal toggles
    Processorslib/payments/processors/*.processor.tswayforpay, stripe, paypal, credit-balance, native-token
    Dispatcherlib/payments/conductor/webhook-dispatcher.tsPurpose → handlers
    Webhooksapp/api/payments/{wayforpay,stripe,paypal}/webhookCanonical PSP callbacks

    Verified store payment routes (not cart REST)

    MethodPathRole
    —Server Action placeAndPayStoreOrderPrimary checkout UI
    POST/api/store/payments/cardCard rail alias → wayforpay route
    POST/api/store/payments/wayforpayCard via WFP processor path
    POST/api/store/payments/stripeCard via Stripe
    POST/api/store/payments/creditCredit rail
    POST/api/store/payments/tokenNative token rail
    POST/api/store/payments/paypalPayPal Orders v2
    GET/api/store/payments/[orderId]/statusProcessing poll

    There is no /api/cart/... payment surface. Cart state stays client/feature-store; money always enters via Conductor.

    Environment (excerpt)

    Templates: env.local.template, docker.env.template, docker-compose.template.yml. Ledger: data/migrations/004_payment_transactions.sql.

    PaymentConductor architecture

    Deep-dive: CheckoutRedirect DTO, idempotency, and webhook dispatcher.

    Payment Gateway Integration

    Next-step: operator PSP setup checklist for a new clone.

    Ring Oracle

    Depends-on: main_currency / native_token rates for presentment and jar FX.

    Public Pools & DAO Jars

    See-also: public_pool_contribution desk oracle — not PSP donate products.

    json
    
    {
      "payment": {
        "cardPaymentProcessor": "wayforpay",
        "supportedMethods": ["wayforpay", "credit_balance", "native_token"],
        "futureMethods": ["stripe", "paypal", "nft_gate"],
        "gateways": {
          "wayforpay": { "enabled": true, "feePercent": 2.5, "currency": "<main_currency>" },
          "stripe": { "enabled": false, "feePercent": 2.9, "feeFixedCents": 30, "currency": "<main_currency>" },
          "credit_balance": { "enabled": true, "feePercent": 0, "currency": "<main_currency>" },
          "native_token": { "enabled": true, "feePercent": 0, "currency": "<native_token_symbol>", "label": "Tokens" },
          "paypal": { "enabled": false, "feePercent": 2.9, "feeFixedCents": 30, "currency": "USD" }
        }
      }
    }
    native_token
    On-chain
    Action + POST …/token
    0%
    Needs PAYMENT_STORE_ALLOW_TOKEN=true (+ public twin for UI)
    card / paypal → desk FX → pledged_native_token
    /membership/manage

    Operator scenarios

    • Launch UA store — WayForPay credentials + default processor; keep credit on for members; defer PayPal until PAYPAL_* is ready.
    • International card — set PAYMENT_DEFAULT_PROCESSOR=stripe (or purpose overrides); same rails UI.
    • DAO jar fundraising — enable public-pool card checkout; fees via publicPools.platformFeePercentByRole — not donation products.
    • Admin visibility — user detail Payments tab lists ledger rows (GET /api/admin/users/[id]/payments).

    ring-config.json payment section

    Symbols are examples — replace with your clone’s store.mainCurrency and tokens.nativeToken.symbol.

    UI store rails are driven by getClientStorePaymentRails() (env + gateways) — not by inventing PSP buttons.

    followCheckoutResult / followCheckoutRedirect
    Store actionapp/_actions/store-checkout-payment.tsPrimary store UI path
    Client railslib/ring-config-client.ts → getClientStorePaymentRailsCard / credit / token / paypal toggles
    Processorslib/payments/processors/*.processor.tswayforpay, stripe, paypal, credit-balance, native-token
    Dispatcherlib/payments/conductor/webhook-dispatcher.tsPurpose → handlers
    Webhooksapp/api/payments/{wayforpay,stripe,paypal}/webhookCanonical PSP callbacks

    Verified store payment routes (not cart REST)

    MethodPathRole
    —Server Action placeAndPayStoreOrderPrimary checkout UI
    POST/api/store/payments/cardCard rail alias → wayforpay route
    POST/api/store/payments/wayforpayCard via WFP processor path
    POST/api/store/payments/stripeCard via Stripe
    POST/api/store/payments/creditCredit rail
    POST/api/store/payments/tokenNative token rail
    POST/api/store/payments/paypalPayPal Orders v2
    GET/api/store/payments/[orderId]/statusProcessing poll

    There is no /api/cart/... payment surface. Cart state stays client/feature-store; money always enters via Conductor.

    Environment (excerpt)

    Templates: env.local.template, docker.env.template, docker-compose.template.yml. Ledger: data/migrations/004_payment_transactions.sql.

    PaymentConductor architecture

    Deep-dive: CheckoutRedirect DTO, idempotency, and webhook dispatcher.

    Payment Gateway Integration

    Next-step: operator PSP setup checklist for a new clone.

    Ring Oracle

    Depends-on: main_currency / native_token rates for presentment and jar FX.

    Public Pools & DAO Jars

    See-also: public_pool_contribution desk oracle — not PSP donate products.

    json
    
    {
      "payment": {
        "cardPaymentProcessor": "wayforpay",
        "supportedMethods": ["wayforpay", "credit_balance", "native_token"],
        "futureMethods": ["stripe", "paypal", "nft_gate"],
        "gateways": {
          "wayforpay": { "enabled": true, "feePercent": 2.5, "currency": "<main_currency>" },
          "stripe": { "enabled": false, "feePercent": 2.9, "feeFixedCents": 30, "currency": "<main_currency>" },
          "credit_balance": { "enabled": true, "feePercent": 0, "currency": "<main_currency>" },
          "native_token": { "enabled": true, "feePercent": 0, "currency": "<native_token_symbol>", "label": "Tokens" },
          "paypal": { "enabled": false, "feePercent": 2.9, "feeFixedCents": 30, "currency": "USD" }
        }
      }
    }
    1. Docs
    2. /Features
    3. /Payments Overview

    Updated Aug 22, 20267 min listen

    1. Docs
    2. /Features
    3. /Payments Overview

    Updated Aug 22, 20267 min listen

    1. Docs
    2. /Features
    3. /Payments Overview

    Updated Aug 22, 20267 min listen