67 lines
7.1 KiB
Markdown
67 lines
7.1 KiB
Markdown
# Phase 1E provider-independent blueprint
|
|
|
|
The user chose a blueprint and test cases before purchasing a gateway. No payment, shipping or messaging provider is selected or registered. Fake gateway code exists only under test/helpers; its HMAC format is illustrative and must never be treated as a production provider protocol.
|
|
|
|
## Implemented now
|
|
|
|
- Inactive-by-default, immutable pricing policy versions with explicit tax and shipping settings.
|
|
- Checkout snapshots of configured final totals, with database reconciliation and preserved historical prices.
|
|
- Transactional order-created/order-cancelled events, leased delivery, bounded retries and safe diagnostics.
|
|
- Authorized operational summary, event inspection and retry APIs.
|
|
- Gateway contracts and pure decision policies for capture validation, late capture compensation, refund bounds, partial shipping and returns.
|
|
- Fake-provider contract tests and database integration tests.
|
|
|
|
There are no production payment/capture/refund/webhook/shipment/return endpoints. No real payment or notification is sent. Order status remains the Phase 1D pending/cancelled model. Payment and fulfillment decisions are tested policies, not a persisted live payment lifecycle.
|
|
|
|
## Integration boundaries
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
Checkout --> PricingSnapshot
|
|
Checkout --> Order
|
|
Order --> TransactionalEvents
|
|
TransactionalEvents --> LeasedDelivery
|
|
LeasedDelivery --> DeliveryAdapter["Future notification adapter"]
|
|
GatewayAdapter["Future gateway adapter"] --> VerifiedCapture
|
|
VerifiedCapture --> CapturePolicy
|
|
CapturePolicy --> StockCommit["Future transactional stock commit"]
|
|
CapturePolicy --> ReviewRefund["Late/mismatched capture review"]
|
|
```
|
|
|
|
GatewayPort defines idempotent payment creation, raw-byte capture verification and refund submission. Money crosses the provider boundary as canonical integer minor-unit strings with currency. Never accept amounts, successful payment flags or fulfillment authorization from the frontend. Normalize a provider's verified payload into CapturedPayment, then compare it with server-stored references and totals.
|
|
|
|
Capture decisions reject reference, amount and currency mismatches. Duplicate captured payments cause no additional stock commitment. A cancelled or expired order requires review and compensation, even if the provider says payment succeeded: its stock may already have been allocated elsewhere. Do not automatically refund from this pure decision function; a persisted, idempotent refund workflow must execute that decision.
|
|
|
|
Refund eligibility subtracts completed and pending refunds from captured money. Gateway acceptance means PENDING, not refunded. Only verified terminal provider state may mark a refund completed.
|
|
|
|
## Persistence required when a gateway is selected
|
|
|
|
Add new timestamped migrations for payment attempts, authenticated event receipts, refund requests and state transitions. Enforce unique provider/event IDs and compare payload digests when a repeated event ID arrives. Store an idempotency key before network work. Do not hold database locks while calling providers.
|
|
|
|
Process verified capture under order/stock locks in one transaction: recheck expiry, references and amount, commit each reserved quantity once, update payment/order state, preserve paid coupon usage, append ledger/audit records and enqueue notifications. Persist unmatched or late captures for reconciliation and compensation. Cancellation after capture must use refund policy, not the current pending-order cancellation route.
|
|
|
|
Refund requests must lock the payment while reserving refund capacity; pending amounts count against the refundable balance. Provider calls and callbacks need durable retry/reconciliation. Never interpret a timeout as proof that the external write failed.
|
|
|
|
Shipping persistence should include shipment lines and carrier events. Check paid eligibility and remaining quantities under locks before booking partial shipments. Track provider references and deduplicate events; out-of-order tracking must not regress delivery state. Do not conflate booking, dispatch and delivery.
|
|
|
|
Returns need request lines, delivered quantities, configurable time windows, approval and receipt/QC states. Pending returns reserve eligibility. Refund and restock are separate actions: a requested/approved return does not prove that inventory was physically received or saleable.
|
|
|
|
## Acceptance test matrix
|
|
|
|
| Area | Tests now | Required provider-stage tests |
|
|
| ---------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
| Payment creation | Same-key replay; changed input rejected by fake adapter | Timeout reconciliation and durable attempt recovery |
|
|
| Webhooks | Fake signature, raw-byte tampering, malformed and oversized payloads | Selected provider signatures, key rotation, actual event payloads and persisted replay protection |
|
|
| Capture | References, exact amount/currency, duplicate and late/cancelled cases | Atomic payment/stock/ledger commit under real PostgreSQL races |
|
|
| Refunds | Completed + pending bounds; fake retry idempotency | Partial refunds, concurrent limits, provider failure/reconciliation |
|
|
| Shipping | Paid eligibility, partial quantity bounds, monotonic tracking | Provider booking, replay, split shipment and tracking fixtures |
|
|
| Returns | Delivered/pending/returned bounds and explicit window | Approval, receipt/QC, separate restock/refund transactions |
|
|
| Pricing | Inclusive/exclusive arithmetic, rounding, region selection, immutable snapshots | Approved tax treatment, invoices, product tax classes and shipping services |
|
|
| Notifications | Atomic enqueue, leases, backoff, retries, redacted failures | Real adapter deduplication and delivery receipts |
|
|
|
|
The current tax calculator supports one configured merchandise rate per matching geographic policy, plus a shipping rate. Test values are synthetic and are not tax advice or the store's approved rates. Mixed tax classes, invoice requirements, provider shipping quotations and real business rules must be designed before production enablement.
|
|
|
|
## Before enabling providers
|
|
|
|
Select the gateway and shipping/messaging services, implement their official adapters, run their sandbox fixtures and persist the workflows above. Keep raw webhook bytes available only at the gateway boundary and redact credentials and personal information from logs. Use environment-managed secrets, native PostgreSQL concurrency checks and an independent VAPT of the deployed service. Purchasing a gateway is not needed to run the current tests.
|