- A purchase order says what the buyer intended to buy.
- Real procurement is rarely that tidy.
- A supplier may omit a SKU, use its own reference, split one received product across two invoice lines or describe a familiar item in unfamiliar words.
- For a procurement marketplace built with Medusa, we designed a review step for precisely this moment.
The client problem
A purchase order says what the buyer intended to buy. A receipt of goods says what actually arrived. A supplier invoice says what the vendor expects to be paid. In an ideal transaction, all three documents use the same product references and every line joins automatically.
Real procurement is rarely that tidy.
A supplier may omit a SKU, use its own reference, split one received product across two invoice lines or describe a familiar item in unfamiliar words. An extraction model can read the document, but it cannot safely decide which commercial line the supplier meant. A plausible guess is still a guess—and the mistake will surface later as a wrong price, an unexplained variance or a payment against the wrong goods.
For a procurement marketplace built with Medusa, we designed a review step for precisely this moment. Obvious references can still match automatically. Uncertain lines become an explicit buyer decision. The platform then checks that every invoice line is accounted for and that the corrected mapping reproduces the document's quantities, prices and totals before validation can continue.
The goal was not to make AI look confident. It was to let automation do the reading while keeping payment authority with a person who can see the commercial context.
The problem begins where exact SKU matching ends
Automatic matching works when the invoice SKU identifies exactly one received item. That is the easy path, and it should remain fast.
But several legitimate cases break that assumption. The invoice may contain no SKU. Two products may share a supplier reference. A vendor may have changed its nomenclature. One ordered line may appear as two invoice lines because the goods shipped in separate batches. Conversely, an invoice description may be too generic to distinguish two similar products.
Treating these cases as extraction failures throws away useful information. Treating them as successful automatic matches is worse: it converts uncertainty into an accounting fact.
We modelled the gap explicitly. Each extracted invoice line has its own stable identity, tied to the reviewed source document and its line position. Each received-goods line also has an identity belonging to the order. A manual mapping connects those two facts without changing either original record.
That distinction matters. The system is not rewriting the invoice to make it fit the order. It is recording how a buyer interpreted an ambiguous supplier line for this comparison.
Show the buyer three truths, not one red error
A message such as “invoice mismatch” is not a workable review interface.
The buyer needs to see the ordered or received item, the extracted invoice line and the values that disagree. Product description, SKU when present, quantity, unit price, line total and source reference all contribute to the decision.
This creates a much more useful question: “Which received item does this supplier line describe?” The answer can come from product wording, the physical receipt, a packing slip, a known supplier convention or the surrounding invoice lines.
Once the buyer selects a target, the mapping is stored explicitly. If the selected target is different from the unique automatic SKU candidate, the system records it as a manual override. That gives operations a durable explanation of why the comparison used a particular relationship.
The interface therefore turns an opaque machine failure into a bounded business decision. The buyer does not edit database identifiers or approve a vague exception. They connect one visible document line to one visible receipt line.
Never turn missing quantity into zero
Missing information must remain missing.
If extraction cannot determine a quantity, quietly treating it as zero would make the arithmetic appear complete while changing the meaning of the invoice. The same applies to a missing or ambiguous price.
In this workflow, a missing extracted quantity marks the grouped comparison as incomplete. It does not contribute zero units. A unit price may be derived from an extended line price only when the quantity is present and non-zero. A line total may be derived from quantity and unit price, but when the invoice provides both unit and extended prices, the two must agree arithmetically.
These rules keep convenience subordinate to evidence. Derivation is acceptable when the equation is explicit. Fabrication is not.
For the buyer, this produces a precise blocker: the line has no extracted quantity, no unambiguous unit price or no consistent line total. The next action is clear—review the document or ask the supplier for a correction—rather than approve an apparently harmless zero.
Require a decision for every extracted line
A partial mapping can be deceptively convincing.
Suppose four invoice lines match neatly and a fifth remains unknown. The four matched lines may display no variance, but the invoice as a whole is not reconciled. Ignoring the fifth line would effectively make it disappear from the payment decision.
When explicit mappings are submitted, the platform requires every active extracted invoice line to be mapped. It rejects an invoice line mapped more than once, a mapping to an item outside the order and a reference to a line that no longer belongs to the active invoice.
It also checks the opposite direction: every received-goods item in the comparison must be covered by at least one invoice line. This prevents a buyer from making the invoice look complete by mapping only the convenient subset.
Completeness is a business rule, not a user-interface preference. The validation boundary enforces it again on the server, where a stale or manipulated browser cannot bypass it.
Allow two invoice lines to describe one received item
Completeness does not mean forcing a one-to-one relationship.
A supplier can legitimately split a product across invoice lines. Two deliveries, packaging differences or internal supplier accounting may produce “Filter A” and “Filter B” even though the buyer received two units of one ordered filter.
The mapping model permits both extracted lines to target the same received-goods item. Their quantities and line totals are aggregated for comparison. If each line represents one unit at the same price, the resulting received-item comparison can correctly show two units and the combined value.
This is a small architectural choice with a large operational consequence. A rigid one-to-one join would force buyers either to reject valid invoices or to distort the source document. A many-to-one mapping preserves what the supplier sent while comparing it against the commercial line the buyer recognises.
The system stays strict about coverage and arithmetic without being naïve about document shape.
Recalculate the comparison after the mapping
A manual choice is not an approval.
After mappings are applied, the platform rebuilds the comparison by grouping extracted values against the selected received items. It evaluates quantity, unit price and line total independently before producing the overall line result.
That separation matters because different mismatches imply different remedies. A quantity mismatch may mean the invoice does not reflect the final received quantity and should return to the supplier. A unit-price mismatch may be a legitimate commercial correction that the buyer can apply to the order through a controlled reconciliation. A line total that disagrees even though quantity and unit price match cannot be repaired by simply changing the order price.
The buyer therefore sees the consequence of the mapping before payment validation advances. Selecting a product does not silence the variance; it gives the variance the correct commercial context.
This makes human review safer. The person supplies meaning, while the system remains responsible for recomputing the numbers.
Make the lines reproduce the extracted subtotal
Line-by-line plausibility is not enough.
The platform sums the extracted line totals and compares the result with the subtotal extracted from the invoice. If those values disagree, reconciliation remains blocked. Required document amounts—subtotal, sales tax and grand total—must also be present before the advanced comparison can pass.
This protects against a subtle failure mode. A buyer could map every line to a believable item, yet still miss a line, accept an inconsistent extended price or build a corrected order that does not explain the supplier's document total.
The arithmetic gate asks a stronger question: after our interpretation, can the set of invoice lines still reproduce the invoice itself?
Only then does it make sense to compare that document with the goods received and the order values. The safeguard is deliberately mechanical. A compelling description or a confident extraction score cannot override a subtotal that does not add up.
Keep automatic matching as a suggestion, not an authority
There is no reason to send every invoice through a slow manual workflow.
When a normalised invoice SKU identifies one received item, the platform can surface that candidate automatically. The buyer only needs to intervene when the reference is absent, ambiguous or contradicted by the commercial context.
The important boundary is that automatic matching remains explainable. The comparison knows which received item was the unique SKU candidate and can distinguish it from a manual override. It does not hide a semantic guess behind a generic “AI matched” label.
This gives teams a sensible operating model:
- extract the document;
- accept exact, unambiguous references as candidates;
- send uncertain lines to a focused review;
- rebuild quantities, prices and totals;
- block payment progression until the complete comparison is valid.
Automation removes repetitive work. Human authority resolves ambiguity. Deterministic validation checks the result.
Preserve the decision when document processing retries
Invoice ingestion is asynchronous. Extraction callbacks can be retried, a source can be reviewed again and a browser can remain open while the underlying comparison changes.
The mapping therefore belongs to the canonical invoice source and review state rather than to a temporary screen. Subsequent processing preserves the explicit decision instead of forcing the buyer to repeat it or silently reverting to automatic matching.
The wider validation flow also carries a comparison version. A buyer cannot submit an old approval against a newly changed comparison without the system detecting that the underlying facts moved.
This is what makes the review operational rather than cosmetic. The mapping survives the workflow that needs it, yet remains attached to a specific invoice source and comparison state.
The result is a traceable answer to a future support question: which invoice line was associated with which received item, and was that relationship automatic or manually selected?
Why Medusa was the right commerce foundation
Medusa already gave the project orders, order lines, payment collections and extensible workflows. The client needed a procurement-specific layer connecting those commerce facts to receipt-of-goods records and supplier invoice evidence.
We did not replace the commerce engine with a separate accounts-payable product. We extended the validation journey around the existing order lifecycle: document extraction produces evidence, received-goods lines provide the physical truth, mappings resolve semantic ambiguity and the comparison controls whether payment validation may proceed.
That is the value of choosing an extensible platform. The standard engine continues to own orders and payment state. The project-specific capability expresses how this buyer decides that an invoice is payable.
The architecture serves the business problem: suppliers can keep sending real-world invoices, while buyers get a controlled path through references that do not match perfectly.
A practical design checklist
Before building invoice-line mapping, answer these questions:
- What gives every extracted line a stable identity?
- Which received or ordered lines are valid mapping targets?
- When is an automatic SKU match genuinely unambiguous?
- Can several invoice lines map to one received item?
- Must every invoice line be covered before continuing?
- Must every received item be represented?
- How are duplicate and out-of-order mappings rejected?
- Does a missing quantity remain missing?
- When may unit price or line total be derived?
- What happens when supplied unit and extended prices disagree?
- Do mapped line totals reproduce the invoice subtotal?
- Which mismatches require a supplier correction rather than an order edit?
- Where is a manual override stored?
- How does the system reject an approval based on a stale comparison?
- What can operations inspect when a payment remains blocked?
These contracts are more important than the matching model. They determine whether the final decision is defensible.
The broader lesson
AI can read an invoice quickly. It cannot be allowed to invent the commercial relationship that authorises payment.
For this marketplace, we separated those responsibilities. Exact references accelerate the obvious cases. Unknown or ambiguous lines become a concrete buyer mapping. The server requires complete coverage, allows legitimate many-to-one relationships, preserves missing values as missing and rebuilds the comparison. Quantities, prices, line totals and the invoice subtotal still have to agree.
The buyer is not asked to trust a black box. They are asked one intelligible question about one uncertain line, and the platform proves that the answer produces a coherent invoice.
That is a much stronger automation story than promising perfect recognition. It removes routine effort while putting ambiguity exactly where it belongs: in a reviewable human decision surrounded by deterministic safeguards.
