openvibers/openvibe.billing .env.example
.env.example
| 1 | # ═══════════════════════════════════════════════════════════════ |
| 2 | # billing.openvibe.network — Environment Configuration |
| 3 | # Copy to .env for development. In production this lives at /etc/openvibe/billing.env (0600). |
| 4 | # ═══════════════════════════════════════════════════════════════ |
| 5 | |
| 6 | # Server: the service API (other services call http://127.0.0.1:4600/api/v1 — never through nginx), |
| 7 | # provider webhooks and the staff console (https://billing.openvibe.network/). |
| 8 | PORT=4600 |
| 9 | HOST=127.0.0.1 |
| 10 | NODE_ENV=development |
| 11 | BASE_URL=http://localhost:4600 |
| 12 | TRUST_PROXY=1 |
| 13 | |
| 14 | # PostgreSQL (ADR-035): DATABASE_URL serves through PgBouncer, DATABASE_DIRECT_URL (the owner) runs migrations/ at |
| 15 | # boot. OpenVibe.Host `roles/data/add-service.sh billing` writes both. Without DATABASE_URL, development runs on an |
| 16 | # embedded PGlite database in data/pglite (BILLING_PGLITE_DIR); production refuses to start. |
| 17 | DATABASE_URL= |
| 18 | DATABASE_DIRECT_URL= |
| 19 | # Valkey: the per-person limit counters, kept across restarts (optional; without it they count in the process). |
| 20 | VALKEY_URL= |
| 21 | |
| 22 | # Who keeps the money books: live (default — OpenVibe.Live is the ledger and receives the PowerChat |
| 23 | # webhook; Billing runs in shadow) or billing (after the cutover, docs/live-cutover.md). Only EXTERNAL |
| 24 | # tips depend on it today: under billing they are announced as billing.receipt.external for |
| 25 | # OpenVibe.Tips; under live they are recorded only, because Live's own webhook announces them. |
| 26 | # Any other value stops Billing at boot. |
| 27 | #BILLING_AUTHORITY=live |
| 28 | |
| 29 | # ── Identity: OpenVibe.Network ────────────────────────────── |
| 30 | OV_NETWORK_URL=https://openvibe.network |
| 31 | OV_NETWORK_INTERNAL_URL=http://127.0.0.1:4000 |
| 32 | # Expected `iss` of service tokens (defaults to OV_NETWORK_URL). |
| 33 | #OV_NETWORK_ISSUER=https://openvibe.network |
| 34 | # Optional: pin the Network's RS256 public key (PEM, \n escaped) instead of fetching the JWKS. |
| 35 | #OV_NETWORK_PUBLIC_KEY= |
| 36 | # Audience Billing accepts on incoming service tokens. |
| 37 | BILLING_AUDIENCE=openvibe.billing |
| 38 | # Billing's own client credentials (client `billing` registered in the Network) — used for |
| 39 | # resolve-batch (identity.subject.resolve, audience openvibe.network), the events relay |
| 40 | # (events.event.publish, audience openvibe.events) and the staff console's SSO code exchange. |
| 41 | OV_OAUTH_CLIENT_ID=billing |
| 42 | OV_OAUTH_CLIENT_SECRET=change-me |
| 43 | |
| 44 | # ── Per-person limits on /api/v1's money routes (server/api/actor-limits.js; README "Per-person limits") ── |
| 45 | # Counted per person named in the request, whichever service sends it; past a limit 429 rate_limited with |
| 46 | # Retry-After. MINUTE/HOUR: a person's history reads; checkouts, transfers, refunds, payout requests, |
| 47 | # recycling and credit subscriptions have fixed, tighter numbers. Webhooks are never limited. |
| 48 | # BILLING_LIMITS=off counts nobody (rollback without a deploy). |
| 49 | #BILLING_LIMITS=on |
| 50 | #BILLING_LIMITS_MINUTE=120 |
| 51 | #BILLING_LIMITS_HOUR=3000 |
| 52 | |
| 53 | # ── Staff console (Network SSO; see README "Staff console") ── |
| 54 | # The Network must list ${BASE_URL}/auth/callback (https://billing.openvibe.network/auth/callback) |
| 55 | # as a redirect URI of OAuth client `billing`. |
| 56 | # Comma-separated usr_ subject ids allowed to use the console. Each must ALSO hold staff.money.cashouts |
| 57 | # in the contracts staff map (money is the owner's: role admin with is_owner in the Network token). |
| 58 | # Empty = nobody can sign in. |
| 59 | BILLING_STAFF_SUBJECTS= |
| 60 | # Signs the sign-in flow cookie and keys the IP hashes in staff_audit: at least 32 random characters |
| 61 | # (e.g. `openssl rand -hex 32`). Required in production — the console answers 503 without it. |
| 62 | BILLING_SESSION_SECRET= |
| 63 | # Absolute console session lifetime in minutes (5–720). |
| 64 | #BILLING_SESSION_TTL_MIN=60 |
| 65 | # Audience a Network user token must carry. |
| 66 | #BILLING_SSO_AUDIENCE=openvibe.network |
| 67 | |
| 68 | # ── Money rates (Live's current values are the defaults) ──── |
| 69 | #BILLING_BITS_PER_USD=100 |
| 70 | #BILLING_PRICE_TIERS=[{"min":25000,"usd_per_bit":0.011},{"min":10000,"usd_per_bit":0.0115},{"min":5000,"usd_per_bit":0.012},{"min":2500,"usd_per_bit":0.0124},{"min":1000,"usd_per_bit":0.013},{"min":500,"usd_per_bit":0.014},{"min":0,"usd_per_bit":0.015}] |
| 71 | #BILLING_MIN_PURCHASE_BITS=100 |
| 72 | #BILLING_MAX_BITS=10000000 |
| 73 | #BILLING_SUB_PRICE_CENTS=499 |
| 74 | # Creator-priced subscription tiers (GET/PUT /api/v1/tiers): price bounds in cents and tiers per creator (max 10). |
| 75 | #BILLING_TIER_MIN_CENTS=100 |
| 76 | #BILLING_TIER_MAX_CENTS=50000 |
| 77 | #BILLING_MAX_TIERS=10 |
| 78 | #BILLING_SUB_SHARE_PCT=70 |
| 79 | #BILLING_SITE_ROUTE_FEE_PCT=10 |
| 80 | #BILLING_SUB_PERIOD_DAYS=31 |
| 81 | #BILLING_MIN_CASHOUT_BITS=500 |
| 82 | #BILLING_ESCROW_DAYS=14 |
| 83 | #BILLING_STRIPE_GRACE_DAYS=3 |
| 84 | # Days a failed credit renewal stays past_due (retried by the hourly sweep on the same key) before it ends. |
| 85 | # 3 is the default (VIP reads past_due, plan s4); set 0 to restore immediate expiry (docs/renewal-grace-cutover.md). |
| 86 | #BILLING_RENEWAL_GRACE_DAYS=3 |
| 87 | |
| 88 | # ── Providers: each adapter is ENABLED only when its secrets are set ── |
| 89 | # PowerChat (the only rail carrying money in production) |
| 90 | # optional until the Billing cutover (WS-K task 2): without it the PowerChat provider stays off |
| 91 | # POWERCHAT_WEBHOOK_SECRET= |
| 92 | # The site's PowerChat tips account (lower-case username). REQUIRED for PowerChat money: pcorder:/pcdon:/site |
| 93 | # pcsub: checkouts settle only when the tip was paid to this account (unset: they are held for review). |
| 94 | # Unattributed tips to it are flagged. |
| 95 | POWERCHAT_SITE_USERNAME= |
| 96 | # Credit isTest deliveries (flagged test). Development/sandbox only. |
| 97 | #POWERCHAT_ALLOW_TEST_FULFILLMENT=false |
| 98 | |
| 99 | # Stripe (off in production). The owner can enter these in the admin panel's Setup tab instead (billing.cards, |
| 100 | # sealed); a value entered there wins, these stay the fallback. |
| 101 | #STRIPE_SECRET_KEY= |
| 102 | #STRIPE_PUBLISHABLE_KEY= |
| 103 | #STRIPE_WEBHOOK_SECRET= |
| 104 | # PayPal (off in production) |
| 105 | #PAYPAL_CLIENT_ID= |
| 106 | #PAYPAL_CLIENT_SECRET= |
| 107 | #PAYPAL_WEBHOOK_ID= |
| 108 | #PAYPAL_MODE=sandbox |
| 109 | # CCBill (off in production) |
| 110 | #CCBILL_WEBHOOK_SECRET= |
| 111 | #CCBILL_CLIENT_ACCOUNT= |
| 112 | #CCBILL_SUBACCOUNT= |
| 113 | #CCBILL_FLEXFORM_ID= |
| 114 | #CCBILL_SALT= |
| 115 | # NOWPayments (off in production) |
| 116 | #NOWPAYMENTS_API_KEY= |
| 117 | #NOWPAYMENTS_IPN_SECRET= |
| 118 | |
| 119 | # ── Durable events: relay the outbox to OpenVibe.Events (off when unset) ── |
| 120 | #EVENTS_URL=http://127.0.0.1:4300 |
| 121 | #EVENTS_RELAY_INTERVAL_MS=2000 |
| 122 | |
| 123 | # ── Background jobs: webhook retries, hourly renewal sweep, outbox relay ── |
| 124 | #BILLING_JOBS=on |
| 125 | #BILLING_SWEEP_INTERVAL_MS=3600000 |
| 126 | #BILLING_WEBHOOK_RETRY_MS=60000 |
| 127 | # Scheduled reconciliation (0 = off); passing scheduled runs older than KEEP_DAYS are pruned. |
| 128 | #BILLING_RECONCILE_INTERVAL_MS=3600000 |
| 129 | #BILLING_RECONCILE_KEEP_DAYS=30 |
| 130 | # A provider receipt unprocessed this long (economy open) fails reconciliation (receipts.stale). |
| 131 | #BILLING_RECONCILE_STALE_RECEIPT_MIN=60 |
| 132 | # Usage rating (README "Rates"): the sweep is off until this is set (0 = off); nothing is charged without a |
| 133 | # rate card, and cards are loaded only by review: OV_RATE_CARDS + node scripts/load-rate-cards.js. |
| 134 | #BILLING_RATING_INTERVAL_MS=0 |
| 135 | #BILLING_RATING_BATCH=500 |
| 136 | #BILLING_RATING_RETRY_MS=3600000 |
| 137 | #OV_RATE_CARDS=/etc/openvibe/rate-cards.json |
| 138 | |
| 139 | # Account export and deletion (ADR-033): the signing secret of Billing's own Events subscriptions (32+ characters; |
| 140 | # comma-separated during a rotation). Without it, the account subscriptions are not created and /internal/events answers 503. |
| 141 | #BILLING_EVENTS_SECRET= |
| 142 | |
| 143 | # ── Vibes Pay (D12): developer app charges, the pay sheet and sandbox test Vibes ── |
| 144 | # These are the pre-D11 names of the billing.vibes namespace keys; while set they pin the owner's value. |
| 145 | #BILLING_VIBES_PAY=0 |
| 146 | #BILLING_VIBES_MAX_CHARGE=0 |
| 147 | #BILLING_VIBES_DAILY_APP_SPEND=0 |
| 148 | # Test grants and sandbox charges, worth nothing (one switch, like BILLING_CREDITS_SANDBOX). |
| 149 | #BILLING_VIBES_SANDBOX=0 |
| 150 | # Charge lifetime and the openvibe.network pay-sheet origin. |
| 151 | #BILLING_VIBES_CHARGE_TTL_SECONDS=1800 |
| 152 | #BILLING_VIBES_PAY_BASE_URL=https://openvibe.network |
| 153 | # The webhook delivery job (0 = off; tests call deliverDue directly). |
| 154 | #BILLING_VIBES_WEBHOOK_INTERVAL_MS=5000 |
| 155 | # Development only: allow a private webhook address. Production always applies the egress guard. |
| 156 | #BILLING_VIBES_ALLOW_PRIVATE_WEBHOOKS=0 |
| 157 |