← All postsTechnical

Will my WooCommerce app show the wrong price or stock?

By · Published October 20, 2026 · 9 min read

“Will the app ever show a price my store doesn’t?” is the right question to ask before you put an app in front of your customers. A shopper who sees one price in the app and another at checkout does not think “stale cache”. They think you tried something.

The honest answer depends on which path a piece of data travels. A StoreToNative app has three, and they run at three different speeds. This post walks through each one with the real endpoint names, so you or your developer can check every step on your own store. It is written by the vendor, so treat it as a list of things to verify, not a promise.

Three paths, three speeds

  1. Your catalogue: phone to your store. Products, prices and stock are read straight from your store.
  2. Store events: your store to StoreToNative. Orders and product changes arrive by WooCommerce webhook.
  3. Your design: StoreToNative to the phone. Theme, layout and add-ons arrive as a config file when the app starts.

Path 1: the phone reads your catalogue from your store

Product lists, product pages, categories and price filters come from the WooCommerce Store API on your own domain, at /wp-json/wc/store/v1. It is the public, read-only API that WooCommerce ships with your store. The phone needs no keys to use it, and none are on the phone.

There is no StoreToNative copy in the middle. Every product list asks your store when it loads, and pull-to-refresh asks again. The app only joins two identical requests that are on the wire at the same moment into one; it does not keep prices around as a cache. So a price you change in wp-admin is the price the next list shows. There is no sync step to wait for.

Two details are worth knowing:

  • Offline. The offline catalogue add-on (on by default) saves the last list each category loaded. It is used only when your store cannot be reached, and then the app says so with a banner, “Showing saved catalog — you appear to be offline”, and a Retry button. When your store answers, the saved list is not used.
  • Variations. The Store API lists a variable product’s options, but not the price and stock of each variation. Those exist only in WooCommerce’s REST API, which needs your store keys, so the phone asks StoreToNative’s API and our API asks your store. That answer is kept for up to 60 seconds per product. In the worst case, a variation price change takes about a minute to reach the option picker. If your store cannot be reached, the app opens the product’s own page on your website instead of the picker. More on variations in variable products in a mobile app.

And whatever a list showed, the order is priced by your store. The default checkout hands the cart to your store’s own checkout page. The optional native checkout form (off by default) asks your store for shipping options through StoreToNative, creates the order in WooCommerce, and then takes the shopper to payment on your store’s own order-pay page. That is “native checkout form, payment on your own gateway”.

One thing this path cannot fix is a cache in front of /wp-json/. If your host or CDN caches those answers, the app sees the cached answer, the same as any visitor would.

Path 2: your store tells StoreToNative what changed

When you connect, StoreToNative also copies your products and categories into its own database. The phone does not show prices from this copy. It is used for the work that happens on our side: the phone preview in the console, the product counts behind your category tabs, back-in-stock and price-drop alerts, and the variation picker (it only opens for products in the copy).

To keep that copy current, the sync registers four webhooks on your store. These are the exact topic names:

  • order.created
  • order.updated
  • product.updated
  • product.deleted

You can see them in wp-admin under WooCommerce → Settings → Advanced → Webhooks, named “StoreToNative order.created” and so on. Each delivery is signed by your store, and StoreToNative checks the signature before it uses anything.

What each one does:

  • product.updated carries the whole product. StoreToNative applies it directly to that one product in the copy, without re-reading your catalogue. A product that is no longer published is removed.
  • product.deleted removes the product from the copy.
  • order.created and order.updated become events in the console feed and your revenue numbers. When order.updated carries a new status and the push add-on is on, the phone that placed the order gets an order-status notification. It goes out once per real status change, so a store that sends the same update three times does not send the shopper three notifications.

Bulk edits. Edit 500 products at once and WooCommerce sends 500 webhooks. Each one is a small write for one product. The expensive part, recounting your categories and product totals, waits until the deliveries pause (5 seconds by default) and then runs once. If a delivery cannot be applied directly, StoreToNative falls back to a full re-sync. That is collected the same way, and by default webhooks can start at most one full re-sync per minute per app, so a steady stream of edits cannot make us page through your whole store again and again.

Repairs. WooCommerce pauses a webhook after repeated failed deliveries. StoreToNative answers each delivery before it does slow work like sending a push, and it answers “received” even when processing fails, so one bad minute does not switch the hook off. Every successful sync also reads your store’s webhook list and re-creates any of the four that is missing, paused or pointing somewhere else. That happens when you press Sync now, and on the automatic sync: a connected store with auto-sync on that has not synced for six hours gets a full sync on its own (the check runs every hour). A delivery your host dropped means a stale few hours in our copy, not a stale month.

Note there is no product.created in the list. On the phone that does not matter: a new product shows in the app as soon as it is published, because Path 1 reads your store directly. Our copy picks it up on the next sync. Press Sync now if you want it in the console preview straight away. The WooCommerce tab help page shows the webhook status and the Auto-sync switch, and WooCommerce webhooks and product sync covers the host settings that can silently block webhooks.

These are webhooks into StoreToNative. Going the other way, on Pro and Agency, StoreToNative can send its own signed webhooks to your tools, for events like a new install, an abandoned cart or a back-in-stock alert. That is a separate feature: see Webhooks & API.

Path 3: design changes and the two-restart rule

Your theme, layout, home sections, navigation and add-on switches live in the app’s config. Every installed app reads it from GET /v1/apps/:id/config on api.storetonative.com. Each change you save to one of those settings in the console raises a number in it, configRevision, by one.

On each full launch (a cold start, not a return from the background), the app asks for the current config before it draws the first screen, and waits a moment for the answer (under a second on a normal launch). If the answer arrives in time, the change shows on that launch. If the network is slow, the app opens with the config it saved last time, keeps downloading in the background, and saves the new config for the launch after. A broken answer is never used, so a bad network can never stop the app from opening.

That is why we say a change reaches installed apps within a launch or two, with no rebuild and no store re-review. When you test it yourself, use two full restarts: close the app completely, open it, close it completely again, open it again. That always works. The app icon, the app name and brand-new features still need a new build. OTA, explained lists what changes over the air and what does not.

Prove a change is live with one command. Take your app id from the console address bar (/builder/<APP_ID>) and run:

curl -s https://api.storetonative.com/v1/apps/<APP_ID>/config | python3 -c "import json,sys; print(json.load(sys.stdin)['configRevision'])"

Save a small change in the console and run it again. If the number is one higher, the change is live on the server, and every installed app will have it within a launch or two. The config holds your design, not secrets, which is why the endpoint is public. Running the command does not count as a launch in your analytics.

When the store itself is wrong: the stale price index

Sometimes the app is right and the store is wrong. WooCommerce keeps a product lookup table, wc_product_meta_lookup, and price sorting and price filters read it. After a demo import or a tool that writes straight to the database, some published products can have no row in that table. Their product pages show the right price, but sorting by price or filtering by price can treat them wrongly, and in the app it looks like the app is broken.

The companion plugin’s Store readiness card runs 14 checks inside wp-admin. One of them, Price sorting and filters, counts published products that have no row in the lookup table and shows a warning if there are any. The row has a Rebuild price index button, which asks WooCommerce’s own tool to rebuild the table in the background. It is the same job as WooCommerce → Status → Tools → Product lookup tables → Regenerate. If the plugin cannot tell (an older WooCommerce without that table, or a query the host stops), the row says “skipped” instead of warning you about a problem it cannot see. The 14 store-readiness checks tells the story behind each check, and the WordPress plugin help page lists them all.

Test it on your own store before launch

Do this once before launch, and again after any big plugin or host change:

  1. Webhooks. Open WooCommerce → Settings → Advanced → Webhooks. You should see four rows named StoreToNative, all Active. If one is missing or paused, press Sync now in the console and look again.
  2. A price. Change the price of one simple product in wp-admin. In the app, pull to refresh the list it is in. The new price should be there. Change it back.
  3. Stock. Set one product to out of stock, refresh, and check the app shows it that way. Change it back.
  4. A variation. Change the price of one variation, wait a minute, and open the product’s option picker.
  5. An order. With notifications allowed on your phone and the push add-on on, place a test order in the app. Then change its status in wp-admin, for example to Completed. The phone should get an order-status notification.
  6. A design change. Run the curl command above, change one colour in the console, run it again, then do two full restarts on the phone.
  7. The price index. Open the plugin’s Store readiness card. Price sorting and filters should pass. If it warns, press Rebuild price index.
  8. Offline. Turn on airplane mode and open a category you have already visited. You should see the saved list under the offline banner, not an empty screen.

If every step passes, the three paths are working: your catalogue comes from your store, your store tells us what changed, and your design reaches phones within a launch or two.

Related reading