PluginUs.Net - Business Tools for WooCommerce and WordPress

[realize your idea - make your dreams come true]

Support Forum

You need to log-in to create request (topic) to the support

Webhook question

The support doesn work on Saturdays and Sundays, so some Friday requests can be answered on Monday. If you have problems with registration ask help on contact us page please
If you not got email within 24~36 business hours, firstly check your spam box, and if no any email from the support there - back to the forum and read answer here. DO NOT ANSWER ON EMAILS [noreply@pluginus.net] FROM THE FORUM!! Emails are just for your info, all answers should be published only here.
The support doesn work on Saturdays and Sundays, so some Friday requests can be answered on Monday.

Hello,

At Tibladin, we have set up a web hook to synchronize product changes (using the product.change hook) to a Point-of-Sales system (Ka-ching POS).

This works well for us, and we use it to synchronize both the product catalog with products, variants, images and extra metadata - as well as product stock.

The Point-of-Sales system is used in the physical Tibladin store and uses the default currency of the shop, DKK.

We have observed, that we once in a while receive product.change webhooks where the price is not the configured price in DKK.
For instance, a product priced 59 DKK comes over as 93.20.
By debugging a bit, we can see that 93.20 is the exact exchange rate configured in Fox for Norwegian kroner NOK.

In the data received by the web hook, we can't easily distinguish this from an actual intended price change.

After a bit of googling, I now suspect that the product.change webhook sends over the price in NOK when the stock is changed as a side effect of a sale to a Norwegian user.

Is this a situation that you have experience with? Do you have a workaround or a recommendation for how to handle this? For instance, if this is a side effect of a sale, if I could recognize that fact, I could skip the product change and only use the data for changing the stock count.

Thank you for your help.

Kind regards

Ole

Hello Ole

When a customer who has NOK selected places an order, WooCommerce reduces the stock and fires the product update webhook. By default WooCommerce does not send the webhook right away. It queues it in Action Scheduler, and the queue is often processed straight after the customer's request by a background request that carries that customer's cookies. So FOX still sees NOK as the current currency while WooCommerce builds the JSON payload, and the price getters return converted values. 59 DKK converted to NOK is the 93.20 you received. When the queued task runs later from WP-Cron or from an admin request, there are no customer cookies and the price comes through in DKK. That is why it happens only once in a while.

The webhook data has no flag that tells a sale-triggered update apart from a manual edit, so filtering on your side would not be reliable. The cleaner fix is on the shop side. FOX has an internal switch that disables price conversion for the current PHP process only. The code below turns it on right before WooCommerce builds the webhook payload and turns it off right after, so prices in the payload are always in the base currency (DKK). It also temporarily sets the base currency, which covers fixed per-currency prices if you use them. Visitors and customers on the site are not affected, because the switch lives only in the process that delivers the webhook.

Please add this to the functions.php of your child theme, or use a code snippets plugin:

// Disable FOX price conversion only while this process builds a webhook payload
function woocs_webhook_block_on() {
    global $WOOCS;
    $_REQUEST['woocs_block_price_hook'] = 1;
    if (is_object($WOOCS)) {
        // fixed per-currency prices read current_currency directly
        $GLOBALS['woocs_prev_currency'] = $WOOCS->current_currency;
        $WOOCS->current_currency = $WOOCS->default_currency;
    }
}
function woocs_webhook_block_off() {
    global $WOOCS;
    unset($_REQUEST['woocs_block_price_hook']);
    if (is_object($WOOCS) && isset($GLOBALS['woocs_prev_currency'])) {
        $WOOCS->current_currency = $GLOBALS['woocs_prev_currency'];
        unset($GLOBALS['woocs_prev_currency']);
    }
}
// async delivery via Action Scheduler (WooCommerce default)
add_action('woocommerce_deliver_webhook_async', 'woocs_webhook_block_on', 1);
add_action('woocommerce_deliver_webhook_async', 'woocs_webhook_block_off', 999);
// sync delivery (if async delivery is disabled on the site)
add_action('woocommerce_webhook_process_delivery', 'woocs_webhook_block_on', 1);
add_action('woocommerce_webhook_process_delivery', 'woocs_webhook_block_off', 999);

To test it, switch to NOK on the front end, buy a product and check the payload that arrives in Ka-ching. The price should now be in DKK.

If this does not solve it, we will need the full picture of your setup to hook in at the right place:

  1. Which webhook topic(s) you use exactly (product.updated, product.created, etc.) and the API version selected for the webhook.
  2. Whether the webhook is set up in WooCommerce > Settings > Advanced > Webhooks, or created by a plugin or custom code. If it is custom code, please share it.
  3. Whether any custom code or plugin changes the webhook payload or delivery (for example filters on woocommerce_webhook_payload or woocommerce_webhook_deliver_async).
  4. Whether Ka-ching also reads products from the REST API (wc/v3) directly, or only receives webhooks.
  5. An example of a bad payload (the price fields are enough) together with the time of the order that triggered it.

Kind regards, Alex

Hi Alex,
We have reviewed the timing, and we can see that there were no orders for the product in question - neither in NOK or DKK around the time where the 'product.update' webhook was sent.
Instead it looks like an immediate response to a stock quantity change.
In the store they counted the stock of a product (id 2006) to be 14.
It was updated through WooCommerce's REST API by POST'ing
{
   "stock_quantity": 14
}
to
[STORE_URL]/wp-json/wc/v3/products/2006
The 'product.update' webhook appears to be an immediate response to that, which is expected since the webhook should fire no matter the source of the change.
But it appears that some logic - and I assume this logic must come from Fox since it relates to foreign currencies - decides that the prices of the subsequent webhook should be in NOK.
We have just tested the hypothesis, and we appear to get prices in random currencies. We have observed both DKK (default currency), NOK and SEK.
Can we force the webhook based on REST api stock quantity changes to be in the default currency?
regards
Ole

Hello Ole

Thank you for checking the timing, that is very useful. You are right: in your case the trigger is not an order but the stock update through the REST API. That does not change the solution, but it explains the random currencies better, so let me complete my previous answer.

FOX remembers the currency each visitor has selected. By default it keeps this per visitor IP address. A server to server request, like the POST from Ka-ching or the background task that delivers the webhook, has no real visitor behind it. So FOX picks up whatever currency is stored for the IP that request comes from, and that value may have been left there by someone else. This is how a webhook can come out in DKK one time and in NOK or SEK the next, with no order involved.

The snippet from my previous message does not depend on what triggered the webhook. It hooks into the webhook delivery itself, and while the payload is being built it switches off the conversion and sets the base currency. So a stock change from the REST API, a manual edit and an order should all produce prices in DKK.

To move forward, we need a more complete picture from you:

1. Did you add the snippet from my previous message? If yes, please paste here the exact code you added, so we can see it is the same and nothing was lost when copying. Then repeat the same test (POST stock_quantity to product 2006) and tell us which currency the price comes in.
2. In FOX settings, on the Options tab, which storage type is selected (Session, Transient, or other), and is the option for cached shops enabled?
3. Is the site behind Cloudflare, a CDN or another proxy?
4. The questions from my previous message are still open and they matter here: which API version the webhook uses, whether the webhook was created in WooCommerce > Settings > Advanced > Webhooks or by a plugin or custom code, and whether Ka-ching also reads products directly from the REST API (wc/v3) or only receives webhooks.

Point 4 is important. If Ka-ching also reads products through the REST API, those responses can be affected the same way, and we will extend the snippet to cover them too.

Point 3 matters for your online customers as well. If the visitor IP is not detected correctly behind a proxy, several visitors can end up sharing the same stored currency on the site itself. Then a customer can suddenly see prices in a currency they never selected. With your answers we can check that and recommend the right storage setting.

If it turns out that the shop is cached or behind a proxy, we will most likely recommend switching the storage to Transient and enabling the option"I am using cache plugin on my site". In that mode every browser gets its own storage key, so visitors who share an IP no longer share a currency. Please note that this setting is for your online customers only. It does not affect the webhook, because a server request has no browser, so the snippet is still what fixes the webhook.

Kind regards, Alex