Forum Replies Created

Viewing 15 replies - 1 through 15 (of 37 total)
  • Thread Starter olppa

    (@olppa)

    Solved it.
    It was because of a mismatch between Tidio identifier numbers. For some reason Tidio was trying to access the js-file with a wrong identifier.

    Thread Starter olppa

    (@olppa)

    Hi,
    Our Tidio widget is not visible on our site at all.
    Here is another console error:
    GET https://code.tidio.co/XXX.js net::ERR_ABORTED 404 (Not Found)
    asyncLoad @ (index):3581

    Any help?

    • This reply was modified 6 months, 3 weeks ago by olppa.
    • This reply was modified 6 months, 3 weeks ago by olppa.
    Thread Starter olppa

    (@olppa)

    Hi @mathdaniel

    I tried disabling the COS plugin and the duplicate emails went away.
    I’ve narrowed down the issue to Checkout.php.

    Your duplicates were caused by Checkout::admin_new_order_email triggering WC_Email_New_Order on woocommerce_payment_complete, on top of WooCommerce’s own email on status change. Please either:

    • remove that trigger by default,
    • gate it to offline methods only, and/or
    • add an idempotency guard (order meta) so it can’t send twice.
    Thread Starter olppa

    (@olppa)

    I’m using this snippet as a temporary solution:
    https://pastebin.com/wWKm5NMu

    • This reply was modified 7 months, 3 weeks ago by olppa.
    Thread Starter olppa

    (@olppa)

    What we tried (and results)

    • Disabled candidates one by one on live:
      • WT Smart Coupons, Reaktion (server-side tracking), Redis (and changed object-cache key), Complianz, Profitmetrics, Pixel Manager for WooCommerce, Notification (Bracketspace), and switched Paytrail plugin vendor.
      • Result: 400 still occurs.
    • Payment gateways isolated:
      • Klarna only → 400
      • Paytrail only → 400
    • Updated WooCommerce to 10.2.1: no change.
    • Incognito tests + fully logged-out: still occurs.
    • Staging (exact copy) without Redis/CDN: cannot reproduce.


    Additional context that may help.

    • Single shipping method: Only Posti is available. Most orders qualify for free shipping over €50 (one rate; cost can be €0).
    • Carrier agents plugin (Woo Carrier Agents / Noutopistehaku by Markup.fi):
      • Has a Blocks integration (blocks.js) that used to set checkout extension data immediately on mount (pushing {id:0}), which can trigger an early Store API recalc.
      • We patched it locally to not push extension data until a real agent is selected and a shipping rate is selected.
      • After patching, error still persists on live (so this is likely not the root cause, though it could contribute to timing).
    • Store API debugging:
      • Console (with manual logging) shows wc-blocks:apiFetch → checkout PUT to .../v1/checkout?__experimental_calc_totals=true with data: { payment_method: ... }.
      • The first recalc happens very early—apparently before shipping selection and/or addresses are fully hydrated in the Blocks store.
    • Server-side mitigation we added:
      • A rest_request_before_callbacks filter that injects fallback billing/shipping into __experimental_calc_totals requests (verified in logs: “WC Store API: injected fallback billing/shipping into recalc request”).
      • This removed the billing_address 400, but we still get woocommerce_rest_invalid_shipping_option → suggests shipping selection isn’t ready when recalc fires.

    What we need / questions

    1. Is it expected that Blocks triggers __experimental_calc_totals=truebefore a shipping rate is selected / address hydrated?
      • If not, could this be a timing bug in recent Blocks builds on production (but not in our staging stack)?
    2. On Stores with a single shipping method (often free), should the Store API still reject the recalc with invalid_shipping_option until selection exists, or should Blocks delay/debounce recalc until selection is known?
    3. Any known issues with CDN/proxy front-ends (BunnyCDN) interacting with Store API (e.g., request coalescing/timing) even with no-cache?
    4. Is there an official way to defer the initial __experimental_calc_totals until:
      • wp.data.select('wc/store/cart').getShippingRateSelections() has at least one selection (or getNeedsShipping() is false), and
      • the checkout store has a minimal billing_address?
        (We implemented a client-side middleware to do this; happy to test any recommended approach from your side.)

    Happy to provide a temporary admin user or run any additional diagnostics/logging you recommend (e.g., enabling wc-blocks debug flags you prefer). Since staging can’t reproduce, I suspect a race on live during early checkout hydration.

    Thread Starter olppa

    (@olppa)

    Doesn’t appear to be gateway-specific

    • Enabled only COD (Cash on Delivery) to test different combinations
    • With COD + Paytrail enabled, the error can appear on refresh, before any payment selection change.
    • With Paytrail only and Klarna only, error occurs as well.

    Environments

    • Live: issue occurs. BunnyCDN in front (we did disable caches for testing; response headers still show Bunny as proxy but Cache-Control: no-cache is set). Redis object cache was disabled for tests.
    • Staging: identical code/plugins/theme, no Redis/CDN → cannot reproduce.

    Versions (current at time of testing)

    • WordPress 6.8.2
    • WooCommerce 10.1.2, also tested 10.2.1 → no change
    • Checkout is WooCommerce Blocks (woocommerce/checkout block).
    • Gateways: Klarna for WooCommerce 4.2.0, Klarna Order Management 1.9.9; Paytrail for WooCommerce 2.5.3 (also tested the Markup/“Lauri Karisola” Paytrail plugin) → no change.
    • Theme: Blocksy Child (same on staging).

    Network details (example request/response)

    Request body when the error first surfaced:

    { “payment_method”: “klarna_payments” }

    Request headers (excerpt):

    POST /wp-json/wc/store/v1/checkout?__experimental_calc_totals=true&lang=fi&_locale=site
    X-HTTP-Method-Override: PUT
    Content-Type: application/json
    X-WP-Nonce: eb0fbb1420

    Response: 400 with the messages above.
    Response headers include: server: BunnyCDN-..., cache-control: no-cache.

    • This reply was modified 7 months, 3 weeks ago by olppa.
    Thread Starter olppa

    (@olppa)

    Hi @lovingbro

    Thanks for looking into this.
    The issue started after we switched from the Classic checkout to the Block Checkout.

    Here’s everything we’ve tried and what we’re seeing.
    What’s happening

    • Endpoint: POST /wp-json/wc/store/v1/checkout?__experimental_calc_totals=true&lang=fi&_locale=site (with X-HTTP-Method-Override: PUT)
    • When:
      • On payment method switch and sometimes immediately on a hard refresh of the checkout page (before any interaction).
    • Initial error:

    {
    “code”: “rest_missing_callback_param”,
    “message”: “Parametri tai parametrejä puuttuu: billing_address”,
    “data”: { “status”: 400, “params”: [“billing_address”] }
    }

    After adding a server-side fallback for billing/shipping:
    We now see:

    {
    “code”: “woocommerce_rest_invalid_shipping_option”,
    “message”: “Pahoittelemme, tilaus vaatii toimitustavan.”,
    “data”: { “status”: 400 }
    }

    UI behavior: The error is dismissible; customer can continue to payment. Still a UX issue and suggests an early “recalc totals” race.


    Thread Starter olppa

    (@olppa)

    @mosesmedh I also tried switching my theme in the live site to Storefront in the customizer using the preview theme function and the error message still appears.

    Blocksy does have a companion plugin but I don’t use their WooCommerce addons or modifications.

    Thread Starter olppa

    (@olppa)

    Hi @mosesmedh,
    Thank you for the reply.

    Here is the report: https://pastebin.com/VBcHyfcb

    My staging site is only accessible with a user login.
    You can reproduce and see the issue on the frontend:

    How to reproduce (live site)

    1. Go to https://linssikauppa.fi/tuote/aurinkolasilinssit-ilman-vahvuuksia/
      Select color from dropdown and click “Lisää ostoskoriin” (Add to cart).
      You will be redirected to Cart. Click “Siirry kassalle” (To Checkout).
    2. Fill email, address and phone with dummy data.
    3. Under Maksutapa (Payment method) Toggle payment method (Paytrail ↔ Klarna).
    4. Within ~500ms, a notice appears on top of the order form (translated FI→EN): “Parameter or parameters missing: billing_address.”
    5. Open DevTools → Network and inspect PUT /wp-json/wc/store/v1/checkout?__experimental_calc_totals=true…. The first request’s JSON body lacks billing_address.
    Thread Starter olppa

    (@olppa)

    I did some extensive further troubleshooting and this is probably not caused by Klarna.
    I created a new support thread with WooCommerce.

    More information here:
    https://ww.wp.xz.cn/support/topic/bug-checkout-block-sends-cart-totals-without-billing_address/

    Thread Starter olppa

    (@olppa)

    Almost 5 days and no response.
    Do you need additional information?
    We are still getting this error message in our checkout.

    Thread Starter olppa

    (@olppa)

    Hi @webtoffeesupport ,

    We are using Klarna for WooCommerce and Paytrail for WooCommerce.

    I’ve disabled Smart Coupons for now and I’m still getting a 400 bad request error.
    The error might actually be caused by the Klarna plugin.

    I started a support topic with Klarna regarding the issue.
    You can find more information here:
    https://ww.wp.xz.cn/support/topic/400-bad-request-error-when-changing-payment-method-in-block-checkout/#new-topic-0

    Plugins and themes we use.
    WC version: 10.1.2 (newest)
    Klarna for WooCommerce version: 4.2.0 (newest)
    Klarna Order Management for WooCommerce version: 1.9.9 (newest)
    Paytrail for WooCommerce version: 2.5.3 (newest)
    Blocksy theme and companion plugins (newest versions).

    • This reply was modified 8 months ago by olppa.
    Thread Starter olppa

    (@olppa)

    Polylang’s support answered:

    You are right, Brightplugins_COS and Polylang send this email twice.
    It requires to develop a compatibility. It is the first time we have encountered an issue with this plugin. As of today, we don’t plan a compatibility.
    Would you please contact the development Brightplugins Custom Order Status Manager team? Maybe they already encountered this feedback and have a workaround.

    If Brightplugins has any questions about Polylang, feel free to tell them to contact us. We will provide Polylang license and guide them in our code.

    Thread Starter olppa

    (@olppa)

    @webtoffeesupport Thank you for the quick reply.

    I would also like to raise another issue.

    Smart coupons reserves space for coupons by creating a wrapper div above the checkout form.
    The wrapper classes: wbte_sc_block_coupon_wrapper_div and wt_coupon_wrapper.
    I don’t use the feature to display coupons in the checkout but Smart Coupons reserves the space anyway and creates an unneccesary dom element and whitespace in the checkout.
    Can your developers also see about removing the wrapper divs?

    See image here: https://pasteboard.co/5L11zjLKhToB.png

    I would suggest making the “Display coupon in” setting a global setting.
    There would first be a global setting: “Enable coupons to display” and when selected the the option to display the coupon in myaccount/cart/checkout would appear in the indivual coupon settings.
    This would also reduce unneccessary database queries.

    • This reply was modified 8 months, 2 weeks ago by olppa.
    • This reply was modified 8 months, 2 weeks ago by olppa.
    Thread Starter olppa

    (@olppa)

    Chatgpt suggested fix.
    In wt-smart-coupon-public.js

    Change this:
    $(‘.wc-block-components-shipping-rates-control input[type=”radio”]:checked’).each(function(){ let prefix = $(this).attr(‘name’).split(‘-‘).pop(); shipping_method[prefix] = $(this).val(); });

    To this:
    $(‘.wc-block-components-shipping-rates-control input[type=”radio”]:checked’).each(function(){
    const name = $(this).attr(‘name’) || ”;
    // Try bracket syntax first: shipping_method[0]
    const m = name.match(/[(\d+)]/);
    let prefix = m ? m[1] : (name.includes(‘-‘) ? name.split(‘-‘).pop() : ‘0’);

    const val = $(this).val();
    if (typeof val === ‘string’ && val.length) {
    shipping_method[prefix] = val;
    }
    });

    Handles both shipping_method[0] and shipping-method-0.
    
    Never calls .split() on undefined.
    
    Falls back to package index '0' if neither pattern is present.
    
    Skips empty/undefined values safely.
Viewing 15 replies - 1 through 15 (of 37 total)