feat: Implement return and refund functionality in commerce module
CI / test (push) Successful in 10m27s

- Added return request handling in return.controller.js
- Implemented webhook handling for PayHere payments in webhook.controller.js
- Created models for coupon redemptions, invoices, orders, order items, payments, payment attempts, payment webhook events, refunds, return items, and return requests.
- Developed services for order management, payment processing, refunds, and returns.
- Introduced validation schemas for payment and return requests.
- Created migration scripts for new database tables related to orders, payments, refunds, and returns.
- Added unit tests for order state transitions and PayHere provider functionality.
This commit is contained in:
Sathira Sri Sathara
2026-09-09 12:39:57 +05:30
parent ad9287b804
commit cd2c1c6d08
38 changed files with 192 additions and 4 deletions
+42
View File
@@ -0,0 +1,42 @@
# Orders and Payments API
All `/api/v1` customer endpoints derive ownership from authentication.
## Orders
- `POST /orders/from-checkout` converts an owned READY checkout. Conversion locks the checkout, verifies ACTIVE reservations, copies immutable snapshots, converts the cart, and is idempotent by unique checkout ID.
- `GET /orders` and `GET /orders/:id` provide owner-scoped history/detail.
- `POST /orders/:id/cancel` releases unpaid reservations. Paid orders require an explicit refund.
- Admin: `GET /admin/orders`, `GET /admin/orders/:id`, cancel, and mark-processing action endpoints.
Legal transitions are centralized. Payment, order, and fulfillment status are separate.
## Payments and webhooks
- `POST /orders/:id/payment`, `GET /orders/:id/payment`
- `POST /payments/webhooks/payhere` is unauthenticated at the session layer but requires the PayHere merchant hash.
Online browser redirects are never authoritative. A verified webhook must match local payment reference, currency, and DECIMAL amount. Unique provider event IDs make retries idempotent. A first successful event consumes each reservation once, records coupon redemption, marks payment/order paid, and issues invoice metadata. Failure does not consume inventory.
PayHere configuration uses `PAYHERE_MERCHANT_ID`, `PAYHERE_MERCHANT_SECRET`, and notify/return/cancel URLs. Stripe has an explicit disabled adapter until its official SDK and webhook secret are configured. No raw card or provider secret is accepted or returned.
## Invoices
- `GET /orders/:id/invoice` is owner-scoped.
Invoice numbers use the locked ReferenceNumber sequence. Invoice metadata is created once per paid order. PDF generation is reserved for the existing document worker integration; no second PDF/storage subsystem was introduced.
## Refunds
- `POST /admin/orders/:id/refunds` requires `payments.refund` and `Idempotency-Key`.
Requested item quantities and captured totals are locked and validated. A refund never restocks inventory automatically. Provider refund execution remains disabled until provider API credentials/workflows are validated.
## Returns
- Customer: `POST /orders/:orderId/returns`, `GET /returns`, `GET /returns/:id`.
- Admin: list, approve, reject, mark-received, and complete actions.
The return window uses `RETURN_WINDOW_DAYS` (default 30). Quantity cannot exceed the remaining purchased quantity. Only accepted RESTOCKABLE items are added through the inventory service; damaged/non-restockable items are not. EXCHANGE records intent only.
Business credit purchasing is intentionally disabled: no locked credit ledger was added without an approved accounting policy. Delivery, loyalty, support AI, and analytics are outside Phase 7.
+3
View File
@@ -417,3 +417,6 @@ Date: 2026-09-03. Inventory/reservation foundations, business pricing, promotion
## Phase 6 Completion Update
Date: 2026-09-03. Module 06 is 91%, Module 08 is 84%, and Module 07 is revised to 86%. Authenticated cart is 92%, wishlist 92%, shipping 86%, checkout 88%, and reservation integration 90%. Nine models, a forward-only migration, owner-scoped shopping APIs, permission-protected shipping administration, server-authoritative totals, atomic inventory reservation composition, idempotent checkout creation, and bounded expiry/cancellation release are implemented. Verification passes 20 suites/95 tests and 258 JavaScript syntax checks. The migration was not executed. Before Phase 7, staging must precheck legacy shopping/shipping tables and address/currency compatibility, seed shipping configuration/permissions, apply migrations, and validate real multi-connection InnoDB concurrency plus multi-instance expiry behavior.
## Phase 7 Completion Update
Date: 2026-09-09. Module 09 is 86%, Module 10 is 76%, and Module 13 is revised to 82%. Orders are 90%, payments 78%, invoices 72%, refunds 68%, returns 82%, coupon redemption 80%, and verified-purchase reviews 90%. Eleven commerce models, a forward-only migration, transactional checkout conversion, owner/admin APIs, explicit state machines, verified/idempotent webhook processing, payment-time inventory consumption, invoice sequencing, itemized refund validation, RMA handling, and return-only restocking were added. Migration and real provider/MySQL/document-worker validation remain staging requirements. Module 16 AI Customer Support Chatbot is intentionally excluded from this backend and planned as a separate service.
+84
View File
@@ -0,0 +1,84 @@
# ZUMRI Phase 7 Orders and Payments
## Objective
Convert checkout snapshots into durable orders and establish authoritative payment, invoice, refund, and return lifecycles without delivery or rewards.
## Existing Components Reused
Checkout snapshots, inventory reservations, pricing money helpers, coupons, ReferenceNumber, document infrastructure, audit queue, authentication, and permissions.
## Order Architecture
Order/payment/fulfillment states are independent. Commercial and address/shipping details are immutable snapshots.
## Checkout Conversion
The centralized transaction locks an owned READY checkout, verifies reservations, returns any existing order, copies items, and converts checkout/cart.
## Order State Machine
Explicit transition sets reject illegal terminal-state transitions and arbitrary status patches.
## Order Snapshots
Items retain product/variant IDs, reservation key, SKU, names, quantity, unit price, discount, total, currency, and limited metadata.
## Payment Architecture
Payments retain immutable attempts. Only server/provider reconciliation changes authoritative financial state.
## Provider Adapters
Generic payment logic delegates verification/parsing/initiation/refund/status behavior to provider modules.
## PayHere
Merchant secrets are environmental. Browser redirects are non-authoritative; the notify hash, reference, amount, and currency must validate.
## Stripe
An explicit disabled boundary is present. Integration awaits official SDK/configuration rather than accepting unverified callbacks.
## Webhook Verification
Invalid signatures, currencies, amounts, and references are rejected.
## Webhook Idempotency
Unique provider/event records and locked payment/order rows ensure duplicate success cannot repeat side effects.
## Inventory Consumption
Checkout reserves; confirmed online payment consumes. Failed payment does not consume. Unpaid cancellation releases.
## Payment Reconciliation
Webhook persistence supports reconciliation, but remote status polling is deferred until the enabled provider supplies a validated status API.
## Business Credit
Disabled pending an approved immutable credit-ledger/accounting policy; concurrent unsafe balance mutation was not introduced.
## Invoice Architecture
One invoice per order uses transaction-safe ReferenceNumber sequencing. The existing document worker remains the PDF integration point.
## Refund Architecture
Idempotent itemized requests validate remaining quantity and captured amount. Provider processing is separate from request approval.
## Return/RMA Architecture
Owner-scoped requests and explicit admin transitions track physical receipt/condition independently from refunds.
## Exchange Boundary
EXCHANGE is recorded as resolution intent; no replacement order or fulfillment is created.
## Coupon Redemption
Redemption occurs once on confirmed payment while the coupon row is locked. Full-refund restoration is deferred by policy.
## Verified Purchase Reviews
Review creation derives verification only from an actual paid order containing the product.
## Permissions
Orders read/manage/cancel, payments read/manage/refund, invoices read, and returns read/manage were added.
## Audit Events
Order, payment creation, cancellation, refund request, return lifecycle, and admin operations reuse sanitized Phase 2 activity logging.
## Database Changes
Forward-only migration `20260909070000` creates eleven commerce tables with unique references/idempotency and lifecycle indexes.
## Tests
Unit tests cover order transitions, PayHere signature validation, forged notifications, secure return/refund inputs, and configurable return eligibility.
## Remaining Known Issues
Real PayHere, refunds, document generation, migration, webhook delivery, and MySQL concurrency were not exercised. Refund approval/provider completion APIs and reconciliation polling require provider policy/configuration.
## Phase 8 Prerequisites
Apply all migrations on restored staging, seed permissions, configure/validate PayHere sandbox, test concurrent duplicate webhooks, final-stock payment consumption, coupon quotas, invoice jobs, refund callbacks, and return restocking.
Module 16 AI Customer Support Chatbot is intentionally excluded and planned as a separate service.