fix: remap add-to-cart→product_id for AJAX, fallback zone detection for guest FSN amount

This commit is contained in:
2026-03-05 08:44:52 +01:00
parent f8081c6b65
commit 1f85d517f0
2 changed files with 68 additions and 3 deletions

View File

@@ -113,7 +113,17 @@
e.preventDefault();
$btn.addClass( 'loading' ).data( 'cgkit-fc-handled', true );
$.post( ajaxUrl, $form.serialize() )
// WC's wc-ajax=add_to_cart reads $_POST['product_id'], but the
// single-product form submits the ID as field name 'add-to-cart'.
// Append the correctly-named field so the endpoint finds it.
var serialized = $form.serialize();
var productId = $form.find( '[name="add-to-cart"]' ).val() ||
$form.find( '[name="product_id"]' ).val() || '';
if ( productId && serialized.indexOf( 'product_id=' ) === -1 ) {
serialized += '&product_id=' + encodeURIComponent( productId );
}
$.post( ajaxUrl, serialized )
.done( function ( response ) {
if ( ! response ) {
self.formFallback( $form, $btn );

View File

@@ -3,7 +3,7 @@
* Plugin Name: CommerceKit Floating Cart
* Plugin URI: https://www.commercegurus.com
* Description: Adds a floating cart icon (bottom-right) and auto-opens the CommerceKit minicart after add to cart. Requires CommerceGurus CommerceKit and WooCommerce.
* Version: 1.1.0
* Version: 1.1.1
* Author: CommerceGurus
* Author URI: https://www.commercegurus.com
* License: GPLv3
@@ -19,7 +19,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit;
}
define( 'CGKIT_FC_VERSION', '1.1.0' );
define( 'CGKIT_FC_VERSION', '1.1.1' );
define( 'CGKIT_FC_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'CGKIT_FC_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
@@ -56,6 +56,61 @@ add_filter( 'option_commercekit', function ( $options ) {
return $options;
}, 1 );
/**
* Fallback free-shipping amount for guests / users without a shipping address.
*
* CommerceKit bails with `if (!$free_amount) return ''` BEFORE it reaches the
* `fsn_before_ship` check. The bail happens because for guests WooCommerce zone
* detection falls back to "Rest of World" (empty destination in session), which
* often has no free_shipping method → amount stays 0.
*
* Fix: if the amount is still 0 after CommerceKit's own lookup, redo the zone
* detection using the shop's base country/state so we always resolve against
* the same zone as a logged-in customer in the store's home country.
*/
add_filter( 'commercekit_fsn_get_cart_options', function ( array $options ): array {
// Amount already resolved — nothing to do.
if ( $options['amount'] > 0 ) {
return $options;
}
// Re-run zone detection with the store base location.
$fake_package = [
'destination' => [
'country' => WC()->countries->get_base_country(),
'state' => WC()->countries->get_base_state(),
'postcode' => '',
'city' => '',
],
];
$zone = wc_get_shipping_zone( $fake_package );
$th_sep = wc_get_price_thousand_separator();
$dc_sep = wc_get_price_decimal_separator();
foreach ( $zone->get_shipping_methods( true ) as $method ) {
if ( 'free_shipping' !== $method->id ) {
continue;
}
$instance = $method->instance_settings ?? [];
$amount = isset( $instance['min_amount'] ) ? $instance['min_amount'] : 0;
$requires = isset( $instance['requires'] ) ? $instance['requires'] : '';
$amount = floatval( str_replace( $dc_sep, '.', str_replace( $th_sep, '', $amount ) ) );
// Only use this fallback when the method just needs a minimum order
// amount — coupon-gated thresholds can't be shown without a coupon.
if ( $amount > 0 && 'min_amount' === $requires ) {
$options['amount'] = $amount;
$options['requires'] = $requires;
$options['shipping'] = true;
}
break;
}
return $options;
}, 10 );
/**
* Main plugin class.
*/