URD: Payment & Transaction
| Module | CORE-08 | Version | v0.5 |
|---|---|---|---|
| Status | In-progress | Date | 2026-06-04 |
Business documentation. This URD is Payment & Transaction's feature list - each feature below is one Functional Area (
<AREA>). The same<AREA>keys the feature's PRDs (PRD-<AREA>-NNN) and tests (TC-<AREA>-NNN), and each feature is listed in the Delivery feature catalog. See the Feature Spine convention.
1. Purpose
Define the user-facing requirements for collecting payments and recording the resulting money. The module connects a merchant's payment providers to KICKO, surfaces live payment status, and books every completed payment, purchase, and stock movement into a double-entry finance ledger so owners can see balances and reconcile their books.
2. Scope
| Included | Excluded |
|---|---|
| Per-merchant payment provider credentials (VNPAY QR MMS, PhonePOS) | Direct gateway integration code (developer concern) |
| Real-time payment status (webhook + WebSocket) | Checkout / split-payment UX (Orders module) |
| Outbound webhook subscriptions per merchant | Card-data / token storage |
| Finance accounts / wallets + control accounts | Multi-currency conversion |
| Double-entry vouchers (RECEIPT / PAYMENT / TRANSFER / ADJUSTMENT) | Tax invoice issuance (Tax & Invoice module) |
| Auto-posting from sale, purchase, and inventory events | Structured provider refunds (Planned) |
| Category hierarchy (seeded + custom) | Per-shift cash reconciliation (Planned) |
3. Definitions
| Term | Definition |
|---|---|
| Payment provider | An external service (e.g. VNPAY) that processes a customer's payment |
| Webhook | An outbound notification KICKO sends to a subscriber when a payment changes state |
| Account / Wallet | A place money sits: cash, bank, QR collection, mobile POS, or an internal control account |
| Voucher | A balanced bookkeeping entry of one type (RECEIPT, PAYMENT, TRANSFER, ADJUSTMENT) |
| Transaction (ledger line) | One DEBIT or CREDIT line within a voucher, affecting one account's balance |
| Category | An income or expense label classifying where money came from or went |
| Auto-posting | A voucher created automatically by the system in reaction to a business event |
4. Conceptual Model
Conceptual only - full schema lives in the payment and finance developer domain models.
5. Feature Catalog
The feature list of this module. Each row is one feature (a Functional Area). Detail in §6. Mirrored in the Delivery feature catalog.
| Feature ID | Feature | Phase | Status | Priority |
|---|---|---|---|---|
PAY | Payment Lifecycle | P1 | Built | High |
PRV | Provider Credentials | P1 | Built | High |
WAL | Accounts & Wallets | P2 | Built | High |
VCH | Vouchers & Ledger | P2 | Built | High |
CAT | Categories | P2 | Built | High |
Status: live from Plane where mapped, otherwise registry-declared. Vocabulary mirrors Plane (state-group / phase).
6. Features
One sub-section per feature, in catalog order. Each feature keeps its description, requirements, and acceptance together. Priority = MoSCoW (Must / Should / Could / Won't).
PAY - Payment Lifecycle Built
Feature ID: payment/PAY · Phase: P1 · PRDs: - · Dev: @nx/payment
What it does for users: a payment moves from pending to paid, failed, or expired in real time; the cashier sees the change live and the sale that owns the order is notified the moment a payment succeeds.
Requirements
| ID | P | Requirement |
|---|---|---|
| URD-PAY-001 | M | The system receives payment results from the provider and updates the payment's status |
| URD-PAY-002 | M | On a successful payment, the system notifies subscribers (e.g. the sale that settles the order) |
| URD-PAY-003 | M | Payment status is broadcast live to the cashier (pending → paid / failed / expired) |
| URD-PAY-004 | M | The same payment result is applied only once, even if delivered multiple times (idempotent) |
| URD-PAY-005 | S | An owner can subscribe webhook endpoints by event type, with retries on delivery failure |
| URD-PAY-006 | W | Structured refund back through the original provider (Planned - see §7) |
Acceptance
AC-PAY-01: Payment status updates
| Given | When | Then |
|---|---|---|
| A pending payment | The provider reports success | Status becomes paid, subscribers are notified, cashier sees the update live |
| A pending payment | The provider reports failure / expiry | Status becomes failed / expired; the order stays open |
| An already-applied result | The same result is redelivered | It is ignored; no duplicate effect |
PRV - Provider Credentials Built
Feature ID: payment/PRV · Phase: P1 · PRDs: - · Dev: @nx/payment
What it does for users: an owner connects a payment provider (VNPAY QR MMS, PhonePOS) per merchant; credentials are stored encrypted, masked in responses, and never usable by another merchant.
Requirements
| ID | P | Requirement |
|---|---|---|
| URD-PRV-001 | M | An owner can connect a payment provider (VNPAY QR MMS, PhonePOS) per merchant |
| URD-PRV-002 | M | Provider credentials are stored encrypted and never shown in full |
| URD-PRV-003 | S | Credentials are scoped per merchant so one merchant cannot use another's |
Acceptance
AC-PRV-01: Connect a provider securely
| Given | When | Then |
|---|---|---|
| An owner of a merchant | Connects a payment provider | Credentials are stored encrypted and masked in responses |
| Another merchant | Attempts to use those credentials | Access is denied; credentials are scoped per merchant |
WAL - Accounts & Wallets Built
Feature ID: payment/WAL · Phase: P2 · PRDs: - · Dev: @nx/finance
What it does for users: an owner creates accounts where money sits - cash, bank, QR collection, mobile POS - each tracking an opening and running balance; the system also keeps internal control accounts automatically, and one default account receives auto-posted sale income.
Requirements
| ID | P | Requirement |
|---|---|---|
| URD-WAL-001 | M | An owner can create accounts of type CASH, BANK, QR code, or mobile POS |
| URD-WAL-002 | M | The system maintains internal control accounts (e.g. inventory, COGS) automatically |
| URD-WAL-003 | M | Each account tracks an opening balance and a running current balance |
| URD-WAL-004 | M | A default account per merchant receives auto-posted sale income |
| URD-WAL-005 | S | Non-owner roles see only the accounts of merchants they are granted access to |
Acceptance
AC-WAL-01: Accounts and balances
| Given | When | Then |
|---|---|---|
| An owner | Creates an account with an opening balance | The account shows that opening balance as current |
| A posted voucher | It debits/credits an account | The account's running balance updates accordingly |
VCH - Vouchers & Ledger Built
Feature ID: payment/VCH · Phase: P2 · PRDs: - · Dev: @nx/finance
What it does for users: every movement of money is a balanced double-entry voucher (RECEIPT, PAYMENT, TRANSFER, ADJUSTMENT); completed sales, received purchase orders, and stock movements auto-post once each, and an owner can create or void vouchers manually without ever deleting financial history.
Requirements
| ID | P | Requirement |
|---|---|---|
| URD-VCH-001 | M | Every voucher is balanced: total DEBIT equals total CREDIT |
| URD-VCH-002 | M | Voucher types are RECEIPT, PAYMENT, TRANSFER, ADJUSTMENT |
| URD-VCH-003 | M | A completed sale payment auto-posts a RECEIPT voucher to the default account |
| URD-VCH-004 | M | Receiving a purchase order auto-posts a PAYMENT voucher |
| URD-VCH-005 | M | A stock issue/adjustment auto-posts the matching ledger voucher |
| URD-VCH-006 | M | Each voucher records its source event so the same event posts only once (idempotent) |
| URD-VCH-007 | M | Vouchers are numbered per merchant and type (e.g. PT / PC / PCK / PKT) |
| URD-VCH-008 | S | An owner can create a manual voucher (draft → issue) |
| URD-VCH-009 | S | An owner can void a voucher via a balanced reversal (no hard delete) |
| URD-VCH-010 | C | Transfer between two accounts is recorded as a zero-sum voucher |
Acceptance
AC-VCH-01: Auto-posting from events
| Given | When | Then |
|---|---|---|
| A successful sale payment | The event is processed | A balanced RECEIPT voucher posts to the default account |
| A received purchase order | The event is processed | A balanced PAYMENT voucher posts |
| The same source event | It is delivered again | No second voucher is created (idempotent) |
AC-VCH-02: Manual voucher and void
| Given | When | Then |
|---|---|---|
| An owner | Creates and issues a manual voucher | A balanced voucher appears in the ledger with a sequence number |
| An issued voucher | The owner voids it | A balanced reversal voucher is posted; the original is preserved |
CAT - Categories Built
Feature ID: payment/CAT · Phase: P2 · PRDs: - · Dev: @nx/finance
What it does for users: income and expense are classified by category; 14 system categories are seeded and protected, and an owner can add merchant-specific custom categories, including a parent hierarchy.
Requirements
| ID | P | Requirement |
|---|---|---|
| URD-CAT-001 | M | 14 system categories are seeded and cannot be removed |
| URD-CAT-002 | M | Categories are typed as INCOME or EXPENSE |
| URD-CAT-003 | S | An owner can add merchant-specific custom categories, including a parent hierarchy |
Acceptance
AC-CAT-01: Seeded and custom categories
| Given | When | Then |
|---|---|---|
| A new merchant | The finance ledger initializes | 14 typed (INCOME / EXPENSE) system categories exist and cannot be removed |
| An owner | Adds a merchant-specific custom category | It is available for classifying money, optionally under a parent |
7. Constraints & Non-Goals
Constraints
| ID | Constraint |
|---|---|
| C-01 | Every voucher must be balanced (DEBIT total = CREDIT total) |
| C-02 | The 14 seeded categories cannot be removed |
| C-03 | Provider credentials are encrypted at rest and masked in responses |
| C-04 | Each business event posts at most one voucher (idempotent via source event id) |
| C-05 | Records use soft-delete / reversal - no hard delete of financial history |
| C-06 | One default account per merchant for auto-posted sale income |
Non-Goals
- SoftPOS / NFC tap-to-pay flow
- Additional e-wallet providers (Momo, ZaloPay)
- Structured refund / reversal of external provider charges
- Multi-currency conversion and cross-currency reconciliation
- Per-shift cash reconciliation dashboard
8. Version History
| Date | Author | Description | Ver |
|---|---|---|---|
| 2026-02-26 | P. Do - Product Owner | Initial user stories | v0.1 |
| 2026-04-16 | P. Do - Product Owner | Finance wallets, transactions, categories | v0.3 |
| 2026-05-30 | Migration | Restructured to module convention; aligned areas (PAY/PRV/WAL/VCH/CAT) to two-package reality; refund + reconciliation marked Planned | v0.4 |
| 2026-06-04 | Claude (AI pair) | Reorganize by feature (Feature Spine); each feature carries its own requirements + acceptance; CON moved to Constraints | v0.5 |