Core Concepts
“Which marketplaces does BigLedger synchronise with?” is the question most people bring to this module. Orders arrive from Lazada, Shopee, TikTok Shop and Shopify as ordinary sales orders, and stock goes back out to Lazada and Shopee. That short answer hides seven ideas, and they explain nearly everything that surprises people later: why an online sale is not on the P&L, why a shop shows less stock than the shelf, where the payout money lands, and which jobs are still yours.
1. A cart is not an order, and neither of them posts
Two server document types carry everything the storefront produces, and both have amount signum 0 and quantity signum 0:
| Document | Type | Signums (qty · amt) | What FINAL does |
|---|---|---|---|
| Shopping cart | INTERNAL_SHOPPING_CART (short code SHPCRT) | 0 · 0 | Makes the lines available to the Sales Order applet’s knock-off tab. No journal, no stock |
| Sales order | INTERNAL_SALES_ORDER | 0 · 0 | Counts against available stock and the customer’s credit; can hold a reservation. No journal, no stock |
The signums are fixed by the platform and cannot be changed by an applet. The first
document in the online chain that reaches the general ledger and the stock ledger is the Sales
Invoice (INTERNAL_SALES_INVOICE, quantity −1, amount +1), and it belongs to
Sales. Read that page’s signum table before answering any
“why has my online sale not hit the P&L” question: the answer is always “because it has not been
invoiced”.
A marketplace order arrives FINAL and stays an order. Which document then carries the sale into the ledger (an invoice knocked off each order, or another document your accountant chooses) is a decision for whoever closes the month, made once and written down. They check it each month the same way: the sales booked on each marketplace branch should tie to that shop’s own sales report in its seller centre.
A cart also has no VOID and no DISCARD in the user interface. Staff can DELETE a non-FINAL cart (the header goes with its lines and events, and the listing no longer shows it) and can set a cart FINAL once; that is the whole lifecycle.
2. Three paths turn an online purchase into a sales order
The whole chain, from a buyer paying to the sale reaching your books:
flowchart LR
subgraph STORE["Your storefront"]
W["Website<br/>CP Commerce Admin"] --> CART["Shopping cart<br/>posts nothing"]
SP["Shipping Pricebook"] -.fee line.-> CART
CART -->|"A: gateway payment"| SO1["Sales order<br/>posts nothing"]
CART -->|"B: staff FINAL, then knock-off<br/>in Sales Order (Internal)"| SO1
end
subgraph MKT["Marketplaces"]
LZ["Lazada · Shopee · TikTok Shop · Shopify"] -->|"C: order jobs"| SO2["Sales order on the<br/>marketplace branch<br/>numbered · FINAL"]
LZ -->|"payout jobs"| RV["Receipt voucher"]
end
SO1 --> POS["Sales module:<br/>invoice (posts, stock out) · delivery · return"]
SO2 --> POS
RV --> FA["Financial Accounting: bank and debtor"]
Path A — a paid storefront checkout. The shopper’s cart is the same INTERNAL_SHOPPING_CART
row, created through the storefront’s own endpoint. At checkout the storefront asks the server for a
payment reference, posts the shopper to the gateway, and on the gateway’s callback the server
converts the cart to a sales order itself, after checking that the cart’s lines are still intact.
Nobody opens the Shopping Cart applet. A member paying with points goes through the same conversion
with no gateway leg, and so does a corporate client whose basket is within their available credit on
a restricted website (§7).
Path B — a cart finalised by staff. A cart keyed by staff is set FINAL in the Shopping Cart
(Internal) applet. FINAL queues the cart’s lines into the generic line open queue — provided the
company’s Knock Off Configuration (Organisation applet) has an INTERNAL_SHOPPING_CART →
INTERNAL_SALES_ORDER row. The Sales Order applet’s Search Shopping Cart tab then lists those
lines, and a sales administrator raises the order from them. Without the knock-off row the cart
goes FINAL, the tab stays empty, and nothing tells you why.
A cart keyed by a customer in the Customer Access applet takes neither Path A nor Path B: its FINAL button calls the storefront’s convert to sales order service, which rewrites the same row in place into a FINAL sales order. That call is currently rejected by the backend for this applet (a guard added in 2025 requires a platform value the applet does not send), so a customer-keyed cart today has to be finalised by staff from the Shopping Cart (Internal) listing, where it is an ordinary Path B cart. The applet page carries the detail.
Path C — a marketplace order is different in kind: no cart exists. The Lazada, Shopee, TikTok Shop and Shopify order-ingestion jobs create sales orders directly on the marketplace branch, ACTIVE, numbered and FINAL in one pass — the job creates the header, gives it its running number, then finalises it like any other document.
Nothing waits for a person, and a marketplace order is not a TEMP document. TEMP is a real
status in this platform — it is how an applet reserves an empty header while lines are imported, and
how the document-numbering rule “a TEMP document is
deliberately not numbered” arises — but no channel ingestion path uses it. A marketplace order that
has no running number is therefore a fault to investigate, not a document waiting for a human.
Two consequences follow, and both matter. Because the order is FINAL on arrival it is immediately a knock-off source and immediately counts against available stock; and because nobody opens it, an order that never arrived leaves no trace on this screen at all — see EcomSync troubleshooting.
3. What a marketplace is shown as available stock
The number BigLedger sends a Lazada or Shopee shop is not the stock balance. Per item and marketplace branch it is computed by the stock-availability job as
stock balance − open channel-order quantity, then the buffer applied
Three details in that line decide whether it says what you expect, and none of them is on the screen.
The open-order term is not “FINAL sales orders”. The calculation applies no posting-status
filter at all. It selects the sales orders for the item that the branch’s SO Config Type points
at (Stock Configuration → Sales Order), and then keeps the ones whose marketplace status is in a
fixed list — CANCELLED, CANCELED, TRANSIT_TO_SHIP, SHIPPED, RETURNED, READY_TO_SHIP,
DELIVERED. Which orders it selects depends on that setting: INACTIVE selects none; ACTIVE with
no branch ticked selects every branch’s orders, whatever the marketplace, so one shop’s orders
lower every shop’s figure; SELECTIVE_ACTIVE selects the ticked branches’ orders, or none when none
is ticked. The setting is read only when the stock configuration is AUTO; a MANUAL one publishes
the balance you key.
The list is matched exactly, capitals included, and each marketplace fares differently against it.
Shopee: an order that arrives paid reads READY_TO_SHIP and is counted at once, as are SHIPPED
and CANCELLED; UNPAID, PROCESSED, TO_CONFIRM_RECEIVE and COMPLETED are not, and Shopee has no
status called delivered. An order cancelled from BigLedger is written canceled and is not counted.
So a cancelled Shopee order goes on suppressing published stock. Lazada: its own statuses
arrive in lower case (canceled, shipped, delivered), and BigLedger’s own writes for cancelled,
packed and ready to ship are lower case too, so none of them is deducted. The one Lazada status that
matches is DELIVERED in capitals, written by the API call that marks an order delivered by the
seller’s own fleet (no screen was found that uses it); whether an order marked that way then holds
anything back depends on what its lines carry, which the current Lazada order job does not write.
TikTok Shop: CANCELLED matches; its other
statuses are not covered here. Shopify: unfulfilled, written when an order has no fulfilment
status, does not match; Shopify’s other values are not covered here.
And it takes whole orders, not the item’s own lines. It picks the orders that contain the item, then adds up the open quantity on every line of each one, whatever item the line is for. So an order for a phone and a case lowers the phone’s figure and the case’s figure by both lines together. What a line carries as its open quantity differs by marketplace, so the exact figure depends on your marketplaces and on how your branch is set up. The held-back check in Running an Online Channel, Step 2 shows the true figure on your own data.
The buffer is not always a subtraction. BUFFER subtracts a quantity; PERCENTAGE multiplies
— the figure sent to the shop is that percentage of what is left, so 100 (the default when the
field is blank) publishes everything and 5 publishes a twentieth.
The buffer is set on the branch’s Stock Configuration (a quantity or a percentage), optionally overridden per item on the listing record. The result is stored on the listing, shown as each shop’s Balance on the item’s Stock Availability tab in Doc Item Maintenance, and sent by the stock jobs to a Lazada or Shopee shop. They send nothing to a TikTok Shop or Shopify shop: keep the stock those shops show in their seller centres (Running an Online Channel, Step 2).
When the figure is worked out, and where it is kept. It is not recomputed on a clock. Every listing of an item is queued to be worked out again, and on a Lazada or Shopee shop sent, at three moments: when a marketplace order carrying the item is finalised on arrival, when a stock movement for the item is posted, and when someone saves the branch’s Stock Configuration, which queues every active listing on that branch. Each addition to the queue sets off one recalculation there and then, so the figure normally moves within moments; a scheduled job drains anything left waiting. The “stock balance” in the formula is the current balance at the locations ticked on that stock configuration. Each result overwrites the Balance stored on the listing, so the Balance you see is a snapshot taken at the last of those moments, not a live figure. The result is never below zero, and a percentage is rounded to the nearest whole unit.
One trap follows from the order of events. The Balance is stored before the figure is sent. If the shop refuses the update, the refusal is caught inside the job and is not written to its error log, so the Balance shows the new figure while the shop keeps the old one until the next of those moments. Comparing a few Balances with the seller centre is how you find out (How you know it is working).
Worked through: one Shopee order at GadgetSphere Online
For example, a paid Shopee order reaches GadgetSphere Online’s Shopee branch for one flagship
smartphone and two screen protectors, on two lines. The branch’s stock configuration is AUTO,
counts the fulfilment centre’s stock, sets SO Config Type to SELECTIVE_ACTIVE with only the
Shopee branch ticked, and publishes PERCENTAGE 90. The fulfilment centre holds 40 phones and 150
protectors.
- The order arrives already numbered and FINAL, with Shopee’s status
READY_TO_SHIP, which is on the list. Finalising it queues every listing of both items, on every shop, for recalculation. - Shopee orders carry an open quantity of 1 on every line, whatever the quantity ordered. The phone’s figure takes the whole order: 1 for the phone line plus 1 for the protector line, so 2. The protector’s figure takes the same 2, even though two protectors were ordered.
- The phone’s figure is (40 − 2) × 90% = 34.2, rounded to 34, and that is what Shopee is sent.
The protector’s is (150 − 2) × 90% = 133.2, so 133. With
BUFFER5 instead, the phone would read 40 − 5 − 2 = 33. - Nothing has reached the ledger yet. The order carries signum 0, so the sale is on the P&L only when the document your month-end uses for marketplace sales is raised (§1). The money arrives later, net of Shopee’s deductions, on the payout job’s receipt voucher (§4).
If the buyer cancels on Shopee, the order reads CANCELLED, which is also on the list, so it keeps
holding those 2 back from both items. That is why the held-back check is the first thing to run when
a shop’s figure looks low.
Two consequences. First, an “available on the shop is lower than my stock balance” ticket is only sometimes correct behaviour. Check the buffer first. If the gap is bigger than the buffer explains, run the held-back check, which ends by handing the difference to support. Second, nothing is reserved by a checkout or an ingestion. Reservation is a deliberate act in the Stock Reservation applet, or on a sales order line’s Reserved Stock tab. A sales order holds stock for a customer only when someone reserves it on purpose. The reverse holds too: a reservation does not lower the figure the shops are shown, because the calculation starts from the posted stock balance and subtracts only the open marketplace orders and the buffer. Stock set aside for a corporate customer goes on being offered online unless it sits at a location the stock configuration does not tick, or the buffer covers it.
4. A gateway payment is a record on the document, and the receipt voucher comes from a job
A storefront payment is recorded as a payment-gateway transaction attached to the document being paid: merchant code and reference, the request sent to the gateway, the response that came back, the payment channel code and up to four charge lines. What happens when the gateway calls back depends on which screen asked for the payment, and only one of the three routes uses a job.
- A storefront checkout. The reference is generated against the cart. When the gateway reports success, the server rewrites the cart, in place, into a FINAL sales order dated at that moment, and writes the payment onto it as a settlement line carrying the gateway’s merchant reference, for the amount on the payment record. No receipt voucher is created. Where the cashbook posting job is among your tenant’s follow-on jobs, it posts that settlement line into the cashbook of the settlement item the checkout sent with the payment request. A callback that does not report success leaves the cart a cart.
- A bill paid from the portal’s My Invoice screen. The reference is generated against a receipt voucher the portal raises before the customer is sent to the gateway. A successful callback activates that voucher and sets it against the invoice; a failed one deletes it. No job is involved.
- A bill paid through BigLedger’s billing applet, on the ERP payment route. Here the callback does no accounting itself: it queues a background job, which creates the receipt voucher (amount signum −1) and contras it against the paid document; a payment covering several bills gets one voucher per bill. If that voucher is missing, the job’s queue is where to look. A gateway that calls back twice does not produce a second voucher: the job looks for a voucher already carrying the merchant reference (and, on a payment covering several bills, that bill) and skips what it finds done.
Open question (Q-1341). Nothing we found links a storefront order’s payment to the sales invoice raised from the order later. How that invoice is shown as settled is for your accountant to decide before the first month-end, and then to check once: the first paid order’s invoice should not appear as owing on the customer’s statement.
Marketplace money arrives through payout jobs where one runs, and each marketplace does it differently:
- Shopee. The payout job creates a receipt voucher against the marketplace branch: one line for the net payout, matched to no invoice. Its cashbook comes from the job’s own schedule settings, not from the branch’s Marketplace → Settlement sub-tab, and the job refuses to run without one. The other side credits receivables on a record for the shop, and no job setting changes that account.
- Lazada. An older receipt job, marked for retirement in the code. Its settlement line takes an item named after Lazada’s “Item Price Credit” line, or a default item it creates, and it does not read the Settlement sub-tab either.
- TikTok Shop. A settlement matcher exists in the code and is not registered, so nothing records a TikTok payout. The accounts clerk books each one by hand, from the settlement report.
So whoever sets up the Shopee payout schedule chooses where its money lands, on the schedule’s Json tab in the Scheduler applet: a GL-code item whose cashbook takes the payout. They check it by opening the first voucher the job writes. Its money is in that item’s cashbook, whatever the branch’s Settlement sub-tab says.
The platform’s deductions are booked by a person — see Reconciling Marketplace Payouts.
What the module does not do: post gateway fees. The merchant rate cards and contract rates maintained in Merchant Admin price each payment channel for the monthly merchant transaction report; that report is the only place the fee is computed, and no journal is written from it. A “payment gateway holding account” or “merchant fee expense” entry exists only if finance journals it.
5. A website is not a branch, but a storefront needs one of each
The storefront is configured as a Website in CP Commerce Admin: its pricing model (a pricing scheme, entity pricing, or EcomSync-by-branch), menus, layouts, sign-in providers, shipping option, settlement methods per country, legal agreements. It posts nothing and holds no stock.
The website is attached to a branch (required on Website create) and a merchant entity (Details tab). Prices come from the item master through the pricing model; delivery charges from a Shipping Pricebook evaluated in the shopper’s browser; payment options from the settlement methods linked to the website and to the country.
A marketplace branch is a different object again: an ordinary branch in the Organisation applet whose Marketplace Type is Lazada, Shopee, TikTok, Shopify, Magento, Selluseller, Anchanto OMS — or CP Commerce. That last value is why the same stock rule, pricing scheme and publish queue can serve your own storefront as well as an external shop.
6. A seller is a merchant entity; a seller order is not a finance document
The marketplace tables let other businesses sell through your storefront. A seller is a merchant entity — a row in the same entity table as customers and suppliers, with the merchant flag and gateway credentials, created in Merchant Admin. The Seller Applet gives a login linked to that entity a window on its own marketplace products and store stock balances, and on the seller orders allocated to it.
A seller order is created from your sales-order lines by three background steps — mark the order, create a temporary seller line when exactly one seller’s pricing scheme covers the item, then turn each temporary line into one seller order. It is a marketplace-table record with no server document type, no journal and no stock movement. You settle with the seller through ordinary purchase invoices and payment vouchers, and nothing links those to the seller order.
So matching what you pay a seller to what the seller sold is a person’s job. Whoever approves a seller’s purchase invoice compares it, before payment, with that seller’s orders for the same period. At month-end the same person lists the seller orders no invoice has covered yet, because those are amounts still owed to sellers. Nothing in the product lists them for you.
7. What the module has no engine for
- No approval engine. The generic approval engine covers Purchase Order, Purchase Requisition and Stock Requisition only; nothing in e-commerce consults it. A B2B portal has two credit controls instead. The portal’s own gate runs at checkout: on a restricted website it places an order on account when the basket is within the client’s available credit, and above it sends the client to the gateway or refuses the order. It runs in the client’s browser, so an order created through the API is not measured by it. The Sales Order screen’s credit check applies at FINAL when the applet’s credit-limit setting is on, and measures only orders finalised on that screen. To limit who may finalise, the Sales Order applet has a setting that hides FINAL and a permission that shows it again. The Spending Limit rule per member class in CP Commerce Admin neither stops an order nor, today, sends its alert (Best Practices §8).
- No gateway settlement reconciliation. See §4.
- No safety-stock or overselling engine beyond the buffer in §3. The figure moves when an order arrives, when stock moves and when the stock configuration is saved (§3). Deciding how much to hold back before a platform sale day, and lowering the published share for the day, is the channel manager’s call (Running an Online Channel, Step 2).
- No separate EcomSync applet. The two applets with that name are the original standalone screens, since superseded (see the module page); the working screens are the tabs in Organisation, Doc Item Maintenance and Sales Order (Internal).
- No cart-abandonment, channel-performance or catalogue-search reports. See Reports.
When it goes wrong
| What you see | Why | What to do |
|---|---|---|
| An online sale is not on the P&L and stock has not moved | Carts and sales orders carry signum 0. Only the sales invoice, or whichever document your month-end uses, posts (§1) | Raise that document for the order. Then check the month’s marketplace sales against the seller centre |
| A cart is FINAL but the Sales Order’s Search Shopping Cart tab is empty | The company has no Shopping Cart → Sales Order row in its Knock Off Configuration (§2) | Add the row (Configuration §5) |
| A customer’s cart will not finalise from the Customer Access applet | The backend rejects that applet’s call (§2) | Finalise it from the Shopping Cart (Internal) listing |
| A marketplace order has no running number | Ingestion numbers and finalises every order in one pass, so this one failed part-way (§2) | Treat it as an ingestion fault. A person opening and saving it does not fix the cause |
| The seller centre shows orders the branch does not | The order feed stopped or skipped a period | Best Practices §6 |
| A Shopee shop shows less than balance minus buffer explains | Orders Shopee cancelled stay in the count, and whole orders are counted (§3) | Run the held-back check |
| One shop’s sale lowers every shop’s figure | SO Config Type is ACTIVE with no branch ticked (§3) | Use SELECTIVE_ACTIVE and tick the branches whose orders should count |
| A shop shows about a twentieth of your stock | PERCENTAGE 5 publishes 5%, it does not hold 5% back (§3) | Enter the share to publish, for example 95 |
| The item’s Stock Availability tab shows one Balance and the shop shows another | The shop refused the last update. The Balance is stored before the figure is sent (§3) | Find out why the shop refused, starting with its connection, then save the branch’s stock configuration to resend every listing on it |
| A TikTok Shop or Shopify shop’s stock never changes | The stock jobs send nothing to those shops (§3) | Keep their stock in their own seller centres |
| A storefront payment succeeded but no receipt voucher appeared | None is made for a storefront checkout: the payment is a settlement line on the sales order (§4) | Look for the settlement line on the order, and its amount in the settlement item’s cashbook (Best Practices §3) |
| Shopee payouts land in the wrong bank account | The payout job takes its cashbook from its own schedule settings, not the branch’s Settlement sub-tab (§4) | Change the GL-code item on the schedule’s Json tab |
| TikTok Shop payouts never appear | Nothing records them (§4) | Book each one by hand from the settlement report |
How you know it is working
Four checks, each a few minutes, none of which the product runs for you.
- Orders. Today’s order count in each shop’s seller centre matches today’s sales orders on that marketplace branch. A branch that is quiet while the shop is busy is the only symptom a stopped feed gives.
- Stock. For three items, put the shop’s displayed stock beside the Balance on the item’s Stock Availability tab, then work the figure out by hand: the balance at the locations on the stock configuration, less what the held-back check shows, then the buffer. If your arithmetic and the Balance agree but the shop differs, the shop refused an update. If your arithmetic and the Balance disagree, look at the configuration: the SO Config Type, the ticked branches, the buffer type.
- Storefront money. After a small paid test order, the sales order carries a settlement line with the gateway’s merchant reference, for the amount paid. Where the cashbook posting job runs, that amount is in the settlement item’s cashbook. No receipt voucher appears, and none should.
- Marketplace money. The first voucher the Shopee payout job writes lands in the cashbook of the GL-code item named on its schedule. Check it once when the schedule is set up, and again whenever someone edits the schedule.
Where this sits among the other modules
- What must exist first. A branch in the Organisation applet for each shop and for the storefront, with the shop’s connection; a listing for each item in Doc Item Maintenance, without which the shop is never sent a figure for it; the Knock Off Configuration row for carts; and, for a storefront, a merchant entity and settlement methods.
- What it lets you do next. The sales order is where Sales takes over: delivery, invoicing, and through the invoice the journal, the stock movement and the e-invoice. The receipt voucher reaches the cashbook, which is what bank reconciliation matches against the gateway’s or Shopee’s deposit.
- Which sibling to use when. Use the buffer rather than a Stock Reservation to keep a margin back from the shops. A reservation holds stock for one customer’s document and is invisible to the shop figure (§3); the buffer holds back a margin on every listing of the branch. Use a marketplace branch for an external shop and a website for your own storefront (§5); the website still hangs off a branch.
- What breaks elsewhere if it is wrong. The stock configuration is shared by every listing on its branch, so one wrong SO Config Type or buffer affects every item that shop shows, and saving it resends all of them. A wrong cashbook item on the Shopee payout schedule puts every payout in the wrong bank account, so both accounts fail to reconcile until it is corrected.
- What it is used together with. The Scheduler applet runs the order, payout and stock jobs; Running an Online Channel is the occupation’s side of the same work; and Reconciling Marketplace Payouts books what the platform deducted.
Read next
Configuration puts these in setup order — the knock-off row, the marketplace branch, the website, the payment channel — and says what each looks like when it is missing.