Files

215 lines
4.8 KiB
Markdown

# Billing + Credits Architecture v1
## 1. System boundary
Separate billing orchestration from plugin runtime.
1. `Payment System` (e.g. Paymenter):
- plans, checkout, invoices, payments
2. `Management Cloud / Credits Service`:
- authoritative credit ledger
- entitlement state
- grant workflows
- treasury + funding automation
3. `NuQloud plugin + broker`:
- checks credits/entitlements before write operations
- records consumption/refunds via management APIs
Nextcloud app should not integrate directly with payment webhooks.
## 2. Data model (minimum)
## 2.1 Ledger entries
`ledger_entries`
1. `id`
2. `instance_id`
3. `type` (`grant|purchase|consume|refund|adjustment`)
4. `credits_delta` (signed integer)
5. `qort_amount` (nullable decimal, reference only)
6. `ref` (idempotency key)
7. `metadata` (JSON)
8. `created_at`
Constraint:
1. unique index on `(instance_id, type, ref)`
## 2.2 Balances
`instance_balances`
1. `instance_id` (PK)
2. `credits_balance`
3. `updated_at`
## 2.3 Entitlements
`instance_entitlements`
1. `instance_id` (PK)
2. `plan`
3. `follower_count`
4. `capacity_gb`
5. `status` (`active|past_due|suspended|cancelled`)
6. `period_end`
7. `updated_at`
## 2.4 Grants
`intro_grants`
1. `instance_id` (unique)
2. `status` (`pending|approved|rejected|completed`)
3. `requested_at`
4. `approved_by`
5. `approved_at`
6. `grant_credits`
7. `ref` (request id / tx id)
## 3. API contract (minimum)
## 3.1 Billing webhook ingest
`POST /billing/webhook/paymenter`
1. Verify signature/HMAC.
2. Extract `instance_id` from trusted metadata.
3. Write idempotent purchase ledger entry.
4. Update entitlement state.
5. Trigger async funding/reconciliation job.
## 3.2 Balance + entitlement read
1. `GET /instances/{id}/billing/summary`
2. Returns:
- balance
- plan
- capacity
- follower targets
- status
## 3.3 Consumption
`POST /instances/{id}/credits/consume`
1. Input:
- `cost_credits`
- `ref` (publish operation id)
- `metadata`
2. Behavior:
- atomic check and decrement
- idempotent by `ref`
## 3.4 Refund
`POST /instances/{id}/credits/refund`
1. Input:
- `credits`
- `ref` (failed operation id)
2. Behavior:
- idempotent compensation entry
## 3.5 Intro grant request/approval
1. `POST /instances/{id}/grants/intro/request`
2. `POST /instances/{id}/grants/intro/approve`
3. `POST /instances/{id}/grants/intro/reject`
Guardrails:
1. One grant ever per instance.
2. Approval role required.
3. Fixed max grant size.
## 3.6 Product catalog discovery
`POST /api/sovereign/v1/billing/catalog`
1. Accepts instance-scoped request plus optional `categoryId`.
2. Returns canonical catalog contract `sc.billing.catalog.v1`.
3. Includes normalized `subscriptions[]` and `addons[]` for UI rendering.
4. Enables adding/changing purchasable products without plugin updates.
## 4. Publish-time flow
1. Plugin/broker receives write request.
2. Determine cost in credits.
3. Call consume endpoint with operation ref.
4. Attempt write/publish.
5. On success: done.
6. On failure: call refund endpoint.
Requirements:
1. operation ref must be globally unique.
2. no duplicate charges on retries.
## 5. Funding and reconciliation
Optional treasury automation keeps publishing identity funded against outstanding credit liabilities.
Reconciliation job:
1. compute required funding from credit liability + safety buffer.
2. compare to instance publishing-wallet balance.
3. queue transfer if below threshold.
4. store tx hash and reconciliation ref.
## 6. Idempotency and concurrency
Non-negotiable:
1. webhook ingest idempotent.
2. consume/refund idempotent.
3. atomic balance updates (transaction/row lock).
4. no negative balance race conditions.
## 7. Failure modes + handling
1. Duplicate webhook:
- ignored by unique `(instance_id,type,ref)`
2. Payment metadata missing instance_id:
- reject and quarantine event
3. Publish fails after consume:
- refund by same operation ref
4. Entitlement expired:
- block guaranteed-replication features; keep clear error state
## 8. Operational controls
1. Admin override endpoint for adjustments with audit trail.
2. Export ledger CSV/JSON for audit.
3. Alerting for:
- low balance
- funding failures
- degraded replication below plan target
## 9. Security controls
1. Verify payment webhooks cryptographically.
2. Restrict webhook endpoint exposure.
3. Separate service credentials for:
- payment ingest
- ledger mutation
- read-only dashboard queries
4. Redact sensitive fields in logs.
## 10. Implementation phases
1. Phase 1:
- ledger + balances + entitlements schema
- summary/read API
2. Phase 2:
- consume/refund idempotent endpoints
- broker integration
3. Phase 3:
- payment webhook ingest + entitlement update
4. Phase 4:
- intro grant workflow
- reconciliation/funding jobs
5. Phase 5:
- dashboards, exports, alerts