解决WooCommerce自定义结账表单在非预览模式下购物车为空的问题

DDD

DDD

2025-07-01

894人浏览

原创

解决woocommerce自定义结账表单在非预览模式下购物车为空的问题

本文深入探讨了WooCommerce自定义页面结账表单在预览模式下正常工作,但在常规访问时显示“购物车为空”的常见问题。核心原因在于WooCommerce购物车会话未被正确加载和初始化。教程将详细介绍如何通过在代码中引入 wc_load_cart() 函数来确保购物车会话的正确加载,从而解决此问题,并提供完整的代码示例及开发注意事项,帮助开发者构建稳定可靠的自定义结账流程。

理解问题根源

在WordPress和WooCommerce环境中,当开发者构建自定义的“页内结账”表单,允许用户直接在产品页面完成支付而无需跳转到购物车页面时,可能会遇到一个奇怪的现象:表单在WordPress的预览模式下运行良好,订单可以正常处理并支付;然而,一旦在新的浏览器窗口、不同的浏览器或移动设备上访问同一页面,点击确认订单按钮后却被重定向到“您的购物车当前为空”的页面,且订单未被处理。

这个问题的核心在于WooCommerce的会话管理机制。在某些特定的加载上下文中(例如WordPress的预览模式),WooCommerce的购物车会话可能已被隐式加载。但在常规的页面请求中,如果自定义代码在操作购物车之前没有明确地初始化或加载购物车会话,那么对 WC()->cart 对象的任何操作(如 empty_cart() 或 add_to_cart())都可能在一个未完全准备好的购物车实例上进行,导致购物车状态无法正确保存或识别,最终表现为“购物车为空”。

解决方案:强制加载购物车会话

解决此问题的关键在于确保在尝试修改购物车内容之前,WooCommerce的购物车会话已被完全加载。WooCommerce提供了一个专门的函数 wc_load_cart() 来实现这一目的。

Comet AI 浏览器
Comet AI 浏览器

下载 Comet AI 浏览器,体验由 Perplexity AI 驱动的革命性上网方式。内置 AI 助手可实时总结网页、跨标签页对比信息、自动执行任务。告别繁琐操作,让 AI 成为你的浏览副驾,大幅提升研究与工作效率。支持 Windows、macOS、Android 和 iOS。

下载

通过在对购物车进行任何操作(例如清空购物车或添加商品)之前调用 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><path d="m9.99 19.779-9.49-4.939v-9.48l9.49 4.37z" fill="#ffcc80"></path><path d="m19.5 5.36v9.48l-9.49 4.939v-10.049z" fill="#ffb74d"></path><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><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><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><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><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><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"></path></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" echo :>>
                            <?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%20echo%20esc_url(wc_get_checkout_url());%20?>" 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><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.

">

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

浏览器 wordpress

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
wordpress seo
wordpress seo

WordPress网站SEO优化方法有:1、选择一个SEO友好的主题,具有清晰的代码结构,快速的加载速度和响应式设计;2、使用SEO插件,优化你的标题标签,元描述,关键字,XML站点地图等;3、优化你的内容,内容是SEO优化的核心;4、优化你的网站速度;5、创建友好的URL;6、使用内部链接;7、优化图像;8、使用社交媒体;9、定期更新你的网站;10、监控和分析你的网站等等。

2023.09.18

2049

6

wordpress下载后怎么安装
wordpress下载后怎么安装

安装前准备:确保服务器满足要求、获取安装文件、创建数据库。上传 wordpress 文件。创建数据库和用户。运行安装程序:选择语言、输入数据库信息、网站标题和管理员信息。安装 wordpress。安装后配置:设置永久链接、安装主题、安装插件、创建内容。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.15

2232

6

WordPress插件教程
WordPress插件教程

本专题整理热门WordPress插件资源,涵盖SEO优化、缓存加速、安全防护、表单管理、电商扩展等插件推荐与使用教程。

2026.06.16

78

17

WordPress建站教程大全
WordPress建站教程大全

本专题汇总WordPress教程相关内容,包括WordPress安装教程、建站教程、使用技巧、网站管理经验和实战案例,帮助用户快速掌握WordPress建站与运营方法。

2026.06.16

70

20

WordPress开发教程
WordPress开发教程

本专题提供WordPress开发技术资料,包括主题开发、插件开发、自定义功能开发、API调用及性能优化等内容。

2026.06.16

108

25

火山引擎API Key获取教程
火山引擎API Key获取教程

火山引擎API Key适合需要调用火山引擎云服务、AI模型、火山方舟接口或其他开放能力的开发者参考。本专题整理控制台入口、账号认证、服务开通、API Key创建、密钥复制保存、权限检查、调用测试和Key无效等常见问题排查。

2026.08.04

1

10

火山引擎API接入教程
火山引擎API接入教程

火山引擎API接入适合需要在应用、脚本、后台服务或AI工具中调用火山引擎能力的开发者参考。本专题整理控制台入口、服务开通、API Key获取、接口地址配置、请求参数填写、调用测试、权限设置、额度查询和常见接口报错排查。

2026.08.04

3

10

火山引擎DeepSeek API调用教程
火山引擎DeepSeek API调用教程

火山引擎DeepSeek API适合需要在应用、脚本、智能体或AI编程工具中调用DeepSeek模型的开发者参考。本专题整理火山引擎控制台入口、模型服务开通、API Key获取、Base URL配置、模型名称填写、调用测试、额度查询和常见接口报错排查。

2026.08.04

1

10

火山引擎控制台操作教程
火山引擎控制台操作教程

火山引擎控制台中常用功能包括API密钥管理、模型调用配置、云资源查看、账单明细、用量统计和权限分配。本专题整理控制台基础操作、服务开通流程、Key创建与保存、费用消耗查看、子账号权限设置和调用失败排查,方便开发者完成日常管理。

2026.08.04

3

10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
如何在 Windows 11 上安装 XAMPP
如何在 Windows 11 上安装 XAMPP

共1课时 | 127人学习

第二十三期_前端开发
第二十三期_前端开发

共98课时 | 10.4万人学习