How the Wbsync replacement works
Derwent Distributors: website orders into MYOB, and MYOB stock and prices back onto the website. Status as of 6 Oct 2026: shadow mode (watching, not writing).
The big picture
Each kind of data moves one way only, and every field has exactly one owner, so the two systems never fight over a number.
Wbsync today vs our bridge
| Wbsync (current) | Our bridge | |
|---|---|---|
| Orders → MYOB | On-hold orders become sales orders | Same, polled every minute |
| Stock → website | Hourly, raw MYOB on-hand | Every 15 min, on-hand minus stock on open sales orders |
| Price → website | Regular price only | Regular price only (dealer levels via a later upload tool) |
| Duplicate protection | Unknown | Checks MYOB for the Woo order number before every post |
| Problems | Silent | Order held + alert; status page lists everything |
| Cost | A$29/month (card failing) | Runs on the existing data VPS |
What happens when a dealer places an order
Dealer checks out on the website
The site creates the order as On hold with the dealer's tier prices, and Woo lowers stock straight away.The bridge picks it up within a minute
It only looks at on-hold orders after an agreed start number, so nothing Wbsync already posted is touched.Find the dealer's MYOB customer card
Uses the link saved on the dealer's website account. No link yet? If exactly one MYOB card has the same email, it links automatically. Otherwise the order is held and flagged.Find every product in MYOB
By exact SKU. If any line can't be found, the whole order is held — never a partial order.Check it hasn't been posted already
Searches MYOB for a sales order carrying this Woo order number. If one exists, it links to it instead of posting again.Create the MYOB sales order
PO field = Woo order number, prices exactly as charged (GST-inclusive, GST split out), customer note copied across.Read it back and compare
Customer, items, quantities, prices and total must match. Any mismatch raises an alert.Stamp the website order
Saves the MYOB sales order number on the Woo order with a note. Tim still marks orders Completed himself.
How stock and prices get to the website
Stock
MYOB's on-hand count only drops when Tim invoices a sales order — often days after the website sale. Pushing raw on-hand (what Wbsync does) makes stock bounce back up in between.
So the bridge sends on hand − units on open sales orders, never below 0. That includes Tim's phone and counter orders.
Prices
The MYOB selling price (GST-inclusive) becomes the website's regular price. The five dealer price levels are not touched — MYOB's web version doesn't expose them.
Only products that actually changed are updated.
Safety brakes
The run stops without writing anything if MYOB returns fewer than 500 items, or plans more than 300 stock or 100 price changes at once. (This already caught one bug during testing.)
Who owns which field
| Field | Owner | How it moves |
|---|---|---|
| SKU, name, active/inactive | MYOB | → website |
| Stock | MYOB (minus committed) | → website, every 15 min |
| Regular price | MYOB | → website, every 15 min |
| 5 dealer price levels | MYOB desktop export | → website, via a planned upload tool |
| Photos, descriptions, categories | Website | stays on the website |
| Orders | Website | → MYOB sales orders |
Inside the bridge
Code lives in derwent-myob-api/bridge/ and runs on the data VPS as two scheduled jobs. Each run starts, does its work, and exits — there's no long-running process to crash.
The pieces
| Piece | What it does |
|---|---|
bff.py | Opens the shared MYOB browser login, copies the security headers the MYOB web app itself uses, and replays them for our requests. |
myob.py | The MYOB calls: find item by SKU, item account and tax code, customer address, new sales order, create, read back, search by PO number, item list with stock, open sales orders. |
woo.py | Website calls: on-hold orders, customers, products and variations, batch updates, order notes. |
payload.py | Turns a Woo order into a MYOB sales order. Pure maths, no network — GST split, line totals, read-back comparison. |
service.py | The order process: link customer, map items, dedupe, post, read back, stamp Woo. |
stock.py | Works out available stock and price per SKU, diffs against the website, applies safety caps, then writes (or records, in shadow). |
store.py | The SQLite memory: what happened to each order, cached sales order details, stock run history. |
routes.py | The status page: counts by state, problem orders, latest stock run. |
Every order has a state
The bridge writes a row for each Woo order before it does anything risky, so if the server restarts mid-way it knows exactly where it was.
| State | Meaning | What happens next |
|---|---|---|
| synced | MYOB sales order exists and matches | Done. MYOB number saved on the Woo order. |
| shadow_ready | Shadow mode: payload built and saved to a file, nothing posted | Compared by hand against what Wbsync posts. |
| submitting | About to post, or posting now | If found here after a crash, MYOB is searched first. |
| unknown | MYOB timed out or errored mid-post | Every run searches MYOB for the PO number. Found → synced. Never re-posted blindly. |
| held_customer | No linked MYOB card and no unique email match (or a guest order) | Alert. Link the dealer once; the next run posts it. |
| held_sku | A product SKU isn't in MYOB, or matches twice | Alert. Fix the SKU; the whole order then posts. |
| held_other | Fee lines, or lines + shipping don't add up to the Woo total | Alert for a person to look at. |
| readback_mismatch | Posted, but MYOB's saved copy differs | Alert. Not deleted automatically. |
Worked example
A level-5 dealer orders 2 tyres at $202.67 each. Woo stores the line total $405.34 with tax 0 (the site doesn't calculate tax). MYOB prices include GST, so the bridge sends:
| Field | Value | From |
|---|---|---|
| Customer | dealer's MYOB card | link on the Woo account |
| PO number | Woo order number | so it can always be found again |
| Item | MYOB item for the SKU | exact SKU match |
| Units / unit price | 2 × $202.67 | exactly what the dealer was charged |
| Line amount | $405.34 | GST-inclusive |
| GST | $36.85 | $405.34 ÷ 11 |
| Ex-GST | $368.49 | amount − GST |
| Account, tax code | item's income account, GST | MYOB item settings |
| Note | dealer's checkout note | Woo customer note |
This is the same shape Wbsync produces — we checked a test order against one of Wbsync's, field by field, before deleting it.
Settings
| Setting | Now | Purpose |
|---|---|---|
BRIDGE_MODE | shadow | shadow = check and record only; live = write to MYOB and Woo |
BRIDGE_START_AFTER_ORDER_ID | 3670 | Only orders after this number. Set to Wbsync's last order at switch-over. |
STOCK_SUBTRACT_COMMITTED | on | Subtract units on open MYOB sales orders |
STOCK_SYNC_PRICES | on | Push MYOB regular price |
STOCK_MAX_CHANGES / PRICE_MAX_CHANGES | 300 / 100 | Brakes: above these, nothing is written and an alert fires |
Running it day to day
Is it working?
Open the status page: counts by state, any held orders, and the last stock run with its change counts.An order is held
Read the reason, fix the cause (link the dealer, correct the SKU), and the next minute's run posts it. No manual re-entry.Pause everything
Stop the two timers on the VPS. Orders simply wait on hold in Woo and are picked up when it's restarted.MYOB login expired
Runs exit without writing; the existing login-rescue process restores the session, then runs resume.How the bridge talks to MYOB
The data VPS already keeps a logged-in MYOB browser session for the 30-minute data pull. The bridge borrows that session and makes the same requests the MYOB web app makes when you click Save — so there's no extra MYOB subscription.
The data pull, the daily item job, the order bridge and the stock sync share one lock, so they take turns with the login instead of colliding.
Shadow mode, then switch-over
Shadow running now
Both syncs do all their checks and record what they would do, but write nothing. First stock run: 2,069 MYOB items, all matched; 20 stock and 7 price changes planned.Compare against Wbsync
For the next few real orders, check our would-be sales order matches the one Wbsync posts.Link dealers
6 dealers already matched from past orders with no conflicts; the rest link automatically by email on their next order.Switch to live
Set the start order to the last one Wbsync posted, turn on live mode, stop Wbsync. Never both at once.