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>
1128 lines
38 KiB
Markdown
1128 lines
38 KiB
Markdown
# 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.0–14.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.3–14.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.0–14.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.0–14.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)
|