System Design
A NestJS + Prisma/PostgreSQL backend serves as the single transactional core for two frontends: the customer-facing LINE Mini App and an internal admin dashboard. The payment domain is modeled as an explicit state machine — payments move PENDING → PAID → SUCCESS/FAILED while items carry their own lifecycle — and fulfillment is delegated through a provider-abstraction layer that routes each request to the correct supplier behind a uniform contract. ECPay handles gateway payments with signed webhook returns, and reconciliation runs continuously via scheduled jobs: a 10-minute cron detects stuck payments and alerts operators via LINE, while a 12-hour cron syncs supplier catalogs with per-supplier isolation so one provider's failure cannot block the rest.