Testing integrations between e-commerce, warehouse, and accounting systems
An order can appear as paid in an online shop even though the warehouse never received it and accounting knows nothing about it. Every system may still have returned a successful response to its own API call. Testing this integration therefore does not end with HTTP 200: it must demonstrate that one business event produced correct, compatible results in every participating system and that the flow can recover from a delay, duplicate, or partial outage.
One order is not one technical transaction
In a monolith, creating an order may look like one database write. In a connected e-commerce system, it is closer to a sequence of steps that finish at different times:
- The shop accepts the order. It assigns an internal ID and records items, quantities, prices, currency, discounts, tax information, and the selected delivery method.
- The warehouse reserves stock. The warehouse management or enterprise resource planning (ERP) system assigns its own ID, confirms the available quantity, and may split or reject the order.
- The payment service confirms the outcome. The immediate response after redirecting the customer may not be final evidence; the decisive server-side event may arrive later.
- The warehouse dispatches the goods. A stock issue, shipment, tracking number, and one or more dispatch events are created.
- Accounting creates a document. An invoice, cancellation, adjustment, or credit note must reflect the real business outcome and the accounting rules in use.
The exact sequence differs between businesses. Some capture payment before reservation, others at dispatch; an invoice may be created after payment or shipment. A test should not impose a generic model on the real process. The team must draw its approved flow, including the owner of each state, and test that particular contract.
First distinguish the communication mechanism
A synchronous API returns a response during one call. Depending on its contract, status 200 can mean a completed operation, merely an accepted command, or a technically successful response whose body contains a business rejection. The test therefore checks the status, body, and subsequent state at the source, rather than just a green request in a client tool.
Asynchronous messages and webhooks separate receipt from processing. A message may wait in a queue, arrive repeatedly, or arrive out of sequence when the particular contract permits it. A test waits for an observable business outcome with a fixed time limit and captures intermediate states for diagnosis. An arbitrary ten-second pause merely hides differences in processing speed.
Batch files and scheduled synchronisation add a processing window, file formats, naming, checksums, and re-import rules. A nightly invoice export needs tests around the day boundary, time zone, empty batch, partly invalid file, and safe repetition of the same batch.
One flow may use all three mechanisms: the shop reserves goods through an API, receives payment through a webhook, and sends invoices to accounting in a nightly batch. The scenario is complete only according to its business definition, not after the first successful transport operation.
Build a map of data and contracts
For every boundary, record which fields cross it, which system is their source of truth, and how they are mapped. A minimum order-flow map will usually include:
- internal and external IDs for the order, payment, reservation, shipment, and document;
- the stock-keeping unit (SKU) or other variant identifier, quantity, and unit of measure;
- unit and total prices, discounts, delivery, currency, tax rate, and rounding;
- state and allowed transitions, event time, receipt time, and time zone;
- customer identity and addresses only to the extent required by the receiving system;
- message or schema version and the rule for an unknown field or value.
An ambiguity such as “order number” often causes an expensive defect. The shop may use a long immutable technical identifier, show the customer a short sequential number, and let accounting assign a separate document series. If the warehouse returns only one of these, a complaint cannot safely be connected to its source record.
A contract must define meaning, not just a data type. A total field without a currency, tax, discount, and rounding definition is technically valid but commercially ambiguous. Automated contract testing can warn about a change to a covered format or expectation, but it does not replace an end-to-end check of calculations and resulting documents.
Idempotency and deduplication prevent duplicate effects
Idempotent processing means that safely repeating the same business command does not create a second reservation, payment, or invoice. The sender assigns a stable key to the operation and reuses it for every attempt; the receiver stores the outcome under that key or enforces uniqueness in its database. Concurrent copies must meet the same protection; a “find first, insert second” check without an atomic constraint can fail under a race.
Deduplication of incoming events commonly uses the provider’s event ID and a processing-state record. Two different events for one order are not duplicates merely because they contain the same order ID. A partial refund of EUR 10 and a later refund of another EUR 5 are separate business operations.
Each API has its own contract. For example, Stripe documents an idempotency key for safely retrying supported requests, and its webhook documentation warns about duplicate delivery and events arriving without a guaranteed order. These properties should not be assumed for every provider; derive tests from that provider’s documentation and your own implementation. The guide on how to test webhooks provides further practical scenarios.
Ordering, delays, and business-state transitions
If a dispatch event can arrive before a delayed reservation confirmation, the system must not move an order from “dispatched” back to “reserved”. A state machine, aggregate version, event sequence number, or lookup of the current state at the source can provide protection. The time at which a message was received is not a reliable substitute for business ordering.
Test boundaries too: payment confirmed after the reservation expires, cancellation received while packing, a refund before the previous step is confirmed, and an event using an older schema version. For every variant, decide whether to reject or defer the message, process it without a change, or start a compensating action. “Ignore” without an audit record creates inexplicable differences between systems.
Retries, a dead-letter queue, and reconciliation
A temporary failure such as a timeout may lead to a bounded retry with delays. A permanent failure such as an unknown SKU or invalid currency will not repair itself through repetition. The integration should distinguish these categories, record the number of attempts, and move the message to a dead-letter queue or another controlled error state when the limit is exhausted.
A dead-letter queue is not an archive to forget. It needs an alert, owner, diagnostic information, safe reprocessing method, and a rule for an order that has changed in the meantime. A replay must pass through the same idempotency controls as the first attempt.
Reconciliation periodically compares sources of truth. It may find a payment without an order, a dispatched parcel without an invoice, or a reservation left hanging after cancellation. A test should deliberately omit an event, run reconciliation, and show whether the system repairs the difference automatically, flags it for a manual decision, or creates a safe compensating action.
A partial failure needs a named state
The highest-risk moment occurs when one system completes an operation and the next one does not. The payment gateway authorises the amount, but the warehouse reservation times out. If the shop marks the order as failed and retries payment without checking, it may charge the customer twice. If it marks the order as successful, it may sell unavailable goods.
The process therefore needs an intermediate state such as “payment confirmed, reservation pending”, an owner for the next decision, and an allowed compensation. This might be another warehouse check, releasing the authorisation, a refund, or manual handling. Not every distributed operation can be rolled back like a database transaction; the test checks for a consistent business outcome and a traceable remaining exception.
Stock quantities, prices, VAT, and currencies
For inventory, it is not enough to see that a quantity decreased. Two concurrent orders for the last item should produce no more than one successful reservation if that is the rule. Test reservation and expiry, partial availability, split shipment, substitution, cancellation, and receipt of returned goods. Distinguish physical stock, available quantity, and reserved quantity; they need not change at the same moment.
Compare money using a precisely defined currency and precision. Store the price and tax snapshot of the accepted order so that a later catalogue change cannot rewrite a historical document. The contract must state whether rounding happens per line or on the total, who determines the exchange rate, and how a discount is allocated on a partial return. VAT scenarios, the document date, and the required adjustment document for a particular country and process must be confirmed by an accounting or tax professional; a technical test does not determine legal correctness.
Test data and environments must cover the whole flow
Prepare a small catalogue of deliberate cases: an SKU with one unit, an out-of-stock item, a mixture of available and unavailable items, a product with a particular tax profile, an order in a supported foreign currency, and a customer with a safe test address. Every run uses its own IDs and knows the initial state of the warehouse, payment sandbox, and test accounting entity.
Mocks suit timeouts and malformed responses, sandboxes cover real formats and authentication, and a shared integration environment verifies the flow through actual components. A small number of production checks may confirm live configuration, but they require labelled accounts, constrained side effects, and agreed clean-up. The guide to test environments explains how to divide these layers, while payment gateway testing covers the boundaries of the payment part.
A correlation ID connects evidence from order to document
Propagate one correlation ID through synchronous calls, messages, and batch records. Alongside it, record the individual message ID, originating event, and attempt number. The team can then reconstruct that a request created an order, the order triggered a reservation, and the payment led to dispatch and an invoice.
Logs should not automatically contain full addresses, payment details, or message bodies. Technical identifiers, state, contract version, time, and rejection reason are often sufficient for diagnosis. Correlation provides evidence of the flow; it is not a reason to copy personal information into every system.
A scenario matrix that tests more than the happy path
| Scenario | Expected business outcome | Evidence to inspect |
|---|---|---|
| paid order for available goods | one reservation, shipment, and correct document | states and amounts in every system, complete correlated trace |
| two concurrent orders for the last item | outcome follows the rule, with no negative available quantity | atomic reservation and final inventory counts |
| payment API timeout followed by a successful webhook | one payment and continuation of the original order | same idempotency key, no second payment |
| duplicate order command or webhook | no second reservation, invoice, or email | deduplication record and count of side effects |
| events in another permitted order | state does not return to an older value | transition history and event consumer decision |
| payment confirmed while warehouse is unavailable | named pending state and approved compensation | retry, warehouse check result, refund, or manual task |
| partial shipment | correct remaining quantity and documents for the process | item-to-shipment links and amounts without duplicates |
| cancellation before dispatch | reservation released and payment changed appropriately | inventory, payment, order, and accounting states |
| full and partial return and refund | returned quantity and amount match the decision | receipt of goods, refund, adjustment document, and balance |
| foreign currency, discount, and rounding boundary | the same agreed totals in every system | line and total calculations and recorded rules |
| accounting batch outage and re-import | each document is created according to the business rule | batch checksum, error records, and safe replay |
Add concrete values and permitted time limits to the matrix. “The order synchronised” is not an expectation; “within two minutes there is one reservation for SKU A, payment P remains unique, and the document contains the agreed amount” can be verified.
Evidence of release readiness
Fast contract and component tests should cover mapping, validation, and error branches at every boundary. Integration tests exercise the database, queue, retries, and sandbox. A smaller number of end-to-end scenarios confirm the most important business flows across real components. Failures need to be induced deliberately; waiting for a random outage is not a testing strategy.
The release evidence records application and schema versions, environment configuration, the data pack used, scenario-matrix results, and correlation IDs. For an asynchronous flow, it includes intermediate states, attempt counts, the dead-letter queue, and the reconciliation result. For money and inventory, it contains a concrete calculation, balance, and sample resulting document. It also names unexecuted scenarios, differences from production, and the owner of each remaining risk.
HTTP 200 is only one piece of evidence about one boundary in this package. Readiness means that the team can demonstrate the final business outcome, the absence of duplicate effects, and a working recovery path for the covered failures.
What you gain
Tests designed this way reveal discrepancies before they become manual order investigations, negative stock, duplicate charges, or invoices without shipments. A correlated trace shortens diagnosis, and the scenario matrix gives operations, engineering, and accounting a shared view of what the release has actually demonstrated and what remains open.
Next step
Choose one real order type and spend 90 minutes auditing its events from acceptance to invoice or credit note. For each step, record the source of truth, ID, contract, allowed time, retry, compensation, and evidence of the final outcome. Then run three scenarios from the matrix: the standard flow, duplicate delivery, and a partial failure after payment. You should be able to reconstruct all three from one correlation ID without manually comparing unlabelled records.