Files
Zumri-Backend/Documentation/API_ORDERS_PAYMENTS.md
Sathira Sri Sathara cd2c1c6d08
CI / test (push) Successful in 10m27s
feat: Implement return and refund functionality in commerce module
- 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.
2026-09-09 12:39:57 +05:30

43 lines
2.7 KiB
Markdown

# 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.