# 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