When an order from your online store reaches Odoo, it should appear with its original store number and its status between the two systems. Finance then knows which order is meant, the owner knows where it stopped, and the employee knows who follows it up. That means telling four states apart: arrived, confirmed, shipped, and paid. An imported order still has its own confirmation, fulfilment and payment steps. At ToDoOps we start system integrations from this question, and you can read about our work on the homepage.
What is the difference between integrating an external system and working inside Odoo apps?
Inside Odoo, sales, inventory, and invoicing run on one database, and documents move between them through the apps’ own setup. See Odoo apps for what each covers. The ToDoOps simulation lets you see how sales and inventory connect using hypothetical data; it is not a real integration with an external store.
Your external store, by contrast, is an independent system with its own database, numbers, and statuses, and every handoff between it and Odoo is something to design and test. So the question here is: what happens to the order at each step between the two systems?
Which fields do we agree on before integrating?
Start with a simple map that makes an order traceable:
- External order number
- Customer ID
- Item code
- Branch or warehouse
- Quantity
- Price and tax as actually configured in your company
- Status
Then decide, for each kind of data, the source of truth and the direction of updates. The store might be the source of the order and Odoo the source of stock and the invoice, so the order flows from store to Odoo and the status flows from Odoo back to the store. That is one possible split, not a fixed rule. Do not assume all data syncs both ways automatically; each direction is designed and tested.
Does your Odoo version and plan support the integration you need?
This is the first question before contracting. According to the Odoo 19.0 documentation (Odoo reference), the External JSON-2 API is new in this version and is not a description of every version. The apps, fields, and methods available depend on your database. The documentation lists external data access under the Custom service plan, rather than One App Free or Standard. Verify your actual plan and hosting arrangement with the provider before contracting.
The API follows user permissions and record rules, and the documentation recommends a dedicated integration user with the minimum permissions required. If a permission is missing, it shows in the result of the request, which is why we test that case early.
The effect on accepting an order is that each call runs as its own transaction. If an order needs several steps, such as creating it, confirming it, and updating related data, one step succeeding does not guarantee the next will, and they cannot be combined into a single transaction this way. An order can be left halfway if one step stops. Actions that must succeed or roll back together need a single suitable method or custom development, which we settle in the scope analysis. The API also does not prevent duplicate external requests on its own, which the integration layer handles as described in the next section.
What happens if the connection drops after the order is created?
The external system sends the order, Odoo creates it, and the response is lost before it arrives. The sender does not know the order went through, so it resends, and without prior design a second order appears. The AWS Builders’ Library (AWS reference), in an article by Malcolm Featonby, describes this risk: resending after a timeout can repeat the effect of an operation that completed but whose reply never arrived. The principle it describes is that the sender attaches a unique identifier to the request, so a resent request can be told apart from a new one.
We call this idempotency: retrying without creating a new effect for the same order. It is a documented design principle, not default behaviour of the JSON-2 API or of every integration, so it falls to your integration layer. The integration layer is the program or service that moves orders between the store and Odoo. Its job here is:
- Save the operation reference: record the external order reference together with its source; the same order number can exist in another store or company.
- Prevent creating it twice: if the same reference arrives again, no second order is created, and the current status is returned instead.
- Coordinate the check and the creation: checking whether the reference exists and creating the order must happen in the same operation, or through an equivalent mechanism that ensures two attempts cannot both create it.
It is not enough to look up the reference and then create the order as two separate steps. If two attempts arrive at the same moment, both may find the reference missing, and each creates an order. That is why we treat the simultaneous-requests test as a core test, not an extra: the same reference is sent twice at once, and the accepted result is exactly one order.
To be clear: a database transaction inside Odoo may protect operations that happen inside Odoo, but it does not turn the store, Odoo, and the integration layer into one transaction. Coordination between the systems is designed and tested at the integration layer.
Three further points apply:
- Similar content alone does not prove a duplicate, since your customer may genuinely want two similar orders. An intended new order carries a new reference, even with the same items.
- Saving the reference and performing the effect must stay consistent: no reference is saved for an order that was not created, and no order is created without a saved reference.
- Amendments and cancellations are separate events handled according to the document’s state, and we do not assume that a stock delivery reflects automatically.
Example: 100 unique orders and 105 attempts
A hypothetical example: 100 unique orders arrived, 98 were created in Odoo and 2 remained in processing, and 5 extra resend attempts brought the total to 105 attempts. The numbers show that attempts can exceed orders without the orders themselves increasing, when the integration layer recognises a repeated reference and returns its status instead of creating a new order. Once the two are processed and verified, the test can finish with one recorded order for each of the 100 unique references. That makes reconciliation easy for the owner: every attempt has a reference, every reference has one order in Odoo, and anything still in processing has a clear status and someone following it.
| Item | Count |
|---|---|
| Unique orders | 100 |
| Created in Odoo | 98 |
| In processing | 2 |
| Extra resend attempts | 5 |
| Total attempts | 105 |
How do you test the integration before approving it?
We suggest covering these cases in the integration acceptance test:
-
A new order arrives with its reference and the correct status.
-
Resend the same reference, then send it in two simultaneous attempts: one order remains in each case.
-
A new reference with the same items: a new order is created.
-
An amendment or cancellation with a delayed status: what does the owner see?
-
An integration user with a missing permission: the cause and the order’s status remain clear enough to follow up.
-
A drop after creation: the status is recovered without duplication.
-
A log you can reconcile, and a named person following up each case.
-
The result approved in a test environment before go-live.
The benefit is that when finance asks about a number, the answer is in the log rather than in one employee’s memory.
What does ToDoOps handle in an integration project?
First we check whether both systems’ interfaces can support the integration, along with scope and plan. Then we define the data, fields, direction, and statuses, run the testing, and document and train your team within the project. The shape and cost of the integration are set after we analyse your scope and your platform. For a first estimate of an ERP application budget, use the ToDoOps calculators; the integration’s quotation items are defined after reviewing both systems.
Start with your hardest exception
The value of starting early is that exceptions do not surprise you mid-project: an order cancelled after shipping, a customer who deliberately repeats an order, or a store quantity that does not match stock. Name your hardest exception now and the implementation scope becomes clear early. Contact ToDoOps and we will review the field map and the statuses with you, try the calculators for a first estimate, and visit the homepage to see what we offer.
References
- Odoo — 19.0 documentation, External JSON-2 API: permissions, record rules, transactions, and availability scope.
- AWS — Making retries safe with idempotent APIs, Malcolm Featonby, AWS Builders’ Library: original link.
