openvibers/openvibe.contracts Commits

v0.8.0: OpenVibe.Billing is alpha (shadow) — billing.intent.create, transfer.create, balance.read, cashout.request, cashout.manage, subscription.manage, entitlement.check, ledger.admin

OP OpenVibers committed 23 Sept 2026 · 22f0a9e7b9 · 10 files, +222 −9


Changes

ddiff --git a/manifests/capabilities/billing.balance.read.json b/manifests/capabilities/billing.balance.read.json
nnew file mode 100644
iindex 00000000..f72eab7a
---- /dev/null
++++ b/manifests/capabilities/billing.balance.read.json
@@@ -0,0 +1,21 @@
++{
++ "id": "billing.balance.read",
++ "version": "1.0",
++ "owner": "billing",
++ "status": "active",
++ "visibility": "internal",
++ "description": "Read a subject's balances (spendable credit, creator payable, pending payouts) and transaction history.",
++ "permissions": [
++ "billing:read"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "ledger-read",
++ "events": [],
++ "implementedBy": [
++ "GET /api/v1/balances/:subject",
++ "GET /api/v1/transactions",
++ "GET /api/v1/transactions/:id"
++ ]
++}
ddiff --git a/manifests/capabilities/billing.cashout.manage.json b/manifests/capabilities/billing.cashout.manage.json
nnew file mode 100644
iindex 00000000..b39837ab
---- /dev/null
++++ b/manifests/capabilities/billing.cashout.manage.json
@@@ -0,0 +1,25 @@
++{
++ "id": "billing.cashout.manage",
++ "version": "1.0",
++ "owner": "billing",
++ "status": "active",
++ "visibility": "internal",
++ "description": "Operator payouts: list cashouts, approve one after its escrow period with the payout reference from the provider (required), or deny it (reversal back to creator payable). Separately controlled from every other capability (ADR-012 rule 10).",
++ "permissions": [
++ "billing:payouts"
++ ],
++ "resourceConstraints": [
++ "none"
++ ],
++ "quotaClass": "ledger-admin",
++ "events": [
++ "billing.cashout.paid",
++ "billing.cashout.denied",
++ "billing.transaction.reversed"
++ ],
++ "implementedBy": [
++ "GET /api/v1/cashouts",
++ "POST /api/v1/cashouts/:id/approve",
++ "POST /api/v1/cashouts/:id/deny"
++ ]
++}
ddiff --git a/manifests/capabilities/billing.cashout.request.json b/manifests/capabilities/billing.cashout.request.json
nnew file mode 100644
iindex 00000000..ae585d33
---- /dev/null
++++ b/manifests/capabilities/billing.cashout.request.json
@@@ -0,0 +1,24 @@
++{
++ "id": "billing.cashout.request",
++ "version": "1.0",
++ "owner": "billing",
++ "status": "active",
++ "visibility": "internal",
++ "description": "Request a cashout of creator payable into escrow (minimum and escrow period enforced by Billing), or recycle creator payable into the subject's own spendable credit. Bought credit is never withdrawable.",
++ "permissions": [
++ "billing:cashout"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "ledger-write",
++ "events": [
++ "billing.cashout.requested",
++ "billing.transaction.settled"
++ ],
++ "implementedBy": [
++ "POST /api/v1/cashouts",
++ "POST /api/v1/recycle",
++ "GET /api/v1/cashouts/:id"
++ ]
++}
ddiff --git a/manifests/capabilities/billing.entitlement.check.json b/manifests/capabilities/billing.entitlement.check.json
nnew file mode 100644
iindex 00000000..c9853887
---- /dev/null
++++ b/manifests/capabilities/billing.entitlement.check.json
@@@ -0,0 +1,21 @@
++{
++ "id": "billing.entitlement.check",
++ "version": "1.0",
++ "owner": "billing",
++ "status": "active",
++ "visibility": "internal",
++ "description": "Is a subject entitled to a streamer's subscription right now, and until when. Answered from Billing alone (works with Live offline).",
++ "permissions": [
++ "billing:read"
++ ],
++ "resourceConstraints": [
++ "none"
++ ],
++ "quotaClass": "ledger-read",
++ "events": [],
++ "implementedBy": [
++ "GET /api/v1/entitlements/:subject",
++ "GET /api/v1/subscriptions",
++ "GET /api/v1/subscriptions/:id"
++ ]
++}
ddiff --git a/manifests/capabilities/billing.intent.create.json b/manifests/capabilities/billing.intent.create.json
nnew file mode 100644
iindex 00000000..096dd110
---- /dev/null
++++ b/manifests/capabilities/billing.intent.create.json
@@@ -0,0 +1,21 @@
++{
++ "id": "billing.intent.create",
++ "version": "1.0",
++ "owner": "billing",
++ "status": "active",
++ "visibility": "internal",
++ "description": "Start a checkout: create a payment intent priced by Billing (never by the client) for a Vibes purchase or a channel subscription, and get the provider checkout URL or PowerChat app_ref. Also reads intents and captures approved PayPal orders.",
++ "permissions": [
++ "billing:intents"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "ledger-write",
++ "events": [],
++ "implementedBy": [
++ "POST /api/v1/intents",
++ "GET /api/v1/intents/:id",
++ "POST /api/v1/intents/:id/capture"
++ ]
++}
ddiff --git a/manifests/capabilities/billing.ledger.admin.json b/manifests/capabilities/billing.ledger.admin.json
nnew file mode 100644
iindex 00000000..2b439646
---- /dev/null
++++ b/manifests/capabilities/billing.ledger.admin.json
@@@ -0,0 +1,28 @@
++{
++ "id": "billing.ledger.admin",
++ "version": "1.0",
++ "owner": "billing",
++ "status": "active",
++ "visibility": "internal",
++ "description": "Operate the ledger: economy freeze switch (writes refused, reads served, webhooks queued), reconciliation runs, balanced manual adjustments with a reason, settling a verified provider receipt, provider-event reprocessing, the renewal sweep and import holds.",
++ "permissions": [
++ "billing:admin"
++ ],
++ "resourceConstraints": [
++ "none"
++ ],
++ "quotaClass": "ledger-admin",
++ "events": [
++ "billing.transaction.settled"
++ ],
++ "implementedBy": [
++ "GET|POST /api/v1/admin/freeze",
++ "GET /api/v1/admin/reconcile",
++ "POST /api/v1/admin/adjustments",
++ "POST /api/v1/purchases/settle",
++ "GET /api/v1/admin/provider-events",
++ "POST /api/v1/admin/provider-events/:id/reprocess",
++ "POST /api/v1/admin/sweep",
++ "GET /api/v1/admin/import-holds"
++ ]
++}
ddiff --git a/manifests/capabilities/billing.subscription.manage.json b/manifests/capabilities/billing.subscription.manage.json
nnew file mode 100644
iindex 00000000..e734298e
---- /dev/null
++++ b/manifests/capabilities/billing.subscription.manage.json
@@@ -0,0 +1,26 @@
++{
++ "id": "billing.subscription.manage",
++ "version": "1.0",
++ "owner": "billing",
++ "status": "active",
++ "visibility": "internal",
++ "description": "Start or renew a channel subscription paid from credit (the streamer share is credited on every period), and cancel at period end (Stripe subscriptions are cancelled at Stripe). Receipt-paid subscriptions through the API additionally need billing.ledger.admin.",
++ "permissions": [
++ "billing:subscriptions"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "ledger-write",
++ "events": [
++ "billing.transaction.settled",
++ "billing.entitlement.changed",
++ "billing.subscription.canceled"
++ ],
++ "implementedBy": [
++ "POST /api/v1/subscriptions",
++ "POST /api/v1/subscriptions/:id/cancel",
++ "GET /api/v1/subscriptions",
++ "GET /api/v1/subscriptions/:id"
++ ]
++}
ddiff --git a/manifests/capabilities/billing.transfer.create.json b/manifests/capabilities/billing.transfer.create.json
nnew file mode 100644
iindex 00000000..1581b112
---- /dev/null
++++ b/manifests/capabilities/billing.transfer.create.json
@@@ -0,0 +1,23 @@
++{
++ "id": "billing.transfer.create",
++ "version": "1.0",
++ "owner": "billing",
++ "status": "active",
++ "visibility": "internal",
++ "description": "Give CREDIT to someone (tip, donation, paid interaction): user_credit of the giver to creator_payable of the recipient. Self-dealing is refused by subject. Also refunds a credit-funded transfer back to its giver (e.g. a media request that never played). Idempotent by Idempotency-Key.",
++ "permissions": [
++ "billing:transfer"
++ ],
++ "resourceConstraints": [
++ "owner"
++ ],
++ "quotaClass": "ledger-write",
++ "events": [
++ "billing.transaction.settled",
++ "billing.transaction.reversed"
++ ],
++ "implementedBy": [
++ "POST /api/v1/transfers",
++ "POST /api/v1/transfers/:id/refund"
++ ]
++}
ddiff --git a/manifests/services/billing.json b/manifests/services/billing.json
iindex 51b40cec..9b53382f 100644
---- a/manifests/services/billing.json
++++ b/manifests/services/billing.json
@@@ -1,16 +1,40 @@
{
-- "version": "0.1.0",
++ "version": "0.2.0",
"contractRanges": {
-- "openvibe-contracts": "^0.1.0"
++ "openvibe-contracts": ">=0.5.1 <1.0.0"
},
"id": "billing",
"name": "OpenVibe.Billing",
-- "status": "placeholder",
++ "status": "alpha",
"repository": "OpenVibers/OpenVibe.Billing",
-- "domains": [],
-- "capabilities": [],
-- "eventsProduced": [],
++ "domains": [
++ "billing.openvibe.network"
++ ],
++ "publicOrigin": "https://billing.openvibe.network",
++ "health": "/api/health",
++ "ready": "/api/ready",
++ "capabilities": [
++ "billing.intent.create",
++ "billing.transfer.create",
++ "billing.balance.read",
++ "billing.cashout.request",
++ "billing.cashout.manage",
++ "billing.subscription.manage",
++ "billing.entitlement.check",
++ "billing.ledger.admin"
++ ],
++ "eventsProduced": [
++ "billing.transaction.settled",
++ "billing.transaction.reversed",
++ "billing.entitlement.changed",
++ "billing.subscription.canceled",
++ "billing.cashout.requested",
++ "billing.cashout.paid",
++ "billing.cashout.denied"
++ ],
"eventsConsumed": [],
-- "namespacesOwned": [],
-- "notes": "The isolated money ledger: providers, receipts, subscriptions, entitlements, refunds and payouts. Charter only; no runtime."
++ "namespacesOwned": [
++ "billing.*"
++ ],
++ "notes": "The isolated money ledger (ADR-012): balanced append-only journal, provider receipts, subscriptions/entitlements, refunds and payouts. Alpha, shadow mode: Live stays authoritative for money until the Wave 8 cutover; Billing imports and reconciles."
}
ddiff --git a/package.json b/package.json
iindex 81cd04d3..0719350c 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-contracts",
-- "version": "0.7.0",
++ "version": "0.8.0",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"main": "index.js",
"types": "generated/typescript/index.d.ts",