Prepayments
The customer's payment for an order. It is the only transaction that says how the order was actually paid, and it carries the exchange rate the order was settled at.
A prepayment is the money received for a sales order. It arrives from NetSuite as its own transaction, one per payment, linked back to the order.
It is where the payment method comes from
salesorders.paymentmethod holds the same NetSuite id whatever the customer paid with, so the order itself cannot tell you how it was paid. The prepayment can. Classification resolves the raw payment method text against the paymentmethods table, first on an exact match and then on a prefix match, and falls back to Unknown, which is payment method 1, when neither matches.
This is also why the expected figure books its faked payment on Unknown. The synthetic payment does not read an existing real prepayment, so method-specific rules apply only if they include Unknown.
Where it comes from
app/jobs/netsuite/prepayments.php consumes the ns_prepayments batch type, one batch per date. Orders before ingest.modernera were loaded from verkoopdump, which writes prepayments alongside the orders in the same import.
classify/prepayments.php calls getblocked(array('ns_salesorders')) and ends the run while any sales order batch is still queued, because a payment points back at its order.
Tables
| Table | Holds |
|---|---|
prepayments | The payment |
prepaymentclassifications | The order, date, NetSuite id, currency, exchange rate, resolved payment method, and the euro amount |
There are no line tables. A payment is one amount, not a document with lines, which is what makes this family the shortest of the seven.
Currency
The classification stores exchangerate and computes amount_eur_invat as the paid amount times that rate, so the euro figure is fixed at the rate of that transaction and does not move when rates do. See dates, currency and signs.
What it contributes to margin
Payment costs, which are variable order costs. The seeded rules come from config/seed/cm_calculationrules/payment.csv: one rule per payment method and currency, each with a fixed fee and a percentage, each carrying its own activation window because these terms are repriced per period. payment_refund.csv is the same shape on the credit memo instead, for the cost of paying money back.
An empty method or currency in one of those rows means the rule does not filter on that field, and the rule name drops that part with it.
Where to look, and where to change
| What | Where |
|---|---|
| The payments themselves | /transactions/prepayments |
| One payment in the context of its order | /transactions/salesorderdetail, under related records |
| The payment methods a payment can resolve to | /entities/paymentmethods |
| The payment cost rules | /contributionmargin/calculationrules |
The payment itself is upstream data and is not editable in CCC. The rules that price it are.
Related
- Sales orders
- Credit memos, where a refund is priced
- Calculation rules
- Expected margin
Evidence
Import and blocking from app/jobs/netsuite/prepayments.php and app/jobs/classify/prepayments.php. Payment method resolution and the euro conversion from classify->classifyprepayment(). The Unknown fallback on the order from AGENTS.md, The expected figures, and app/models/expectedimpact.php. Table family from app/jobs/install/install.php. Rule shape from config/seed/cm_calculationrules/payment.csv and payment_refund.csv. Columns from templates/main/transactions/prepayments.tpl. Basis: code-checked against the current implementation.
- Type
object - Status
active - Updated
2026-09-14 - Created
2026-09-13 - Covers
transactions/prepayments