TorbatYar/docs/payment-roadmap.md
Mortezakoohjani 9fac160258 feat(payment): ship Torbat Pay MVP phases 14.0-14.5
Add independent payment-service (port 8012, payment_db) with foundation licensing, BYO-PSP, merchant accounts, idempotent requests, callbacks, and immutable ledger.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 17:57:04 +03:30

1128 lines
38 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Payment Platform — Enterprise Roadmap (Torbat Pay)
> Platform roadmap. Implementation proceeds phase-by-phase under the AI Framework.
> Framework: [ai-framework/](ai-framework/README.md) · ADR: [ADR-020](architecture/adr/ADR-020.md) · Manifests: [phase-manifest.yaml](ai-framework/phase-manifest.yaml), [service-manifest.yaml](ai-framework/service-manifest.yaml)
| Field | Value |
| --- | --- |
| Service | `payment` |
| Commercial Product | Torbat Pay |
| Database | `payment_db` |
| Permission Prefix | `payment.*` |
| API Port (reserved) | **8012** |
| Phases | **14.0 14.10** (manifest IDs: `payment-14.0``payment-14.10`) |
| Status | Pay-Reg complete; **payment-arch** complete; **payment-14.014.5** MVP implemented (v0.14.5.0); next `payment-14.6` Refunds |
| Architecture | [ADR-020](architecture/adr/ADR-020.md), [ADR-021](architecture/adr/ADR-021.md), [payment-contracts.md](reference/payment-contracts.md) |
## Phase Numbering Disambiguation
| Track | Manifest ID pattern | Example |
| --- | --- | --- |
| **Payment Platform** | `payment-14.x` | `payment-14.0` Payment Foundation |
| Beauty Business | `beauty-business-14.x` | `beauty-business-14.0` Beauty Foundation |
Both use numeric **14.x** in documentation tables; manifest IDs are always prefixed and never collide.
---
## Vision
Deliver an independent, multi-tenant **Enterprise Payment Platform** inside TorbatYar so every current and future service can accept, verify, refund, and reconcile payments without owning PSP credentials, callback endpoints, or payment transaction ledgers — and without duplicating business logic or sharing databases.
Torbat Pay supports:
- **Mode A — BYO-PSP:** Tenant connects and operates their own Payment Service Provider credentials.
- **Mode B — Torbat Pay Merchant:** Tenant uses Torbat Pay as payment facilitator; platform manages sub-merchant onboarding shells and settlement routing (implementation phased; architecture ready from registration).
Initial PSP catalog targets **Iranian gateways** (ZarinPal, IDPay, NextPay, Pay.ir, Mellat, Parsian, Saman, …). **International PSPs are out of scope for implementation now** but adapter contracts must accept `region`, `currency`, and `provider_family` metadata for future expansion.
---
## Business Goals
1. Single payment API for all TorbatYar verticals and future services.
2. Tenant choice between own PSP and Torbat Pay Merchant facilitator mode.
3. Idempotent payment requests, verifiable callbacks, immutable transaction ledger.
4. Settlement and accounting handoff via Accounting Posting Engine only.
5. PCI-aware credential storage patterns (secrets outside logs; vault refs in DB).
6. Future-ready provider registry without rewriting vertical integrations.
---
## Architecture Scope
| Rule | Reference |
| --- | --- |
| Independent service + `payment_db` | [ADR-020](architecture/adr/ADR-020.md), [ADR-001](architecture/adr/ADR-001.md) |
| Layering API → Service → Repository → Model | [service-architecture.md](architecture/service-architecture.md) |
| Tenant-aware business tables | [ADR-003](architecture/adr/ADR-003.md) |
| Outbox-ready events `payment.*` | [ADR-006](architecture/adr/ADR-006.md) |
| No journal ownership | [ADR-010](architecture/adr/ADR-010.md) |
| Receipt/notify via Communication only | [ADR-012](architecture/adr/ADR-012.md) |
| Vertical checkout context stays in vertical | [boundary-rules.md](ai-framework/boundary-rules.md) |
| Implementation via AI Framework | [ai-framework/](ai-framework/README.md) |
| Licensing & contracts | [ADR-021](architecture/adr/ADR-021.md), [payment-contracts.md](reference/payment-contracts.md) |
---
## Architectural prerequisites (complete before 14.0 code)
Documented in **payment-arch** phase. Implementation phases MUST NOT redefine these contracts without a new ADR and contract major version.
### Three-layer access control
| Layer | Owner | Purpose |
| --- | --- | --- |
| L1 Core entitlement | Core | `payment.module.enabled` — tenant may use Torbat Pay |
| L2 Payment bundle | Payment | Commercial packs: BYO-PSP, Torbat Pay Merchant, splits, refunds, … |
| L3 Feature toggle | Payment | Operational flags: refunds, installments, subscriptions, wallet top-up |
### Tenant independence guarantees
| Action | Mechanism | Code change required |
| --- | --- | --- |
| Enable Payment | Core L1 + workspace `enabled` + active L2 bundle | No |
| Disable Payment | workspace `disabled` | No |
| Choose BYO-PSP | `default_payment_mode=byo_psp` + `PspConnection` + assignment | No |
| Choose Torbat Pay Merchant | `default_payment_mode=torbat_pay_merchant` + `MerchantAccount` | No |
| Change PSP / routing | Update `PaymentProviderAssignment` + `PspRoutingPolicy` | No |
### Stable v1 contracts (see [payment-contracts.md](reference/payment-contracts.md))
PaymentIntent · CheckoutSession · CallbackIngress · SettlementIntent · RefundIntent (reserved) · SplitAllocation (reserved) · SubscriptionBilling (reserved) · WalletTopUp (reserved) · InstallmentPlan (Payment schedule shell) · CreditProvider (reserved)
### Torbat Credit — reserved independent service
| Field | Value |
| --- | --- |
| Service | `credit` (future) |
| Commercial product | **Torbat Credit** |
| Database | `credit_db` (reserved) |
| Event namespace | `credit.*` (reserved — **not** published by Payment) |
Payment recognizes **external Credit Providers** via the same adapter registry as PSPs. Future payment source **`CREDIT_PROVIDER`** is reserved in routing policy and PaymentIntent v1 — **not implemented** in HIGH-priority phases.
**Boundary:** `InstallmentPlanContract` inside Payment = schedule shell linked to captures. Installment calculation, scoring, KYC, BNPL, and financing are **exclusive to Torbat Credit**.
Architectural reference fields (opaque): `credit_provider_id`, `financing_reference`, `credit_authorization_reference`, `installment_contract_reference`.
See [ADR-021 §12](architecture/adr/ADR-021.md) and [payment-contracts.md](reference/payment-contracts.md).
### Platform compatibility (verified — no breaking changes in existing services)
| Service | Status | Integration pattern |
| --- | --- | --- |
| Core | ✅ | Entitlement API + `feature_access.changed` |
| Identity | ✅ | `user_ref` / payer refs only |
| Tenant (Core) | ✅ | `tenant_id` + workspace lifecycle |
| Accounting | ✅ | SettlementIntent events only ([ADR-010](architecture/adr/ADR-010.md)) |
| CRM | ✅ | `contact_ref` on payer |
| Communication | ✅ | Receipt/refund notify client |
| Hospitality | ✅ | POS/QR refs → PaymentIntent; subscribe `payment.request.paid` |
| Delivery | ✅ | Optional COD payment ref |
| Sports Center | ✅ | Membership payment refs |
| Marketplace | ✅ | Checkout + SplitAllocation (14.7+) |
| Torbat Credit (future) | ✅ | CreditProviderAdapter; Payment calls like PSP; `credit.*` owned by Credit service |
### Architecture verification
| Principle | Verified |
| --- | --- |
| API-first | ✅ REST + internal token APIs |
| Event-first | ✅ `payment.*` outbox |
| Database-per-service | ✅ `payment_db` sole owner |
| Feature toggles | ✅ L3 in Payment |
| Permission tree | ✅ Bundle-gated `payment.*` |
| Bundle isolation | ✅ Hidden routes/capabilities when inactive |
| Multi-tenant isolation | ✅ `tenant_id` + callback routing |
---
## Module Map
| Module | Responsibility | Phase |
| --- | --- | --- |
| Foundation / Workspace | Tenant payment workspace, enable/disable, mode flags | 14.0 |
| Bundle Licensing | PaymentBundleDefinition, TenantPaymentBundle (L2) | 14.0 |
| Feature Toggles | PaymentFeatureToggle (L3) | 14.0 |
| Provider Assignment | PaymentProviderAssignment shells | 14.0 / 14.1 |
| PSP Registry | Provider catalog, adapter protocol, capability flags | 14.0 / 14.1 |
| Credit Provider Registry | External credit adapter catalog (Torbat Credit reserved) | 14.0 shell / future |
| PSP Connections | Tenant BYO-PSP credentials, health, routing priority | 14.1 |
| Merchant Accounts | Sub-merchant / facilitator onboarding shells | 14.2 |
| Payment Requests | Initiate, idempotency, redirect/token payloads | 14.3 |
| Callbacks & Verification | PSP callbacks, signature verify, status reconcile | 14.4 |
| Transaction Ledger | Immutable payment transaction entries | 14.5 |
| Refunds & Reversals | Partial/full refund lifecycle | 14.6 |
| Split & Settlement | Multi-party splits; facilitator settlement intents | 14.7 |
| Vertical Connectors | Hospitality/Marketplace/Sports/Experience checkout contracts | 14.8 |
| Reconciliation | PSP vs ledger; Accounting posting intents | 14.9 |
| Analytics & Validation | Dashboards shells, fraud hooks, enterprise gates | 14.10 |
Canonical inventory: [module-registry.md](module-registry.md#payment).
---
## Integration Map
```
Verticals (Hospitality POS / Marketplace / Sports Center / Experience / CRM / …)
│ API / Events (checkout refs only — no shared DB)
Payment Platform (Torbat Pay)
├──Adapters──▶ PSPs (ZarinPal, IDPay, NextPay, Pay.ir, Mellat, …)
├──API/Events──▶ Accounting (settlement / reconciliation intents → Posting Engine)
├──API/Events──▶ Communication (payment receipt / failure notify)
├──API─────────▶ Core (entitlement, tenant)
└──API/Events──▶ CRM / Loyalty (optional customer refs — no ledger duplication)
```
**Forbidden:** cross-DB queries; verticals calling PSP APIs directly; Payment creating JournalEntry; Payment owning Hospitality order or Marketplace cart aggregates.
---
## Consumer Services (current and future)
| Service | Payment usage |
| --- | --- |
| Accounting | Consumes settlement intents; posts journals |
| Hospitality | POS Pro payments, QR ordering checkout |
| Marketplace / Ecommerce | Checkout capture, multi-vendor splits (later) |
| Sports Center | Membership/competition fees |
| Delivery | COD collection refs (optional) |
| Experience | Paid forms, appointment deposits |
| CRM | Quote-to-pay links (refs) |
| Loyalty | Paid wallet top-up via Payment (integration contract) |
| Healthcare / Beauty | Appointment/service prepayment |
| Automation | Trigger on `payment.transaction.paid` |
| Future services | Same Payment API — no re-analysis required |
---
## Phase Map
| Phase | ID | Name | Implementation Priority | Status |
| --- | --- | --- | --- | --- |
| Reg | `payment-reg` | Platform Registration | — | Complete |
| Arch | `payment-arch` | Architecture Prerequisites | — | Complete |
| 14.0 | `payment-14.0` | Payment Foundation | **HIGH** | Complete |
| 14.1 | `payment-14.1` | PSP Management | **HIGH** | Complete |
| 14.2 | `payment-14.2` | Merchant Accounts | **HIGH** | Complete |
| 14.3 | `payment-14.3` | Payment Requests | **HIGH** | Complete |
| 14.4 | `payment-14.4` | Callback & Verification | **HIGH** | Complete |
| 14.5 | `payment-14.5` | Transaction Ledger | **HIGH** | Complete |
| 14.6 | `payment-14.6` | Refunds & Reversals | LATER | Planned |
| 14.7 | `payment-14.7` | Split Payments & Facilitator Settlement | LATER | Planned |
| 14.8 | `payment-14.8` | Vertical Connectors & Checkout Contracts | LATER | Planned |
| 14.9 | `payment-14.9` | Reconciliation & Accounting Integration | LATER | Planned |
| 14.10 | `payment-14.10` | Analytics, Fraud Shells & Enterprise Validation | LATER | Planned |
Phase detail documents: [phases/Payment/](phases/Payment/README.md).
---
# Phase Specifications
---
## Phase 14.0 — Payment Foundation
| Field | Value |
| --- | --- |
| Phase ID | `payment-14.0` |
| Implementation Priority | **HIGH** |
### Purpose
Establish Torbat Pay as an independent enterprise microservice with foundation aggregates, health/capabilities/metrics, permission tree, publish-only event shells, tenant isolation, audit, and **provider protocol stubs only** — no live PSP calls.
### Business Scope
- Register payment workspace per tenant.
- Expose capability discovery for upcoming PSP, merchant, and checkout features.
- Document BYO-PSP vs Torbat Pay Merchant mode flags at configuration level (no facilitator onboarding yet).
### Technical Scope
- Service scaffold `backend/services/payment` (API → Service → Repository → Model).
- Foundation aggregates: PaymentWorkspace, PaymentRole, PaymentPermission, PaymentBundleDefinition, TenantPaymentBundle, PaymentFeatureToggle, PaymentProviderAssignment (shell), PspProviderRegistration (catalog shell), PaymentConfiguration, PaymentSetting, PaymentAuditLog, OutboxEvent.
- L1 gate: Core `payment.module.enabled` check client (stub in 14.0).
- Endpoints: `/health`, `/capabilities`, `/metrics`, foundation CRUD under `/api/v1/*`.
- Alembic `0001_initial`; compose port **8012**.
- Provider Protocol interfaces: `PspAdapter`, `AccountingClient`, `CommunicationClient`, `CrmClient` (stubs/mock).
### Dependencies
- `payment-reg`, `onboarding-4`, `ai-framework`
- Core entitlement (tenant context)
### Out of Scope
- Live PSP credentials (14.1)
- Merchant onboarding (14.2)
- Payment initiation/capture (14.314.5)
- Refunds, splits, connectors, reconciliation, analytics
### Capabilities (flags)
`payment.foundation`, `payment.workspace`, `payment.bundles`, `payment.feature_toggles`, `payment.provider_assignment_shell`, `payment.psp_registry_shell`, `payment.audit`
### Permissions
`payment.*` root; `payment.workspaces.{view,manage,enable,disable}`, `payment.bundles.*`, `payment.feature_toggles.*`, `payment.provider_assignments.*`, `payment.configurations.*`, `payment.settings.*`, `payment.psp_providers.view`, `payment.audit.view`, planned leaves per [payment-contracts.md](reference/payment-contracts.md).
### Events
`payment.workspace.created`, `payment.configuration.updated`, `payment.setting.upserted`, `payment.psp_provider.registered` (catalog shell)
### API Contracts
| Resource | Method / Path |
| --- | --- |
| Workspaces | CRUD `/api/v1/payment-workspaces` (+ enable/disable actions) |
| Bundle definitions | CRUD `/api/v1/bundle-definitions` |
| Tenant bundles | CRUD `/api/v1/tenant-bundles` |
| Feature toggles | CRUD `/api/v1/feature-toggles` |
| Provider assignments | CRUD `/api/v1/provider-assignments` (shell) |
| PSP provider catalog | CRUD `/api/v1/psp-provider-registrations` |
| Configurations | CRUD `/api/v1/configurations` |
| Settings | CRUD `/api/v1/settings` |
| Audit | GET `/api/v1/audit` |
| Discovery | GET `/health`, `/capabilities`, `/metrics` |
### Data Ownership
Payment sole owner: workspace, roles, permission catalog, provider registration metadata, configuration, settings, audit, outbox.
### Provider Ownership
Adapter **interfaces** owned by Payment; no vendor SDK in 14.0.
### Integration Rules
- No cross-DB access.
- Verticals must not import payment models.
- Accounting/Communication accessed via client protocols only.
### Quality Gates
Architecture, tenant isolation, permissions, migration, dependency, security, documentation validation per [quality-gates.md](ai-framework/quality-gates.md).
### Definition of Done
- Service boots on 8012; tests green; manifests/snapshot/handover updated; no PSP payment flow.
### Future Compatibility
- `PspProviderRegistration` includes `region`, `currency_codes[]`, `provider_family`, `supports_facilitator_mode` for international expansion.
- Workspace stores `default_payment_mode`: `byo_psp` | `torbat_pay_merchant`.
---
## Phase 14.1 — PSP Management
| Field | Value |
| --- | --- |
| Phase ID | `payment-14.1` |
| Implementation Priority | **HIGH** |
### Purpose
Enable tenants to connect **BYO-PSP** credentials, register adapter implementations, and route payments by priority with health checks — Iranian PSPs first (mock + at least one real adapter stub).
### Business Scope
- Tenant admin connects ZarinPal / IDPay / NextPay / Pay.ir / Mellat / Parsian / Saman credentials.
- Test connection and mark PSP connection active/suspended.
- Failover priority list per tenant (primary/secondary PSP).
### Technical Scope
- Aggregates: PspConnection, PspCredentialVaultRef, PspConnectionHealthCheck, PspRoutingPolicy.
- Adapter registry with `MockPspAdapter` + stub adapters per provider family.
- Encrypt/store credential refs (no plaintext secrets in API responses).
- APIs: connect, test, rotate credential ref, suspend, set routing priority.
### Dependencies
- `payment-14.0`
### Out of Scope
- Torbat Pay Merchant sub-accounts (14.2)
- Payment capture (14.3)
- Callback handling (14.4)
- International PSP live integrations
### Capabilities
`payment.psp_connections`, `payment.psp_routing`, `payment.psp_health_check`
### Permissions
`payment.psp_connections.view|create|update|delete|test|manage`, `payment.psp_routing.manage`
### Events
`payment.psp_connection.created|updated|suspended|activated`, `payment.psp_connection.tested`, `payment.psp_routing.updated`
### API Contracts
| Resource | Path |
| --- | --- |
| PSP connections | `/api/v1/psp-connections` |
| Routing policies | `/api/v1/psp-routing-policies` |
| Health checks | POST `/api/v1/psp-connections/{id}/test` |
### Data Ownership
Payment owns connection metadata, routing policies, health check history; vault refs point to secret store — not Core DB.
### Provider Ownership
PSP vendor SDKs live in Payment adapter layer only; verticals forbidden.
### Integration Rules
- Credential rotation must not orphan in-flight payment requests (document migration policy).
- Adapter protocol versioned (`adapter_version`).
### Quality Gates
+ secret redaction tests, tenant isolation, adapter contract tests.
### Definition of Done
- Tenant can register/test/suspend PSP connection; routing policy persisted; events published; no payment capture yet.
### Future Compatibility
- `region` + `currency` on connections; adapter slot for Stripe/PayPal without schema break.
---
## Phase 14.2 — Merchant Accounts
| Field | Value |
| --- | --- |
| Phase ID | `payment-14.2` |
| Implementation Priority | **HIGH** |
### Purpose
Introduce **Torbat Pay Merchant** (facilitator) sub-merchant account shells so tenants can accept payments through platform facilitator mode alongside BYO-PSP.
### Business Scope
- Tenant onboarding as Torbat Pay sub-merchant (KYC/KYB **refs only** — no document storage binaries).
- Merchant account lifecycle: draft → pending_review → active → suspended → closed.
- Link merchant account to workspace; optional branch/vertical refs.
### Technical Scope
- Aggregates: MerchantAccount, MerchantAccountProfile, MerchantSettlementProfile, MerchantComplianceRef, MerchantAccountStatusHistory.
- Facilitator configuration at platform level (PaymentSetting keys).
- APIs for create/submit/activate/suspend merchant account.
### Dependencies
- `payment-14.1`
### Out of Scope
- Live KYC vendor integration
- Actual fund settlement to bank accounts (14.7/14.9)
- Payment capture (14.3)
### Capabilities
`payment.merchant_accounts`, `payment.facilitator_mode`
### Permissions
`payment.merchant_accounts.view|create|update|submit|activate|suspend|close|manage`
### Events
`payment.merchant_account.created|submitted|activated|suspended|closed`
### API Contracts
| Resource | Path |
| --- | --- |
| Merchant accounts | `/api/v1/merchant-accounts` |
| Settlement profiles | `/api/v1/merchant-settlement-profiles` |
| Status actions | POST `.../submit`, `.../activate`, `.../suspend` |
### Data Ownership
Payment owns merchant account domain; Identity owns users; File Storage owns compliance document blobs (refs only).
### Provider Ownership
Facilitator PSP credentials are platform-scoped Payment settings — not tenant BYO connections.
### Integration Rules
- Merchant account required when `default_payment_mode=torbat_pay_merchant`.
- BYO-PSP mode bypasses merchant account for capture routing.
### Quality Gates
Lifecycle transition tests, forbidden plaintext PII in logs, tenant isolation.
### Definition of Done
- Merchant account CRUD + lifecycle; facilitator flag on workspace; no payment requests yet.
### Future Compatibility
- Multi-currency settlement profile; international merchant descriptors.
---
## Phase 14.3 — Payment Requests
| Field | Value |
| --- | --- |
| Phase ID | `payment-14.3` |
| Implementation Priority | **HIGH** |
### Purpose
Allow any vertical to create **idempotent payment requests** with amount, currency (IRR first), payer refs, and commercial context refs — returning redirect URL / token / QR payload from selected PSP.
### Business Scope
- Initiate payment for order/invoice/membership/checkout session refs.
- Support BYO-PSP routing (14.1) or facilitator merchant (14.2).
- Expire abandoned requests; single active capture per idempotency key.
### Technical Scope
- Aggregates: PaymentRequest, PaymentRequestLine (optional), PaymentRequestStatusHistory.
- Idempotency-Key header enforcement.
- State machine: draft → pending → redirect_issued → processing → (terminal: paid|failed|expired|cancelled).
- Adapter call: `initiate_payment()` only; no local ledger mutation beyond request state.
### Dependencies
- `payment-14.2`, active PSP connection or merchant account
### Out of Scope
- Callback verification (14.4)
- Immutable transaction ledger (14.5)
- Refunds (14.6)
### Capabilities
`payment.requests`, `payment.initiate`, `payment.idempotency`
### Permissions
`payment.requests.view|create|cancel|manage`; service-to-service `payment.requests.create` (internal)
### Events
`payment.request.created|redirect_issued|expired|cancelled|failed`
### API Contracts
| Resource | Path |
| --- | --- |
| Payment requests | POST/GET `/api/v1/payment-requests` |
| Cancel | POST `/api/v1/payment-requests/{id}/cancel` |
| Internal initiate | POST `/internal/v1/payment-requests` (token-gated) |
Payload includes: `amount_minor`, `currency`, `idempotency_key`, `source_service`, `source_ref_type`, `source_ref_id`, `payer_contact_ref`, `metadata`, `return_url`, `callback_url`.
### Data Ownership
Payment owns request lifecycle; vertical owns commercial aggregate (order/ticket/invoice).
### Provider Ownership
PSP initiate APIs invoked only inside Payment adapters.
### Integration Rules
- Vertical passes refs only — never PSP credentials.
- Duplicate idempotency key returns same request (200/409 policy documented).
### Quality Gates
Idempotency tests, amount validation, tenant isolation, state machine guards.
### Definition of Done
- End-to-end initiate with mock adapter; redirect payload returned; events emitted; ledger not final until 14.4/14.5.
### Future Compatibility
- Multi-currency amounts; tokenized card flows (metadata slots); wallet debit refs.
---
## Phase 14.4 — Callback & Verification
| Field | Value |
| --- | --- |
| Phase ID | `payment-14.4` |
| Implementation Priority | **HIGH** |
### Purpose
Receive PSP callbacks/webhooks, verify signatures, reconcile status with PSP verify API, and transition payment requests to verified paid/failed states.
### Business Scope
- Trusted callback ingestion per PSP adapter.
- Manual reconcile/admin retry for stuck requests.
- Publish domain events for verticals to mark orders paid.
### Technical Scope
- Aggregates: PaymentCallbackLog (append-only), PaymentVerificationAttempt.
- Public callback routes: `/api/v1/callbacks/{provider_code}/{connection_id}` (design per adapter).
- Signature verification, replay protection (nonce/timestamp window), idempotent callback processing.
- Adapter `verify_payment()` + `parse_callback()`.
### Dependencies
- `payment-14.3`
### Out of Scope
- Immutable financial ledger entries (14.5) — may dual-write transition hooks but ledger is 14.5 authority
- Refunds
- Accounting posting
### Capabilities
`payment.callbacks`, `payment.verification`, `payment.webhooks`
### Permissions
`payment.callbacks.view` (admin), `payment.requests.reconcile|manage`; callbacks unauthenticated with signature gate
### Events
`payment.callback.received|verified|rejected`, `payment.request.paid|failed`
### API Contracts
| Resource | Path |
| --- | --- |
| PSP callbacks | POST `/api/v1/callbacks/{provider_code}/{connection_id}` |
| Verify retry | POST `/api/v1/payment-requests/{id}/verify` |
| Callback logs | GET `/api/v1/payment-callback-logs` |
### Data Ownership
Payment owns callback logs and verification attempts; PSP owns authoritative transaction ids (stored as refs).
### Provider Ownership
Webhook secrets validated in Payment adapter layer.
### Integration Rules
- Callback handlers must be fast — async verify via worker allowed.
- Never trust client-side return URL alone; always verify with PSP.
### Quality Gates
Signature forgery tests, replay tests, tenant routing isolation.
### Definition of Done
- Mock callback → verified paid flow; events to outbox; vertical can subscribe.
### Future Compatibility
- Multiple callback versions per PSP; international webhook formats.
---
## Phase 14.5 — Transaction Ledger
| Field | Value |
| --- | --- |
| Phase ID | `payment-14.5` |
| Implementation Priority | **HIGH** |
### Purpose
Maintain an **immutable append-only payment transaction ledger** as the system of record for captured payments — distinct from Accounting journals.
### Business Scope
- Record paid transactions with PSP refs, fees, net amounts, merchant account linkage.
- Query ledger for tenant admin and service-to-service status checks.
- Support facilitator fee lines (metadata) without Accounting posting.
### Technical Scope
- Aggregates: PaymentTransaction (immutable after insert), PaymentTransactionFeeLine, PaymentLedgerEntry (append-only).
- No UPDATE on monetary fields post-insert; corrections via reversal entries (14.6).
- Link transaction 1:1 (or 1:n partial) to PaymentRequest.
### Dependencies
- `payment-14.4`
### Out of Scope
- Refund entries (14.6)
- Accounting journal creation
- Split allocation (14.7)
### Capabilities
`payment.ledger`, `payment.transactions`
### Permissions
`payment.transactions.view|export|manage` (manage = admin tools only, not mutate amounts)
### Events
`payment.transaction.recorded`, `payment.ledger.entry_appended`
### API Contracts
| Resource | Path |
| --- | --- |
| Transactions | GET `/api/v1/payment-transactions`, GET `/{id}` |
| By source ref | GET `/api/v1/payment-transactions/by-source` |
| Ledger entries | GET `/api/v1/payment-ledger-entries` |
### Data Ownership
Payment owns payment-domain ledger; Accounting owns GL journals.
### Provider Ownership
PSP transaction ids stored as external refs only.
### Integration Rules
- Verticals query Payment for payment status — not vice versa polling vertical DBs.
- Ledger write occurs only after verified paid (14.4).
### Quality Gates
Immutability tests, append-only constraints, tenant isolation, correlation id traceability.
### Definition of Done
- Paid flow produces ledger entries; queries work; HIGH priority MVP path complete (14.014.5).
### Future Compatibility
- Multi-currency ledger partitions; facilitator settlement batch ids.
---
## Phase 14.6 — Refunds & Reversals
| Field | Value |
| --- | --- |
| Phase ID | `payment-14.6` |
| Implementation Priority | **LATER** |
### Purpose
Support full and partial refunds with PSP adapter calls, idempotency, and ledger reversal entries.
### Business Scope
- Merchant-initiated refunds linked to original transaction.
- Track refund status: requested → processing → succeeded|failed.
- Notify payer via Communication on refund completion.
### Technical Scope
- Aggregates: RefundRequest, RefundStatusHistory, PaymentLedgerEntry (type=reversal).
- Adapter `refund_payment()`.
- Partial refund sum ≤ captured amount invariant.
### Dependencies
- `payment-14.5`, Communication client
### Out of Scope
- Chargeback dispute workflow (future)
- Accounting credit note posting (14.9 intents only)
### Capabilities
`payment.refunds`
### Permissions
`payment.refunds.view|create|manage`
### Events
`payment.refund.requested|succeeded|failed`
### API Contracts
POST `/api/v1/refund-requests`; GET `/api/v1/refund-requests/{id}`
### Data Ownership
Payment owns refund domain; vertical owns return/RMA context ref.
### Provider Ownership
PSP refund APIs via adapters only.
### Integration Rules
- Refund requires original transaction in paid state.
- Idempotency on refund requests.
### Quality Gates
Partial refund math, PSP failure handling, ledger reversal integrity.
### Definition of Done
- Mock refund flow with ledger reversal and event publish.
### Future Compatibility
- Multi-currency refund; facilitator pass-through fee reversal lines.
---
## Phase 14.7 — Split Payments & Facilitator Settlement
| Field | Value |
| --- | --- |
| Phase ID | `payment-14.7` |
| Implementation Priority | **LATER** |
### Purpose
Allocate captured funds across multiple parties (marketplace sellers, branches) and emit **facilitator settlement intents** for Torbat Pay Merchant mode.
### Business Scope
- Split rules: fixed, percentage, remainder-to-platform.
- Settlement batch shells for facilitator payouts.
- Marketplace multi-vendor ready.
### Technical Scope
- Aggregates: PaymentSplitRule, PaymentSplitAllocation, SettlementBatch, SettlementBatchLine.
- APIs to define splits on payment request; compute allocations on capture.
- Events for Accounting consumption (intent only).
### Dependencies
- `payment-14.5`, `payment-14.2` (facilitator mode)
### Out of Scope
- Bank payout execution
- Accounting journal creation
### Capabilities
`payment.splits`, `payment.settlement_batches`
### Permissions
`payment.splits.manage`, `payment.settlement_batches.view|manage`
### Events
`payment.split.allocated`, `payment.settlement_batch.created|closed`
### API Contracts
CRUD `/api/v1/payment-split-rules`; POST `/api/v1/settlement-batches`; POST `.../close`
### Data Ownership
Payment owns split/settlement batch domain; Accounting owns cash movement journals.
### Provider Ownership
Facilitator payout rails via future adapter; not in 14.7 MVP.
### Integration Rules
- Sum of allocations = captured amount (minor units).
- Marketplace passes seller refs — not seller bank details in vertical DB.
### Quality Gates
Allocation math tests, batch close invariants, tenant isolation.
### Definition of Done
- Split on capture with settlement intent events; no bank transfer.
### Future Compatibility
- Cross-border split currency conversion metadata.
---
## Phase 14.8 — Vertical Connectors & Checkout Contracts
| Field | Value |
| --- | --- |
| Phase ID | `payment-14.8` |
| Implementation Priority | **LATER** |
### Purpose
Publish versioned **consumer connector contracts** so Hospitality, Marketplace, Sports Center, Experience, CRM, Healthcare, Beauty, Delivery, and future services integrate without custom per-vertical code in Payment.
### Business Scope
- Standard checkout session contract: create → pay → confirm.
- Embedded widget / redirect checkout API shapes documented.
- Connector registration per vertical with capability flags.
### Technical Scope
- Aggregates: PaymentConnectorRegistration, PaymentConnectorDispatch, CheckoutSession (refs to vertical source).
- Mock connectors for Hospitality POS and Marketplace order refs.
- Internal APIs documented in OpenAPI companion.
### Dependencies
- `payment-14.5`
### Out of Scope
- Vertical-side implementation (each vertical phase owns connector client)
- Frontend checkout UI (frontend module)
### Capabilities
`payment.connectors`, `payment.checkout_sessions`
### Permissions
`payment.connectors.manage`, `payment.checkout_sessions.create|view`
### Events
`payment.connector.registered`, `payment.checkout_session.created|completed|expired`
### API Contracts
CRUD `/api/v1/payment-connector-registrations`; POST `/api/v1/checkout-sessions`; POST `.../complete`
### Data Ownership
Payment owns checkout session shell; vertical owns order/ticket/invoice aggregate.
### Provider Ownership
N/A — connector layer is Payment-owned contract surface.
### Integration Rules
- One checkout session maps to one payment request chain.
- Vertical must subscribe to `payment.transaction.recorded` or poll transaction API.
### Quality Gates
Connector contract tests, forbidden cross-DB imports, mock vertical dispatch tests.
### Definition of Done
- Two mock vertical connectors documented and tested; contract doc published.
### Future Compatibility
- SDK stubs for mobile/web; webhook subscription registry.
---
## Phase 14.9 — Reconciliation & Accounting Integration
| Field | Value |
| --- | --- |
| Phase ID | `payment-14.9` |
| Implementation Priority | **LATER** |
### Purpose
Reconcile PSP settlement reports with payment ledger and emit **Accounting posting intents** (revenue, fees, facilitator payable) via API/events only.
### Business Scope
- Import PSP settlement file metadata (refs to File Storage).
- Mark transactions reconciled / exception.
- Daily reconciliation report shells.
### Technical Scope
- Aggregates: ReconciliationRun, ReconciliationException, AccountingPostingIntent.
- AccountingClient mock + event `payment.accounting_intent.created`.
- No JournalEntry in Payment service.
### Dependencies
- `payment-14.5`, Accounting service (contract), optional `payment-14.7`
### Out of Scope
- Tax/e-invoice (Accounting/future compliance)
- Automatic bank feed matching
### Capabilities
`payment.reconciliation`, `payment.accounting_integration`
### Permissions
`payment.reconciliation.view|run|manage`, `payment.accounting_intents.view`
### Events
`payment.reconciliation.started|completed`, `payment.reconciliation.exception.created`, `payment.accounting_intent.created`
### API Contracts
POST `/api/v1/reconciliation-runs`; GET exceptions; GET `/api/v1/accounting-posting-intents`
### Data Ownership
Payment owns reconciliation state; Accounting owns posted vouchers.
### Provider Ownership
PSP settlement files fetched via adapter or manual upload ref.
### Integration Rules
- Idempotent posting intents (Accounting dedupes by intent id).
- Never double-post on reconciliation retry.
### Quality Gates
Intent idempotency, no local journal tables, reconciliation exception workflow tests.
### Definition of Done
- Reconciliation run marks ledger rows; accounting intent event emitted; Accounting not modified in this phase.
### Future Compatibility
- Multi-PSP consolidated reconciliation; FX adjustment intents.
---
## Phase 14.10 — Analytics, Fraud Shells & Enterprise Validation
| Field | Value |
| --- | --- |
| Phase ID | `payment-14.10` |
| Implementation Priority | **LATER** |
### Purpose
Close the Payment track with analytics snapshots, optional fraud/rule hooks, and full AI Framework enterprise validation.
### Business Scope
- Tenant payment KPIs: volume, success rate, average ticket, refund rate.
- Fraud rule shells (velocity, amount threshold) — optional, off by default.
- Production readiness sign-off.
### Technical Scope
- Aggregates: PaymentAnalyticsReportDefinition, PaymentAnalyticsSnapshot, FraudRuleRegistration, FraudCheckDispatch (mock).
- Enterprise validation audit doc.
- Self-heal test suite until green.
### Dependencies
- `payment-14.9`, `ai-framework`
### Out of Scope
- ML fraud models
- PCI certification (operational program outside code phase)
### Capabilities
`payment.analytics`, `payment.fraud_hooks`, `payment.enterprise_validation`
### Permissions
`payment.analytics.view|refresh`, `payment.fraud_rules.manage`
### Events
`payment.analytics.snapshot.created`, `payment.fraud_check.dispatched`
### API Contracts
CRUD `/api/v1/analytics-report-definitions`; POST `/api/v1/analytics-snapshots/refresh`
### Data Ownership
Payment owns analytics snapshots (local aggregates only).
### Provider Ownership
External fraud vendors via adapter registry (stub).
### Integration Rules
- Analytics queries Payment DB only — no cross-service DB reads.
- Core flows work when fraud hooks disabled.
### Quality Gates
Full quality gate suite from [quality-gates.md](ai-framework/quality-gates.md); architecture/security/performance/docs/integration/tenant isolation.
### Definition of Done
- Track 14.014.10 complete; snapshot at `0.14.10.0`; no undocumented public API/event/permission.
### Future Compatibility
- Real-time metrics export; international fraud provider adapters.
---
## Platform Expose (every implementation phase)
Health API · Capability API · Metrics · Events · REST APIs · Permission APIs
## Out of Scope (platform-wide)
- Owning Accounting ledgers or Posting Engine
- Owning vertical order/cart/invoice aggregates
- Owning Communication providers
- International PSP live integrations (initial HIGH phases)
- PCI SAQ execution (operational)
- Payment UI in backend service
## Related Documents
- [Phase Area README](phases/Payment/README.md)
- [ADR-020](architecture/adr/ADR-020.md) · [ADR-021](architecture/adr/ADR-021.md)
- [Payment Contracts](reference/payment-contracts.md)
- [Module Registry](module-registry.md#payment)
- [Service Snapshot](service-snapshots/payment.yaml)
- [Phase Handover Pay-Reg](phase-handover/phase-pay-reg.md)
- [Progress](progress.md)
- [Next Steps](next-steps.md)