在WordPress和WooCommerce环境中,当开发者构建自定义的“页内结账”表单,允许用户直接在产品页面完成支付而无需跳转到购物车页面时,可能会遇到一个奇怪的现象:表单在WordPress的预览模式下运行良好,订单可以正常处理并支付;然而,一旦在新的浏览器窗口、不同的浏览器或移动设备上访问同一页面,点击确认订单按钮后却被重定向到“您的购物车当前为空”的页面,且订单未被处理。
这个问题的核心在于WooCommerce的会话管理机制。在某些特定的加载上下文中(例如WordPress的预览模式),WooCommerce的购物车会话可能已被隐式加载。但在常规的页面请求中,如果自定义代码在操作购物车之前没有明确地初始化或加载购物车会话,那么对 WC()->cart 对象的任何操作(如 empty_cart() 或 add_to_cart())都可能在一个未完全准备好的购物车实例上进行,导致购物车状态无法正确保存或识别,最终表现为“购物车为空”。
解决此问题的关键在于确保在尝试修改购物车内容之前,WooCommerce的购物车会话已被完全加载。WooCommerce提供了一个专门的函数 wc_load_cart() 来实现这一目的。
通过在对购物车进行任何操作(例如清空购物车或添加商品)之前调用 wc_load_cart(),可以强制WooCommerce从会话中加载当前的购物车状态,从而保证后续的购物车操作能够正确地作用于持久化的购物车数据。
以下是修改后的自定义结账表单PHP代码,其中关键的改动是添加了 wc_load_cart();。
<?php // In page checkout form setlocale(LC_TIME, "it_IT"); $productId = $GLOBALS['inpage_form_product']; $options = $GLOBALS['inpage_form_options']; wp_enqueue_style('inpage-form', get_template_directory_uri() . ($options['inpage_form_style'] ?? '/inpage-form.css')); wp_enqueue_script('inpage-form', get_template_directory_uri() . '/assets/js/inpage-form.js'); $product = wc_get_product($productId); $variations = $product->get_available_variations(); $variations = array_map(function ($variation) use ($options) { return [ 'id' => $variation['variation_id'], 'label' => $variation['attributes']['attribute_quantita'], 'price' => $variation['display_price'], 'regular_price' => $variation['display_regular_price'], 'quantity' => strip_tags($variation['variation_description']), 'highlight' => $options['highlight_label_' . $variation['variation_id']] ?? false, 'highlight_color' => $options['highlight_label_color_' . $variation['variation_id']] ?? false, ]; }, $variations); $initialVariation = $variations[0]; function formatPrice($price) { echo number_format($price, 2, ',', '') . '€'; } // 关键改动:在操作购物车之前加载购物车会话 wc_load_cart(); WC()->cart->empty_cart(); WC()->cart->add_to_cart($productId, 1, $initialVariation['id']); if(class_exists('WC_Gateway_Stripe')) { $stripe = new WC_Gateway_Stripe(); $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; wp_register_style('stripe_styles', plugins_url('assets/css/stripe-styles.css', WC_STRIPE_MAIN_FILE), [], WC_STRIPE_VERSION); wp_enqueue_style('stripe_styles'); wp_register_script('stripe', 'https://js.stripe.com/v3/', '', '3.0', true); wp_register_script('woocommerce_stripe', plugins_url('assets/js/stripe' . $suffix . '.js', WC_STRIPE_MAIN_FILE), ['jquery-payment', 'stripe'], WC_STRIPE_VERSION, true); wp_register_script('woocommerce_gateway_stripe', plugins_url('assets/js/stripe' . $suffix . '.js', WC_STRIPE_MAIN_FILE), ['jquery-payment', 'stripe'], WC_STRIPE_VERSION, true); wp_localize_script( 'woocommerce_stripe', 'wc_stripe_params', apply_filters('wc_stripe_params', $stripe->javascript_params()) ); $stripe->tokenization_script(); wp_enqueue_script('woocommerce_stripe'); } wp_enqueue_script('wc-country-select'); wp_enqueue_script('selectWoo'); wp_enqueue_style('select2'); $shippingMethods = WC()->shipping()->get_packages()[0]['rates']; $chosenMethod = isset(WC()->session->chosen_shipping_methods[0]) ? WC()->session->chosen_shipping_methods[0] : ''; function business_day($days, $abbrv = false) { if($abbrv) { return utf8_encode(strtolower(strftime('%a %e. %m.', strtotime(" $days weekdays")))); } return utf8_encode(strtolower(strftime('%A', strtotime(" $days weekdays")))); } function add_delivery_payment_info() { printf('<div class="inpage-form__delivery_payment">'); printf('<div class="inpage-form__delivery_payment__wrapper">'); printf('<div>'); printf('<div class="inpage-form__delivery_payment__title">Oggi non paghi niente!</div>'); printf('<div class="inpage-form__delivery_payment__description">Paghi alla consegna ?</div>'); printf('</div>'); printf(' <svg enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m19 4.86-8.991 4.383-3.501-1.701-1.458-.711-4.05-1.971 8.991-4.374 3.834 1.864 1.53.738z" fill="#ffa726"/><path d="m9.99 19.779-9.49-4.939v-9.48l9.49 4.37z" fill="#ffcc80"/><path d="m19.5 5.36v9.48l-9.49 4.939v-10.049z" fill="#ffb74d"/><path d="m17.5 23.4c-.142 0-.283-.044-.403-.133-.558-.415-5.447-4.141-5.447-7.302 0-1.855 1.514-3.364 3.375-3.364.957 0 1.848.401 2.475 1.074.627-.673 1.518-1.074 2.475-1.074 1.861 0 3.375 1.509 3.375 3.364 0 3.161-4.89 6.888-5.447 7.302-.12.089-.261.133-.403.133z" fill="#f44336"/><path d="m17.5 24c-.157 0-.314-.05-.447-.148-.62-.46-6.053-4.601-6.053-8.114 0-2.061 1.682-3.738 3.75-3.738 1.063 0 2.054.446 2.75 1.194.696-.748 1.687-1.194 2.75-1.194 2.068 0 3.75 1.677 3.75 3.738 0 3.513-5.433 7.653-6.053 8.113-.133.099-.29.149-.447.149zm-2.75-10.5c-1.241 0-2.25 1.004-2.25 2.238 0 2.142 3.276 5.191 5 6.564 1.724-1.374 5-4.427 5-6.564 0-1.234-1.009-2.238-2.25-2.238-.897 0-1.707.527-2.062 1.343-.238.547-1.137.547-1.375 0-.356-.816-1.166-1.343-2.063-1.343z"/><path d="m10.007 10.5c-.278 0-.545-.155-.675-.422-.181-.372-.026-.821.346-1.002l9.244-4.5c.234-.114.507-.099.726.039.219.136.352.377.352.635v4c0 .414-.336.75-.75.75s-.75-.336-.75-.75v-2.801l-8.166 3.975c-.105.052-.217.076-.327.076z"/><path d="m9.25 20c-.125 0-.25-.03-.366-.096l-8.5-4.75c-.237-.132-.384-.383-.384-.654v-9.25c0-.258.133-.499.353-.636.218-.138.493-.153.726-.039l9.244 4.5c.373.181.527.63.346 1.002-.182.373-.632.525-1.002.346l-8.167-3.974v7.61l8.116 4.536c.362.201.491.658.289 1.021-.137.245-.393.384-.655.384z"/><path d="m.75 6c-.277 0-.544-.155-.674-.422-.181-.372-.026-.821.346-1.002l9.244-4.5c.207-.101.449-.101.656 0l9.256 4.5c.373.181.527.63.346 1.002s-.629.529-1.002.346l-8.928-4.34-8.916 4.34c-.105.052-.217.076-.328.076z"/><path d="m5.25 11.99c-.414 0-.75-.336-.75-.75v-3.8c0-.283.16-.542.413-.67l9.09-4.581c.369-.186.82-.038 1.007.333.186.37.038.821-.333 1.007l-8.677 4.373v3.338c0 .414-.336.75-.75.75z"/></svg>'); printf('</div>'); printf('</div>'); } add_action('woocommerce_review_order_before_submit', 'add_delivery_payment_info'); ?> <div class="inpage-form" data-product-id="<?php echo $productId; ?>"> <div class="inpage-form__form-card"> <h4>Modulo d’ordine</h4> <div class="inpage-form__total"> <span class="inpage-form__regular-price"><?php formatPrice($initialVariation['regular_price']); ?></span> <span class="inpage-form__price"><?php formatPrice($initialVariation['price']); ?></span> </div> <?php if(count($variations) > 1): ?> <ul class="inpage-form__options"> <?php foreach ($variations as $variation) : $singlePrice = $variation['price'] / (float) $variation['quantity']; ?> <li class="inpage-form__option <?php echo $variation['highlight'] ? 'inpage-form__option-highlight' : ''; ?>"> <input type="radio" name="quantity" id="option-<?php echo $variation['id']; ?>" value="<?php echo $variation['id']; ?>" data-regular-price="<?php echo $variation['regular_price']; ?>" data-price="<?php echo $variation['price']; ?>" /> <?php if ($variation['highlight']) { ?> <div class="inpage-form__option-top" <?php echo $variation['highlight_color'] ? 'style="background-color:'. $variation['highlight_color'].'"' : ''; ?>> <?php echo $variation['highlight']; ?> </div> <?php } ?> <label for="option-<?php echo $variation['id']; ?>"> <span class="inpage-form__quantity"><?php echo $variation['quantity']; ?><small>x</small></span> <span class="inpage-form__option-main"> <span class="inpage-form__single-price"><?php formatPrice($singlePrice); ?></span> <span class="inpage-form__quantity-info">a pezzo</span> </span> </label> </li> <?php endforeach; ?> </ul> <?php endif; ?> <div class="inpage-form__checkout"> <form name="checkout" method="post" class="checkout woocommerce-checkout" action="<?php echo esc_url(wc_get_checkout_url()); ?>" enctype="multipart/form-data"> <div class="woocommerce-billing-fields__field-wrapper"> <p class="form-row form-row-wide validate-required validate-email" id="billing_email_field" data-priority="110"> <input type="email" class="input-text" name="billing_email" id="billing_email" placeholder="Indirizzo email " value="" autocomplete="email username"/> <label for="billing_email" class="">Indirizzo email</label> </p> <p class="form-row form-row-wide validate-required validate-phone" id="billing_phone_field" data-priority="100"> <input type="tel" class="input-text " name="billing_phone" id="billing_phone" placeholder="Telefono" value="" autocomplete="tel"/> <label for="billing_phone" class="">Telefono</label> </p> <div class="inpage-form__form-row-online"> <p class="form-row form-row-first validate-required" id="billing_first_name_field" data-priority="10"> <input type="text" class="input-text " name="billing_first_name" id="billing_first_name" placeholder="Nome" value="" autocomplete="given-name"/> <label for="billing_first_name" class="">Nome</label> </p> <p class="form-row form-row-last validate-required" id="billing_last_name_field" data-priority="20"> <input type="text" class="input-text " name="billing_last_name" id="billing_last_name" placeholder="Cognome" value="" autocomplete="family-name"/> <label for="billing_last_name" class="">Cognome</label> </p> </div> </div> <?php if($options['insurance_product'] ?? false) : $insuranceProduct = wc_get_product($options['insurance_product']); ?> <label class="inpage-form__insurance inpage-form__extras" data-product-id="<?php echo $options['insurance_product']; ?>"> <svg id="color" enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m23.491 1.826-5.25-1.786c-.156-.054-.326-.054-.482 0l-5.25 1.786c-.305.103-.509.388-.509.71v4.018c0 4.904 5.474 7.288 5.707 7.387.094.039.193.059.293.059s.199-.02.293-.06c.233-.099 5.707-2.482 5.707-7.386v-4.018c0-.322-.204-.607-.509-.71z" fill="#4caf50"/><path d="m21.286 5.618-2.75 3.5c-.168.214-.417.351-.688.377l-.098.005c-.237 0-.469-.084-.65-.241l-1.75-1.5c-.42-.359-.469-.991-.108-1.41.359-.419.
以上就是解决WooCommerce自定义结账表单在非预览模式下购物车为空的问题的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号