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>
38 KiB
Payment Platform — Enterprise Roadmap (Torbat Pay)
Platform roadmap. Implementation proceeds phase-by-phase under the AI Framework.
Framework: ai-framework/ · ADR: ADR-020 · Manifests: phase-manifest.yaml, 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, ADR-021, 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
- Single payment API for all TorbatYar verticals and future services.
- Tenant choice between own PSP and Torbat Pay Merchant facilitator mode.
- Idempotent payment requests, verifiable callbacks, immutable transaction ledger.
- Settlement and accounting handoff via Accounting Posting Engine only.
- PCI-aware credential storage patterns (secrets outside logs; vault refs in DB).
- Future-ready provider registry without rewriting vertical integrations.
Architecture Scope
| Rule | Reference |
|---|---|
Independent service + payment_db |
ADR-020, ADR-001 |
| Layering API → Service → Repository → Model | service-architecture.md |
| Tenant-aware business tables | ADR-003 |
Outbox-ready events payment.* |
ADR-006 |
| No journal ownership | ADR-010 |
| Receipt/notify via Communication only | ADR-012 |
| Vertical checkout context stays in vertical | boundary-rules.md |
| Implementation via AI Framework | ai-framework/ |
| Licensing & contracts | ADR-021, 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)
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 and 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) |
| 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.
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/.
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.enabledcheck 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.
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.
Definition of Done
- Service boots on 8012; tests green; manifests/snapshot/handover updated; no PSP payment flow.
Future Compatibility
PspProviderRegistrationincludesregion,currency_codes[],provider_family,supports_facilitator_modefor 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+currencyon 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.recordedor 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), optionalpayment-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; 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