How to Sync WooCommerce Orders to NetSuite

Push WooCommerce orders into NetSuite as sales orders automatically.

What This Integration Does

WooCommerce captures the order; NetSuite invoices, ships, and books revenue from it. Keeping these in sync manually is one of the most common sources of finance pain in mid-market e-commerce. This workflow takes a WooCommerce order, resolves or creates its NetSuite customer, and writes the matching NetSuite sales order with all line items.

It can run via WooCommerce webhook (real-time) or schedule (batch poll). Each NetSuite sales order carries the WooCommerce order number on otherrefnum, so re-running the workflow on the same order is a no-op rather than a duplicate.

Prerequisites

  • A WooCommerce connection with consumer key + secret and read access to orders.
  • A NetSuite connection with permission to create customers and sales orders and run SuiteQL.
  • An SKU-to-NetSuite-item map (preloaded in MySQL or MongoDB) - this is the slowest call to make per line, so caching matters.

Step 1: Trigger

For real-time, configure a WooCommerce webhook for the order.created topic pointing at a Webhook trigger. For batch, use a Schedule trigger every 10-15 minutes with a since timestamp variable.

Step 2: Fetch the WooCommerce Order

On the webhook path, take id from the payload and call woocommerce get-order for the full record. On the schedule path, call woocommerce list-orders with after={{ since }} and status=processing,completed, then loop.

Step 3: Resolve or Create the NetSuite Customer

Call netsuite run-suiteql to find by email:

SELECT id FROM customer WHERE email = '{{ order.billing.email }}'

Branch on the result via a Condition node. On no-match, call netsuite create-customer with WooCommerce's billing address. Capture the NetSuite internal id in nsCustomerId.

Step 4: Transform Line Items and Reconcile Tax

Use a Transform node to convert each WooCommerce line_item:

  • Look up nsItemId for the line's sku from the cached SKU map.
  • Set quantity from line.quantity.
  • Pick a price strategy: NetSuite expects either tax-inclusive or tax-exclusive rates. WooCommerce reports both subtotal (ex tax) and total (inc tax). Pick one and configure NetSuite tax codes to match, or totals will drift by the rounding error.

Step 5: Create the Sales Order in NetSuite

Call netsuite create-record with type salesOrder:

{
  "entity": { "id": "{{ nsCustomerId }}" },
  "otherrefnum": "{{ order.number }}",
  "trandate": "{{ order.date_created }}",
  "memo": "WooCommerce order {{ order.id }}",
  "item": {
    "items": [
      { "item": { "id": "{{ line.nsItemId }}" }, "quantity": {{ line.quantity }}, "rate": {{ line.rate }} }
    ]
  }
}

Step 6: Write Back the NetSuite ID and Alert on Failure

On success, call woocommerce update-order to stamp a meta field netsuite_id with the NetSuite internal id - this gives finance an immediate cross-reference. On failure, route via Condition to slack send-message with the order id and error so on-call can resolve quickly without log-trawling.

Tips

  • WooCommerce can emit the same webhook twice during retries. Rely on the otherrefnum natural key in NetSuite to reject duplicates.
  • Pre-cache the SKU map nightly - the per-line SuiteQL lookup is the slowest part of this workflow if uncached.
  • Decide which order statuses count as "ready to sync" up front (processing is usually right; pending means payment hasn't cleared).

Common Pitfalls

  • Tax method mismatch - The single biggest source of cent-level drift. Lock down inc-vs-ex tax on day one and validate totals on the first dozen orders.
  • Shipping as a line - WooCommerce reports shipping as its own object. Add it as an explicit shipping line on the NetSuite SO or totals won't reconcile.
  • Currency - For multi-currency WooCommerce stores, push order.currency into the NetSuite SO currency field explicitly.
  • Refunds and partial refunds - This workflow creates orders; refunds are a separate workflow listening on order.refunded.

Testing

Place a single test order in WooCommerce, trigger the workflow, and open the NetSuite sales order. Verify customer (resolved, not duplicated), each line item, tax, shipping, and grand total. Re-fire the webhook on the same order and confirm the duplicate is rejected at the otherrefnum check before going live.

Learn More

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.