WooCommerce and EDI
WooCommerce EDI integration
WooCommerce has no X12 or EDIFACT in it. A retailer's 850 becomes a WooCommerce order through the REST API, with the PO number in order meta data, and the 855, 856, 810 and 846 are built from the order, its tracking and the stock quantity. We build that layer per trading partner, host it and run it.
What WooCommerce does natively
WooCommerce has no X12 or EDIFACT translator. Its REST API, wc/v3, exchanges JSON, and the API reference has no EDI resource, checked on 3 October 2026. What core WooCommerce ships is the store side of an EDI flow, with four gaps an EDI partner notices.
| EDI need | WooCommerce | Gap |
|---|---|---|
| The retailer's PO number | Order meta_data |
No PO number field |
| An order from outside the checkout | POST /wp-json/wc/v3/orders with line items |
The line item sku and price are read-only |
| A shipment with tracking | No shipment record in core | Shipment Tracking extension or the Order Fulfillments feature, off by default |
| An invoice with its own number | No invoice record | Number from accounting or the integration |
| Stock for the 846 | stock_quantity per product or variation |
One number, no locations |
| A trigger on change | Webhooks, sent in the background through wp-cron | Disabled after 5 consecutive failed deliveries |
A supplier that trades with a US retailer still needs the 850, 855, 856 and 810 in X12, with the retailer's version, qualifiers and pack hierarchy. That part runs outside WooCommerce. This page is the WooCommerce side of our EDI integration; the platform itself is covered under WooCommerce integrations.
How an 850 becomes a WooCommerce order
Unlike a cart-based API, WooCommerce creates an order with all its lines in one request. The diagram maps one line of PO 4500018236, the example used on our document pages.
The request for both lines, after the lookups:
{
"customer_id": 52,
"created_via": "edi",
"status": "processing",
"billing": { "company": "HARBOR RETAIL", "email": "" },
"shipping": { "company": "HARBOR RETAIL DC 07", "address_1": "1200 DOCK STREET",
"city": "COLUMBUS", "state": "OH", "postcode": "43215", "country": "US" },
"meta_data": [ { "key": "_edi_po_number", "value": "4500018236" } ],
"line_items": [
{ "product_id": 731, "quantity": 24, "subtotal": "300.00", "total": "300.00" },
{ "product_id": 744, "quantity": 12, "subtotal": "105.00", "total": "105.00" }
]
}
Line 2 carries 12 of the 16 ordered units of item 10499, because 12 were in stock, and the 855 confirms 24 and 12. The totals check by hand: 24 times 12.50 is 300.00, 12 times 8.75 is 105.00, and the order is 405.00, the merchandise total on the 810. created_via can only be set when the order is created, which makes it a reliable filter for EDI orders in reports.
The status is a decision. The default is pending, which reserves nothing. WooCommerce reduces stock when an order reaches processing, on-hold or completed, and the same move from pending to processing sends the Processing order email to the billing address. An EDI order created as pending leaves the stock untouched, so the store and the next 846 both oversell.
The technical reality of this pair
No published rate limit. The wc/v3 REST API documents no request limit; WooCommerce's own rate limiting covers only POST requests on the Store API and is off by default. Capacity is that of the WordPress server. A batch request holds at most 100 objects by default and returns HTTP 413 above that. A morning file of 120 purchase orders is 2 batch requests, 100 and 20, and each order in a batch returns its own result or error, so one bad order does not block the other 99.
Webhooks are a hint. WooCommerce delivers webhooks in the background through wp-cron and disables a webhook after 5 consecutive failed deliveries. The integration polls orders with modified_after (available since WooCommerce 5.8) as a backstop, so a cancelled order still reaches the partner when the webhook did not.
Stock for the 846. Core WooCommerce keeps one stock_quantity per product or variation. An 846 reports that figure, minus a buffer per partner when you set one. Stock per warehouse needs an inventory plugin or the ERP behind the store; see which stock counts.
Authentication. REST keys are bound to a WordPress user and stop working when that user is deleted, and the API needs pretty permalinks. An integration user that is removed in a cleanup stops every EDI order at once, so the integration raises an alert on the first 401.
What WooCommerce and X12 store differently
- Item identity. PO107 carries a UPC. WooCommerce needs its own
product_idorvariation_id; the SKU on a line is read-only, and a GTIN sits in a product field or meta key that differs per store. The integration keeps the lookup from UPC or case GTIN to product per partner. - Units. A WooCommerce line has a quantity and no unit of measure. 2
CAwith 12 per case is 24 units in WooCommerce, and the 855, 856 and 810 convert back to 2 cases. See units of measure. - Addresses. WooCommerce has
address_1andaddress_2, astateas ISO code or name andcountryas ISO 3166-1 alpha-2. An N3 segment carries two lines of up to 55 characters, and N4 a state code. The retailer's location code, 0007, has no field and is kept in order meta data for the 856. - Order number.
numberis read-only and is the order ID unless a plugin changes it. The 855 and 856 refer to the retailer's PO number from meta data, never to the WooCommerce number.
When it goes wrong
| What happens | What the integration does |
|---|---|
| A UPC in the 850 has no product | The order is held with the PO1 line shown; the 997 has already gone out |
| The same PO arrives twice | _edi_po_number exists for this customer: held, no second order |
| An order in a batch returns an error | Only that order is held; the rest of the batch is written |
| The REST key returns 401 | The queue stops for this store and an alert is raised; nothing is lost |
| The partner rejects an 856 with a 997 | AK3 and AK4 are shown with segment and element; the corrected notice goes out under a new control number |
Every document has a status in the dashboard, with the raw file and the WooCommerce order it became or came from.
We build the integration to your WooCommerce store and your trading partners, host it and run it, for a fixed build price and a monthly fee. A new partner starts as a dry run that creates no orders and sends nothing, and you approve the first documents. The same model on other platforms is under Shopify EDI integration and Magento EDI integration; with an ERP behind the store, see WooCommerce ERP integration. Tell us which retailer asked you for EDI.
Frequently asked questions
Does WooCommerce have native EDI?
No. WooCommerce exchanges JSON through its REST API, and its reference documents no X12, EDIFACT or EDI endpoint. It does have what an EDI flow writes to and reads from: orders with line items and meta data, customer accounts, order notes, stock per product and webhooks. The translation, the envelope and the acknowledgments run outside WooCommerce.
Is there a WooCommerce EDI plugin?
Plugins exist that connect a store to an EDI network or a web portal. A plugin moves the documents. The decisions per partner still have to be made: which item ID the partner sends, cases against units, where the PO number is stored, which status an EDI order gets, and what happens to a document the partner rejects. Those are the parts we build.
Will the retailer get a WooCommerce order email?
It can. When an order moves from pending to processing, WooCommerce sends its Processing order email to the billing email address. For EDI orders the integration leaves the billing email empty or switches that email off for the partner's orders, so the retailer's buyer receives the 855 and nothing else.
Where does the invoice number for the 810 come from?
Not from core WooCommerce, which has no invoice record. Its "Customer invoice" email is the order details with a payment link. The 810 takes its number from your accounting system or from an invoice plugin, or the integration assigns one per partner and keeps it unique, because a retailer rejects a reused invoice number.
Can the 856 be sent without a shipping plugin?
Only with the data from somewhere else. Core WooCommerce has no shipment record; tracking numbers come from the Shipment Tracking extension, the Order Fulfillments feature where it is switched on, or the shipping tool. Cartons and SSCCs come from packing. The integration combines them with the order to build the 856.
Tell us what you need
Tell us which systems you use and what needs to work better. We reply personally within one working day. We help you define the work, then agree the price and timing before you commit.
- You know the price and the timeline before you commit to anything
- We work out the connection that takes the work off your hands
- We handle the build, hosting, monitoring and maintenance
- Your team has less information to retype and fewer discrepancies to chase