{"id":19034775,"date":"2026-10-02T10:23:29","date_gmt":"2026-10-02T10:23:29","guid":{"rendered":"https:\/\/wordpress.org\/support\/topic\/quantity-doubles-on-cart-page\/"},"modified":"2026-10-02T10:23:29","modified_gmt":"2026-10-02T10:23:29","slug":"quantity-doubles-on-cart-page","status":"publish","type":"topic","link":"https:\/\/wordpress.org\/support\/topic\/quantity-doubles-on-cart-page\/","title":{"rendered":"Quantity doubles on cart page"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Hi team,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;re seeing cart quantities double on our store, and we&#8217;ve traced it to cart items left behind with a <code>_wc_stripe_calculation<\/code> suffix on their cart item key.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Environment<\/strong><\/p>\n\n\n\n<ul>\n<li>Payment Plugins for Stripe WooCommerce 4.0.16<\/li>\n\n\n\n<li>WooCommerce 11.1.2<\/li>\n\n\n\n<li>Flatsome 3.20.5<\/li>\n\n\n\n<li>Apple Pay and Google Pay enabled<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Steps to reproduce<\/strong><\/p>\n\n\n\n<ol>\n<li>Open any product page (simple or variable) and set quantity to 3.<\/li>\n\n\n\n<li>Click &#8220;Add to cart&#8221;. The cart correctly contains 3.<\/li>\n\n\n\n<li>Click &#8220;View cart&#8221;.<\/li>\n\n\n\n<li>The cart now shows two lines for the same product, 3 each (6 total), and the subtotal reflects 6.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">It doesn&#8217;t happen every time, but it&#8217;s easy to reproduce.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What we found<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The cart item keys on the cart page show the duplicate is a leftover from the plugin&#8217;s calculation process:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cart&#091;f0e2c54e09e81ac2fde8ec4c1891264f]&#091;qty]                         -&gt; 3  (the real add)\ncart&#091;f0e2c54e09e81ac2fde8ec4c1891264f_wc_stripe_calculation]&#091;qty]   -&gt; 3  (the duplicate)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Other items already in the cart also ended up re-keyed with the <code>_wc_stripe_calculation<\/code> suffix, but those weren&#8217;t duplicated.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When the duplication happened, we could see a <code>?wc-ajax=wc_stripe_frontend_request&amp;path=\/wc-stripe\/v1\/cart\/calculation<\/code> request. It looks like the temporary calculation cart isn&#8217;t being fully cleaned up or restored, and the suffixed items persist in the customer&#8217;s real session cart.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Disabling the Mini-cart location for Apple Pay and Google Pay did <strong>not<\/strong> fix it. We suspect the cart-page express buttons trigger the same calculation request.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Temporary workaround<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;re currently running this snippet, which removes the leaked items (or re-keys them if the original is missing) when the cart loads from the session. It has resolved the issue for us:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">php<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>add_action( 'woocommerce_cart_loaded_from_session', 'fix_stripe_calculation_cart_items', 99 );\nfunction fix_stripe_calculation_cart_items( $cart ) {\n\tif ( isset( $_GET&#091;'wc-ajax'] ) &amp;&amp; 'wc_stripe_frontend_request' === $_GET&#091;'wc-ajax'] ) {\n\t\treturn;\n\t}\n\t$suffix   = '_wc_stripe_calculation';\n\t$len      = strlen( $suffix );\n\t$contents = $cart-&gt;get_cart_contents();\n\t$changed  = false;\n\tforeach ( $contents as $key =&gt; $item ) {\n\t\tif ( substr( $key, -$len ) !== $suffix ) {\n\t\t\tcontinue;\n\t\t}\n\t\t$original_key = substr( $key, 0, -$len );\n\t\tif ( isset( $contents&#091; $original_key ] ) ) {\n\t\t\tunset( $contents&#091; $key ] );\n\t\t} else {\n\t\t\t$item&#091;'key']               = $original_key;\n\t\t\t$contents&#091; $original_key ] = $item;\n\t\t\tunset( $contents&#091; $key ] );\n\t\t}\n\t\t$changed = true;\n\t}\n\tif ( $changed ) {\n\t\t$cart-&gt;set_cart_contents( $contents );\n\t\t$cart-&gt;calculate_totals();\n\t}\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Could you look into why the <code>_wc_stripe_calculation<\/code> items persist in the session after the calculation request? I&#8217;m happy to provide more details or test a patch.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Thanks<\/p>\n","protected":false},"template":"","class_list":["post-19034775","topic","type-topic","status-publish","hentry"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/topic\/19034775","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/topic"}],"about":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/types\/topic"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/topic\/19034775\/revisions"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/support\/wp-json\/wp\/v2\/media?parent=19034775"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}