URD: Commerce
| Module | Version | Updated |
|---|---|---|
CORE-03 | v0.14 | 2026-07-15 |
What the Commerce module does
Defines the user-facing requirements for Commerce management - a business owner stands up and runs their business structure: a single Organizer (the brand) and one or more Merchants (the legal point-of-sale units), each with its own sale channels and product categories. The module delivers a one-step onboarding that creates the whole structure atomically, plus full lifecycle management of every entity afterwards.
Seven points to understand first
This is the most important part of the document. Understanding the seven points below is understanding 80% of the module.
1. The organizer is virtual, the merchant is physical
This is where newcomers most often get it wrong, and getting it wrong here misdesigns everything downstream.
The Organizer is just the brand name. It has no legal entity, no tax code, no wallet, and can't issue invoices. It only exists to group things - grouping merchants, grouping users, grouping devices under one shared name.
The Merchant is where a transaction actually happens. It has a tax code, an e-invoice profile, finance accounts and a wallet, a business type, an industry, its own currency, a physical location. Every legal and financial attribute lives on the merchant, never on the organizer.
Example: the Sau Beo Coffee chain is an organizer - it only has a name, a logo, and that's it. Underneath it sit three merchants: "Sau Beo - Headquarters", "Sau Beo - District 3", "Sau Beo - Thu Duc". Each merchant has its own tax code, may have its own e-invoice profile, and tracks its own profit and loss separately. Looking for a place to enter a tax code for "the Sau Beo Coffee chain" itself - there isn't one; only each individual merchant has that field.
| Attribute | Organizer | Merchant |
|---|---|---|
| Brand name, logo | Yes | Has its own name (e.g. "Headquarters") |
| Tax code | No | Yes |
| E-invoice profile | No | Yes |
| Finance account, wallet | No | Yes |
| Business type (household / enterprise) | No | Yes |
| Industry (Retail / F&B / Ticket / Other) | No | Yes - also decides the default sale channels and categories |
| Currency | No | Yes, defaults to VND |
| Physical location | May have one (the brand's HQ address) | Yes - the merchant's real physical location |
| Unique-slug scope | System-wide | Within its own organizer |
| Parent-child hierarchy | Yes (sub-organizers) | Yes (child merchants) |
Because the merchant is the legal unit, everything else in BANA hooks into the merchant - products, inventory, orders, finance - never into the organizer. The organizer only sits on top, gathering those merchants under one brand.
2. Creating an organizer immediately creates a headquarters merchant
There's no such thing as an organizer existing with zero merchants. The moment an organizer is created, the system creates a headquarters merchant right along with it, in the same step - defaulting to the name "Headquarters", taxed under the direct method, and flagged as that organizer's headquarters merchant.
Each organizer has exactly one headquarters merchant at any given time, and the headquarters designation can be reassigned later if the owner wants a different merchant to hold that role. But there always has to be a merchant standing in that position.
The owner of the Sau Beo Coffee chain finishes signing up and immediately has a usable "Headquarters" merchant - no need to open another screen to "create the first merchant".
3. One person can stand inside many organizers, but a merchant belongs to exactly one organizer, forever
This relationship isn't symmetric. Mr. Sau Beo can be both the owner of the Sau Beo Coffee chain and hold another organizer under his name - say, a relative's bubble tea merchant he manages on their behalf. There's no limit on how many organizers one person can belong to.
A merchant is different, though - it's born belonging to one organizer and stays there permanently. There's no "move this merchant to a different organizer" operation. To spin a merchant off as its own independent brand, a new organizer has to be created and a new merchant built inside it - the old merchant can't be relocated.
4. Opening an organizer sets up a whole working system, not just an empty row
Signing up doesn't leave you with just a name. In the same step, the system builds a default setup matching whichever industry the owner picked, so the merchant can start selling right away instead of configuring everything by hand.
| Industry | Default sale channels | Default categories |
|---|---|---|
| F&B | Dine-in, Takeaway | Yes - per the F&B industry template |
| Retail | Counter, Online | Yes - per the Retail industry template |
| Ticket, Other | None | None |
The whole process runs all-or-nothing: if any step fails partway through, the entire batch is discarded - no half-built merchant or orphaned sale channel is left behind. The person signing up immediately becomes the owner of the organizer and merchant just created - no further approval step is needed.
5. Two ways a merchant comes into being: self-signup and operator-provisioned
There are two completely different doors leading to the same outcome (organizer + headquarters merchant + industry defaults), but the mechanics behind them are entirely different.
| Self-signup | Operator-provisioned | |
|---|---|---|
| Who clicks the button | The person about to become the owner, on the signup page themselves | An operations staff member, provisioning on the customer's behalf |
| Who becomes the owner | The very person who just signed up | A brand-new owner account, created on the spot during provisioning |
| License issued | Not issued | Issued alongside |
| How it runs | One tidy operation - it either finishes clean or fails clean, with no half-done step | Two sequential phases: phase one builds the organizer and merchant, phase two creates the owner account and issues the license |
| If phase two fails | Not applicable | The system automatically rolls back what it just created - revokes the license, deletes the just-created owner account, removes the merchant, removes the organizer - every rollback step is logged for operations staff to check if any cleanup didn't land cleanly |
Why the operator-provisioned path has to be split into two phases: phase one only touches Commerce's own internal data, so it's easy to guarantee all-or-nothing; but phase two has to call out to the user-account system and the licensing system elsewhere - those two systems can fail at any moment outside Commerce's control, so a dedicated rollback mechanism is needed instead of relying on one combined transaction.
If an operations staff member calls provisioning twice in a row for the same customer (say, due to network lag or a repeated click), the second call gets back exactly the same result as the first - no duplicate provisioning - as long as both calls carry the same request id.
6. A sale channel is an internal lane inside one merchant, not a marketplace
A sale channel here means dine-in, takeaway, delivery, kiosk - in other words, how the merchant is selling, not where on the internet the merchant is selling. Marketplaces like Shopee or Lazada aren't wired into this sale-channel concept.
Every sale channel belongs to exactly one merchant, and its identifier only needs to be unique within that merchant's own scope (two different merchants can both name a channel "Delivery"). A merchant always has exactly one default sale channel at any given time - designating a different channel as default automatically un-defaults the old one, with no manual unset step needed.
7. Category is a shared resource, not owned by any single module
Category doesn't belong to Commerce or to Inventory - it's a shared resource both modules borrow, distinguished by a discrimination flag: a category serving Products (what's sold) or a category serving Materials (what's used to make things, managed by the Inventory module). Same category tree, same parent-child hierarchy mechanism capped at eight levels, differing only by that flag.
When an organizer is opened, the starting category set is copied once from the shared industry template into the new merchant - not a live reference. After that, editing the shared template never touches the categories a merchant already copied earlier; and any industry with no template authored yet (Ticket, Other) gets no categories seeded at all when its merchant opens.
What the module has
Ten features. Click an AREA code to jump to the Details tab and read that feature's requirements.
AREA | Name | Status |
|---|---|---|
ORG | Organizer | Partial |
MER | Merchant | Partial |
SC | Sale Channels | Partial |
CAT | Categories | Partial |
CFG | Configuration | Not built |
ACC | Access | Partial |
FLR | Table & Floor Allocation | Partial |
RCP | Receipt Templates | Partial |
RTL | Retail Business Type | Partial |
BOP | Backoffice Portal | Partial |