Skip to content

💳 Ring2All BSS (Billing & OCS) Deployment Guide

8 min readUpdated: Sep 26, 2026
View as Markdown

Complete step-by-step guide for installing and configuring Ring2All BSS on Debian 13 (Trixie), decoupling back-office carrier rating from the public customer self-care store.


The Ring2All BSS (Business Support System) serves as the monetization and commercial intelligence engine for telecom operators. It translates raw network events (SIP INVITEs, Call Detail Records, active media sessions) into billed transactions, manages prepaid customer wallets in real time, and exposes self-service purchasing for virtual DIDs, trunks, and extensions.

flowchart TB
    subgraph DMZ["Public Edge / DMZ (Customer Storefront)"]
        ClientWeb["Customer Self-Care Store<br/>(softswitch-bss-client)<br/>store.carrier.com"]
        EdgeProxy["Nginx DMZ Reverse Proxy / WAF<br/>(Passes ONLY /api/client/*)"]
    end

    subgraph InternalLAN["Internal Management LAN (Zero Direct Public Exposure)"]
        AdminWeb["Back-Office Admin Portal<br/>(softswitch-bss-web)<br/>bss-admin.carrier.com"]
        BssApi["BSS & Real-Time OCS Engine<br/>(softswitch-bss-api :3002)<br/>Fastify 5 / Node.js 22"]
        DB[("PostgreSQL 17 HA Cluster<br/>(customers, wallets, rates, ocs_cdrs)")]
        Redis[("Redis In-Memory Cache<br/>(Sub-millisecond Rate Lookups)")]
    end

    subgraph TelecomNodes["Telecom Execution Nodes"]
        SBC["Ring2All SBC Gateway<br/>(Kamailio 6.1)"]
        PBX["Ring2All PBX Cluster<br/>(FreeSWITCH 1.11+)"]
    end

    ClientWeb -->|HTTPS| EdgeProxy
    EdgeProxy -->|Passes /api/client/*| BssApi
    AdminWeb -->|Internal HTTPS / VPN| BssApi

    BssApi <--> DB
    BssApi <--> Redis

    SBC <-->|Sub-millisecond OCS Auth / Balance Check| BssApi
    PBX <-->|Real-Time CDR & Balance Updates| BssApi
  1. Strict Separation of Admin and Storefront:
    • Back-Office Admin (softswitch-bss-web): Confined to internal management LANs or secure VPNs. Telecom administrators manage rate decks, carrier costs, customer accounts, and telecom nodes.
    • Customer Self-Care Store (softswitch-bss-client): Exposed to the public internet. Subscribers purchase subscription plans, order virtual DID numbers, manage autodialer campaigns, top up wallets, and review CDR usage.
  2. Zero Database Exposure at the Perimeter:
    • The customer store is a client-side React 18 Single Page Application. It has zero direct access to PostgreSQL.
  3. DMZ Perimeter Reverse Proxy Filtering:
    • The customer edge reverse proxy passes only authenticated customer endpoints (/api/client/*) while aggressively returning 403 Forbidden for administrative routes (/api/v1/users, /api/v1/telecom-nodes, /api/v1/firewall).
  4. Sub-Millisecond Online Charging System (OCS):
    • Evaluates call authorization, balance verification, and destination pricing using high-speed caching and sub-millisecond PostgreSQL rating queries before an outbound call is established.

Ring2All BSS is distributed via four decoupled Debian packages:

Package Name Function Staging Path Dependencies
softswitch-bss-api Fastify 5 / Node.js 22 OCS rating engine, customer API, billing daemon, background CDR synchronizer /var/www/softswitch/bss/api nodejs (>= 22), postgresql-client
softswitch-bss-web React 18 administrative back-office web application /var/www/softswitch/bss/web nginx
softswitch-bss-client React 18 customer-facing self-care store & billing portal /var/www/softswitch/bss/client nginx
softswitch-bss-all Metapackage for single-server all-in-one deployments N/A Depends on all 3 packages above

Ideal for small to mid-sized telecom operators. The API daemon, Admin UI, and Customer Store run on the same Debian 13 host:

  • Admin UI: Accessed at https://bss.carrier.com (or port 443).
  • Customer Store: Accessed at https://store.carrier.com (or dedicated port :8443).
  • BSS API: Runs locally on 127.0.0.1:3002, reverse-proxied by Nginx.

Topology B: Distributed Multi-Server DMZ Deployment

Section titled “Topology B: Distributed Multi-Server DMZ Deployment”

Recommended for enterprise carriers and public cloud environments:

  • Server 1 (Internal LAN / Billing Core):
    • Runs softswitch-bss-api, softswitch-bss-web, and PostgreSQL 17.
    • Not reachable directly from the public internet. Accessible only via corporate VPN or WireGuard tunnel.
  • Server 2 (Public Edge / DMZ Store):
    • Runs softswitch-bss-client and Nginx.
    • Serves static assets for the Customer Store and proxies /api/client/ across the internal network to Server 1.

🛠️ Step-by-Step Installation (Debian 13)

Section titled “🛠️ Step-by-Step Installation (Debian 13)”

Step 1: System Preparation & Prerequisites

Section titled “Step 1: System Preparation & Prerequisites”

On your target Debian 13 server, install foundational dependencies:

Terminal window
apt-get update
apt-get install -y curl wget gnupg2 openssl nginx postgresql-client

Ensure Node.js 22 LTS is registered:

Terminal window
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y nodejs build-essential

Register the Ring2All APT repository:

Terminal window
curl -fsSL https://repo.softswitchone.com/apt/setup_repo | bash
apt-get update

If using a dedicated PostgreSQL host or local database, create the ss_bss database and user:

Terminal window
sudo -u postgres psql << 'EOF'
CREATE DATABASE ss_bss;
CREATE USER bss_user WITH ENCRYPTED PASSWORD 'StrongBssPassword2026!';
GRANT ALL PRIVILEGES ON DATABASE ss_bss TO bss_user;
ALTER DATABASE ss_bss OWNER TO bss_user;
EOF

Terminal window
apt-get install -y -o Dpkg::Options::="--force-overwrite" softswitch-bss-all
  • On Internal Core Server:
    Terminal window
    apt-get install -y -o Dpkg::Options::="--force-overwrite" softswitch-bss-api softswitch-bss-web
  • On Public DMZ Edge Server:
    Terminal window
    apt-get install -y -o Dpkg::Options::="--force-overwrite" softswitch-bss-client

Edit /etc/softswitch/bss-api.env:

NODE_ENV=production
PORT=3002
HOST=127.0.0.1
# Database Configuration
DATABASE_URL=postgresql://bss_user:StrongBssPassword2026!@127.0.0.1:5432/ss_bss
# JWT Security
JWT_SECRET=super-secret-hex-key-minimum-32-chars-long
JWT_EXPIRES_IN=7d
# Telecom Nodes Sync (Ring2All SBC / PBX)
SBC_API_URL=http://127.0.0.1:3003
SBC_API_KEY=sbc_internal_bearer_token
# Stripe Payment Gateway (Optional / Recommended)
STRIPE_SECRET_KEY=sk_live_YourStripeSecretKeyHere
STRIPE_WEBHOOK_SECRET=whsec_YourStripeWebhookSecretHere
STRIPE_CURRENCY=usd
# OCS Real-Time Rating Cache
REDIS_URL=redis://127.0.0.1:6379

Secure permissions and restart the API daemon:

Terminal window
chmod 600 /etc/softswitch/bss-api.env
systemctl daemon-reload
systemctl enable --now softswitch-bss-api
systemctl status softswitch-bss-api

1. Back-Office Administrative Portal (/etc/nginx/sites-available/bss-admin)

Section titled “1. Back-Office Administrative Portal (/etc/nginx/sites-available/bss-admin)”
server {
listen 80;
server_name bss-admin.carrier.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name bss-admin.carrier.com;
ssl_certificate /etc/ssl/certs/bss-admin.crt;
ssl_certificate_key /etc/ssl/private/bss-admin.key;
root /var/www/softswitch/bss/web;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# Internal REST API proxy
location /api/ {
proxy_pass http://127.0.0.1:3002/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

2. Public Customer Storefront & DMZ Proxy (/etc/nginx/sites-available/bss-store)

Section titled “2. Public Customer Storefront & DMZ Proxy (/etc/nginx/sites-available/bss-store)”
server {
listen 80;
server_name store.carrier.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name store.carrier.com;
ssl_certificate /etc/ssl/certs/bss-store.crt;
ssl_certificate_key /etc/ssl/private/bss-store.key;
root /var/www/softswitch/bss/client;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# DMZ Filtering: ONLY allow customer-facing endpoints
location /api/client/ {
proxy_pass http://127.0.0.1:3002/api/client/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Block administrative routes from public store edge
location /api/v1/ {
return 403;
}
}

Enable and reload Nginx:

Terminal window
ln -sf /etc/nginx/sites-available/bss-admin /etc/nginx/sites-enabled/
ln -sf /etc/nginx/sites-available/bss-store /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

Ring2All BSS includes native Stripe integration for automated prepaid wallet recharges and recurring monthly DID/line subscriptions.

In the Stripe Developer Dashboard (https://dashboard.stripe.com/webhooks), create an endpoint:

  • URL: https://store.carrier.com/api/client/payments/webhook
  • Events to listen for:
    • checkout.session.completed
    • payment_intent.succeeded
    • invoice.paid
    • customer.subscription.deleted

When a customer tops up their prepaid balance via credit card or Apple Pay, Stripe sends an authenticated webhook payload signed with STRIPE_WEBHOOK_SECRET. The BSS API atomically increments the customer’s wallet balance in PostgreSQL and refreshes the in-memory OCS balance cache instantly.


⚡ Interconnecting OCS with Ring2All SBC & PBX

Section titled “⚡ Interconnecting OCS with Ring2All SBC & PBX”

To enforce real-time prepaid balance limits on outbound calling:

  1. In the Ring2All BSS Admin (https://bss-admin.carrier.com), go to Telecom Nodes and register your Ring2All SBC:
    • Node Type: Ring2All SBC (Kamailio)
    • Internal Host: 10.9.0.1 (or private LAN IP)
    • Shared API Token: Generate a secure bearer token.
  2. In Ring2All SBC, configure Kamailio’s HTTP client module (http_client) to query BSS before routing external PSTN calls:
    # Kamailio OCS Pre-Call Authorization Hook
    http_client_query("http://192.168.10.50:3002/api/ocs/authorize?caller=$fU&callee=$rU", "$var(ocs_res)");
    if ($rc != 200) {
    sl_send_reply("402", "Payment Required - Insufficient Funds");
    exit;
    }
  3. If balance is sufficient, the call proceeds without noticeable setup latency (< 5ms). When the call ends, Kamailio or FreeSWITCH transmits the final duration to /api/ocs/cdr, deducting the exact cost from the prepaid wallet.

Terminal window
systemctl status softswitch-bss-api
systemctl status nginx
Terminal window
curl -s http://127.0.0.1:3002/health
# Expected: {"status":"ok","service":"softswitch-bss-api","version":"1.0.0"}
Terminal window
# Permitted customer endpoint (should return 401 Unauthorized or 200 OK)
curl -I https://store.carrier.com/api/client/auth/me
# Prohibited administrative endpoint (MUST return 403 Forbidden)
curl -I https://store.carrier.com/api/v1/users
# Expected: HTTP/1.1 403 Forbidden

1. Customers see “Network Error” when browsing store

Section titled “1. Customers see “Network Error” when browsing store”
  • Cause: Nginx reverse proxy configuration for /api/client/ is misconfigured or softswitch-bss-api is stopped.
  • Solution: Check API service status and Nginx error logs:
    Terminal window
    systemctl status softswitch-bss-api
    tail -f /var/log/nginx/error.log

2. Wallet does not update after successful Stripe payment

Section titled “2. Wallet does not update after successful Stripe payment”
  • Cause: Stripe webhook secret mismatch or endpoint not receiving POST requests.
  • Solution: Check journalctl -u softswitch-bss-api -f while testing a webhook event in the Stripe CLI. Verify STRIPE_WEBHOOK_SECRET matches your Stripe dashboard.