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
    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
    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
    Branding
    Themes
    Features
    Localization
    Token Economics Setup
    Payment Gateway Integration
    Reference Ring deployments
    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
    Docker
    Environment Configuration
    Monitoring & Analytics
    Performance Optimization
    Backup & Recovery
    Architecture
    Data Model
    Security
    Real Time
    Discovery Mutation Sync
    PaymentConductor architecture
    WalletConductor architecture
    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
    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
    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
    Branding
    Themes
    Features
    Localization
    Token Economics Setup
    Payment Gateway Integration
    Reference Ring deployments
    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
    Docker
    Environment Configuration
    Monitoring & Analytics
    Performance Optimization
    Backup & Recovery
    Architecture
    Data Model
    Security
    Real Time
    Discovery Mutation Sync
    PaymentConductor architecture
    WalletConductor architecture
    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
    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
    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
    Branding
    Themes
    Features
    Localization
    Token Economics Setup
    Payment Gateway Integration
    Reference Ring deployments
    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
    Docker
    Environment Configuration
    Monitoring & Analytics
    Performance Optimization
    Backup & Recovery
    Architecture
    Data Model
    Security
    Real Time
    Discovery Mutation Sync
    PaymentConductor architecture
    WalletConductor architecture
    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)
    1. Docs
    2. /Features
    3. /Ring ERP
    4. /Inventory & Stock

    Updated Jul 23, 20263 min listen

    Ring Platform Logo

    Завантаження документації...

    Підготовка контенту платформи Ring

    1. Docs
    2. /Features
    3. /Ring ERP
    4. /Inventory & Stock

    Updated Jul 23, 20263 min listen

    Ring Platform Logo

    Завантаження документації...

    Підготовка контенту платформи Ring

    1. Docs
    2. /Features
    3. /Ring ERP
    4. /Inventory & Stock

    Updated Jul 23, 20263 min listen

    Ring Platform Logo

    Завантаження документації...

    Підготовка контенту платформи Ring

    Inventory & Stock

    Ring tracks quantity with one locked rule: product stock equals available plus reserved. Checkout sells only available. PaymentConductor paid handlers call commitSaleForOrder so fulfill and deduct stay atomic.

    Do not treat Nova Poshta /api/shipping/novapost/warehouses as ERP warehouses. ERP default: label zero-warehouse ↔ store id 1 (DEFAULT_INVENTORY_STORE_ID).

    Locked invariant

    text
    
    store_products.stock  ===  inventory_levels.available  +  inventory_levels.reserved
    sellable              ===  inventory_levels.available
    Eventstockavailablereserved
    Bootstrap / restock +q+q+q—
    Reserve q—−q+q
    Fulfill (paid) q−q—−q
    Cancel / TTL q—+q−q
    Refund restore +q+q+q—

    Wave 1 (2026-07-23): digital / instantDelivery / preorder lines skip reserve+deduct (commissions still settle). Authenticated carts soft-hold via cart_${userId} (5 min TTL) then promote at checkout. ProcessConductor inventory-drift asserts the invariant. MCP: ring-stock-get / ring-stock-low / ring-stock-adjust / ring-reservation-list.

    After paid deduct, levels re-assert available = stock − reserved so paid-without-hold paths cannot leave stale available.

    Operator checklist

    1. Open /admin/store — see totals and pending settlements.
    2. /admin/store/stock — filter low / critical / out; restock with a reason; read the movement timeline (warehouse column shows zero-warehouse).
    3. Vendors use /vendor/stock — only their products; bulk restock supported.
    4. Smoke: stock 5 → checkout 2 → available 3, reserved 2, stock still 5 → pay → stock 3, reserved 0, available 3.

    If checkout returns “Insufficient inventory”, sellable (available) was too low — not “the product.stock field looked high.” Reserved units are already held for another open order.

    Tables

    TablePurpose
    inventory_levelsPer product+store (id = productId_storeId)
    inventory_reservationsOrder holds with TTL; cancel restores available; paid fulfills reserved
    stock_movementsAudit: sale, return, adjustment, …

    Schema: data/schema.sql (+ historical 008_inventory_schema.sql). Apply via migrations.

    Key APIs (verified)

    FunctionFileBehavior
    ensureInventoryLevel

    Admin & vendor UI

    SurfaceRouteActions
    Hub/admin/storeSummary cards + tabs
    Stock/admin/store/stockFilters, reason restock, movements
    Vendor stock/vendor/stockOwnership-gated restock + bulk

    Constants

    features/store/constants/stock.ts — ZERO_WAREHOUSE_ID, DEFAULT_INVENTORY_STORE_ID, STOCK_THRESHOLDS.

    Related documentation

    Ring ERP

    Prerequisite: ERP hub overview and operator surfaces.

    PaymentConductor

    Depends-on: paid webhooks invoke commitSaleForOrder.

    Commissions & Settlements

    Next-step: settlements appear after successful stock commit.

    Multi-Vendor Store

    Same-workflow: catalog and checkout feed reservation items.

    Inventory & Stock

    Ring tracks quantity with one locked rule: product stock equals available plus reserved. Checkout sells only available. PaymentConductor paid handlers call commitSaleForOrder so fulfill and deduct stay atomic.

    Do not treat Nova Poshta /api/shipping/novapost/warehouses as ERP warehouses. ERP default: label zero-warehouse ↔ store id 1 (DEFAULT_INVENTORY_STORE_ID).

    Locked invariant

    text
    
    store_products.stock  ===  inventory_levels.available  +  inventory_levels.reserved
    sellable              ===  inventory_levels.available
    Eventstockavailablereserved
    Bootstrap / restock +q+q+q—
    Reserve q—−q+q
    Fulfill (paid) q−q—−q
    Cancel / TTL q—+q−q
    Refund restore +q+q+q—

    Wave 1 (2026-07-23): digital / instantDelivery / preorder lines skip reserve+deduct (commissions still settle). Authenticated carts soft-hold via cart_${userId} (5 min TTL) then promote at checkout. ProcessConductor inventory-drift asserts the invariant. MCP: ring-stock-get / ring-stock-low / ring-stock-adjust / ring-reservation-list.

    After paid deduct, levels re-assert available = stock − reserved so paid-without-hold paths cannot leave stale available.

    Operator checklist

    1. Open /admin/store — see totals and pending settlements.
    2. /admin/store/stock — filter low / critical / out; restock with a reason; read the movement timeline (warehouse column shows zero-warehouse).
    3. Vendors use /vendor/stock — only their products; bulk restock supported.
    4. Smoke: stock 5 → checkout 2 → available 3, reserved 2, stock still 5 → pay → stock 3, reserved 0, available 3.

    If checkout returns “Insufficient inventory”, sellable (available) was too low — not “the product.stock field looked high.” Reserved units are already held for another open order.

    Tables

    TablePurpose
    inventory_levelsPer product+store (id = productId_storeId)
    inventory_reservationsOrder holds with TTL; cancel restores available; paid fulfills reserved
    stock_movementsAudit: sale, return, adjustment, …

    Schema: data/schema.sql (+ historical 008_inventory_schema.sql). Apply via migrations.

    Key APIs (verified)

    FunctionFileBehavior
    ensureInventoryLevel

    Admin & vendor UI

    SurfaceRouteActions
    Hub/admin/storeSummary cards + tabs
    Stock/admin/store/stockFilters, reason restock, movements
    Vendor stock/vendor/stockOwnership-gated restock + bulk

    Constants

    features/store/constants/stock.ts — ZERO_WAREHOUSE_ID, DEFAULT_INVENTORY_STORE_ID, STOCK_THRESHOLDS.

    Related documentation

    Ring ERP

    Prerequisite: ERP hub overview and operator surfaces.

    PaymentConductor

    Depends-on: paid webhooks invoke commitSaleForOrder.

    Commissions & Settlements

    Next-step: settlements appear after successful stock commit.

    Multi-Vendor Store

    Same-workflow: catalog and checkout feed reservation items.

    Inventory & Stock

    Ring tracks quantity with one locked rule: product stock equals available plus reserved. Checkout sells only available. PaymentConductor paid handlers call commitSaleForOrder so fulfill and deduct stay atomic.

    Do not treat Nova Poshta /api/shipping/novapost/warehouses as ERP warehouses. ERP default: label zero-warehouse ↔ store id 1 (DEFAULT_INVENTORY_STORE_ID).

    Locked invariant

    text
    
    store_products.stock  ===  inventory_levels.available  +  inventory_levels.reserved
    sellable              ===  inventory_levels.available
    Eventstockavailablereserved
    Bootstrap / restock +q+q+q—
    Reserve q—−q+q
    Fulfill (paid) q−q—−q
    Cancel / TTL q—+q−q
    Refund restore +q+q+q—

    Wave 1 (2026-07-23): digital / instantDelivery / preorder lines skip reserve+deduct (commissions still settle). Authenticated carts soft-hold via cart_${userId} (5 min TTL) then promote at checkout. ProcessConductor inventory-drift asserts the invariant. MCP: ring-stock-get / ring-stock-low / ring-stock-adjust / ring-reservation-list.

    After paid deduct, levels re-assert available = stock − reserved so paid-without-hold paths cannot leave stale available.

    Operator checklist

    1. Open /admin/store — see totals and pending settlements.
    2. /admin/store/stock — filter low / critical / out; restock with a reason; read the movement timeline (warehouse column shows zero-warehouse).
    3. Vendors use /vendor/stock — only their products; bulk restock supported.
    4. Smoke: stock 5 → checkout 2 → available 3, reserved 2, stock still 5 → pay → stock 3, reserved 0, available 3.

    If checkout returns “Insufficient inventory”, sellable (available) was too low — not “the product.stock field looked high.” Reserved units are already held for another open order.

    Tables

    TablePurpose
    inventory_levelsPer product+store (id = productId_storeId)
    inventory_reservationsOrder holds with TTL; cancel restores available; paid fulfills reserved
    stock_movementsAudit: sale, return, adjustment, …

    Schema: data/schema.sql (+ historical 008_inventory_schema.sql). Apply via migrations.

    Key APIs (verified)

    FunctionFileBehavior
    ensureInventoryLevel

    Admin & vendor UI

    SurfaceRouteActions
    Hub/admin/storeSummary cards + tabs
    Stock/admin/store/stockFilters, reason restock, movements
    Vendor stock/vendor/stockOwnership-gated restock + bulk

    Constants

    features/store/constants/stock.ts — ZERO_WAREHOUSE_ID, DEFAULT_INVENTORY_STORE_ID, STOCK_THRESHOLDS.

    Related documentation

    Ring ERP

    Prerequisite: ERP hub overview and operator surfaces.

    PaymentConductor

    Depends-on: paid webhooks invoke commitSaleForOrder.

    Commissions & Settlements

    Next-step: settlements appear after successful stock commit.

    Multi-Vendor Store

    Same-workflow: catalog and checkout feed reservation items.

    inventory-sync.ts
    Bootstrap {available: stock, reserved: 0} when missing
    reserveInventoryForOrderinventory-sync.tsNever skips; 409 when insufficient available
    releaseReservation(id, fulfilled)inventory-sync.tsCancel restores available; fulfill decrements reserved only (Flaw E)
    commitSaleForOrderinventory-sync.tsSingle txn; idempotent if sale movements exist for orderId
    restoreStockForOrderinventory-sync.tsRefund/void; idempotent via return movements
    updateStockerp-stock-service.tsTransactional product + levels; reject set below reserved
    POST /api/erp/stock/initializeapp/api/erp/stock/initialize/route.tsAdmin bulk init

    Paid rails (all call commitSaleForOrder)

    • lib/payments/conductor/handlers/store-order.ts (WFP) — also restoreStockForOrder on Refunded/Voided
    • store-order-stripe.ts, store-order-paypal.ts
    • app/api/store/payments/credit/route.ts, …/token/route.ts

    Cancel path

    app/_actions/admin-orders.ts → unpaid canceled releases holds; paid cancel restores via restoreStockForOrder.

    TTL: ProcessConductor cleanup-reservations → cleanupExpiredReservations (cancel path).

    WayForPay Refunded/Voided calls restoreStockForOrder. Stripe/PayPal refund event parity is still open — tracked as a FutureFeature on Commissions.

    Reserve, commit, reverse
    inventory-sync.ts
    Bootstrap {available: stock, reserved: 0} when missing
    reserveInventoryForOrderinventory-sync.tsNever skips; 409 when insufficient available
    releaseReservation(id, fulfilled)inventory-sync.tsCancel restores available; fulfill decrements reserved only (Flaw E)
    commitSaleForOrderinventory-sync.tsSingle txn; idempotent if sale movements exist for orderId
    restoreStockForOrderinventory-sync.tsRefund/void; idempotent via return movements
    updateStockerp-stock-service.tsTransactional product + levels; reject set below reserved
    POST /api/erp/stock/initializeapp/api/erp/stock/initialize/route.tsAdmin bulk init

    Paid rails (all call commitSaleForOrder)

    • lib/payments/conductor/handlers/store-order.ts (WFP) — also restoreStockForOrder on Refunded/Voided
    • store-order-stripe.ts, store-order-paypal.ts
    • app/api/store/payments/credit/route.ts, …/token/route.ts

    Cancel path

    app/_actions/admin-orders.ts → unpaid canceled releases holds; paid cancel restores via restoreStockForOrder.

    TTL: ProcessConductor cleanup-reservations → cleanupExpiredReservations (cancel path).

    WayForPay Refunded/Voided calls restoreStockForOrder. Stripe/PayPal refund event parity is still open — tracked as a FutureFeature on Commissions.

    Reserve, commit, reverse
    inventory-sync.ts
    Bootstrap {available: stock, reserved: 0} when missing
    reserveInventoryForOrderinventory-sync.tsNever skips; 409 when insufficient available
    releaseReservation(id, fulfilled)inventory-sync.tsCancel restores available; fulfill decrements reserved only (Flaw E)
    commitSaleForOrderinventory-sync.tsSingle txn; idempotent if sale movements exist for orderId
    restoreStockForOrderinventory-sync.tsRefund/void; idempotent via return movements
    updateStockerp-stock-service.tsTransactional product + levels; reject set below reserved
    POST /api/erp/stock/initializeapp/api/erp/stock/initialize/route.tsAdmin bulk init

    Paid rails (all call commitSaleForOrder)

    • lib/payments/conductor/handlers/store-order.ts (WFP) — also restoreStockForOrder on Refunded/Voided
    • store-order-stripe.ts, store-order-paypal.ts
    • app/api/store/payments/credit/route.ts, …/token/route.ts

    Cancel path

    app/_actions/admin-orders.ts → unpaid canceled releases holds; paid cancel restores via restoreStockForOrder.

    TTL: ProcessConductor cleanup-reservations → cleanupExpiredReservations (cancel path).

    WayForPay Refunded/Voided calls restoreStockForOrder. Stripe/PayPal refund event parity is still open — tracked as a FutureFeature on Commissions.

    Reserve, commit, reverse