WooCommerce移动结账优惠券表单后应用优惠券丢失客户数据的解决方法
问题解决:WooCommerce优惠券表单移动后清空结账数据
问题原因
默认的form-coupon.php模板包含独立的<form>标签,将其嵌套到主结账表单内会触发HTML表单嵌套(HTML不允许该结构)。提交优惠券时仅会提交优惠券表单数据,主结账表单的用户输入未被提交,页面刷新后已填信息丢失。
修正后的代码
/* * 移除结账页面顶部默认的优惠券表单 */ remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10 ); /* * 在订单总计区域下方添加自定义优惠券表单 */ add_action( 'woocommerce_review_order_after_order_total', 'woocommerce_checkout_coupon_form_custom' ); /* * 渲染自定义优惠券表单(避免嵌套表单,使用AJAX提交) */ function woocommerce_checkout_coupon_form_custom() { echo '<tr class="coupon-form"><td colspan="2">'; ?> <div class="woocommerce-form-coupon"> <p><?php esc_html_e( 'Have a coupon? Enter it below.', 'woocommerce' ); ?></p> <p class="form-row form-row-first"> <input type="text" name="coupon_code" class="input-text" placeholder="<?php esc_attr_e( 'Coupon code', 'woocommerce' ); ?>" id="coupon_code" value="" /> </p> <p class="form-row form-row-last"> <button type="button" class="button" name="apply_coupon" value="<?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?>" id="apply_coupon"><?php esc_html_e( 'Apply coupon', 'woocommerce' ); ?></button> </p> <div class="clear"></div> </div> <?php echo '</td></tr>'; } /* * 添加AJAX处理优惠券应用逻辑 */ add_action( 'wp_ajax_apply_checkout_coupon', 'apply_checkout_coupon_ajax' ); add_action( 'wp_ajax_nopriv_apply_checkout_coupon', 'apply_checkout_coupon_ajax' ); function apply_checkout_coupon_ajax() { if ( ! isset( $_POST['coupon_code'] ) ) { wp_send_json_error( esc_html__( 'Coupon code is missing.', 'woocommerce' ) ); } $coupon_code = sanitize_text_field( $_POST['coupon_code'] ); $coupon = new WC_Coupon( $coupon_code ); if ( ! $coupon->exists() || ! $coupon->is_valid() ) { wc_add_notice( esc_html__( 'Invalid coupon code.', 'woocommerce' ), 'error' ); } else { WC()->cart->apply_coupon( $coupon_code ); wc_add_notice( esc_html__( 'Coupon applied successfully.', 'woocommerce' ), 'success' ); } ob_start(); wc_get_template( 'checkout/review-order.php' ); $review_order_html = ob_get_clean(); wp_send_json_success( array( 'review_order_html' => $review_order_html, 'notices' => wc_get_notices() ) ); } /* * 添加JS处理AJAX提交 */ add_action( 'wp_footer', 'checkout_coupon_ajax_js' ); function checkout_coupon_ajax_js() { if ( is_checkout() && ! is_wc_endpoint_url() ) { ?> <script> jQuery(document).ready(function($) { $('#apply_coupon').on('click', function(e) { e.preventDefault(); var couponCode = $('#coupon_code').val(); $.ajax({ type: 'POST', url: '<?php echo admin_url( 'admin-ajax.php' ); ?>', data: { action: 'apply_checkout_coupon', coupon_code: couponCode }, success: function(response) { if (response.success) { // 更新订单回顾区域 $('.woocommerce-checkout-review-order').replaceWith(response.data.review_order_html); // 更新通知 $('.woocommerce-notices-wrapper').html(''); $.each(response.data.notices, function(type, notices) { $.each(notices, function(i, notice) { $('.woocommerce-notices-wrapper').append('<div class="woocommerce-' + type + '">' + notice + '</div>'); }); }); // 清空优惠券输入框 $('#coupon_code').val(''); } else { $('.woocommerce-notices-wrapper').html('<div class="woocommerce-error">' + response.data + '</div>'); } }, error: function() { $('.woocommerce-notices-wrapper').html('<div class="woocommerce-error"><?php esc_js_e( 'Failed to apply coupon. Please try again.', 'woocommerce' ); ?></div>'); } }); }); }); </script> <?php } } /* 显示优惠券输入框 */ // 自定义CSS function mujuonly_add_inline_css() { $mustlogin_custom_css = " .woocommerce-form-coupon { display:block !important; margin-top: 15px; } .woocommerce-form-coupon .form-row { display: inline-block; margin-right: 10px; } "; wp_add_inline_style( 'woocommerce-inline', $mustlogin_custom_css ); } add_action( 'wp_enqueue_scripts', 'mujuonly_add_inline_css' );
代码说明
- 移除默认表单:保留原有移除逻辑,避免重复显示优惠券表单
- 自定义表单结构:去掉独立
<form>标签,避免嵌套问题,改用按钮触发AJAX请求 - AJAX处理逻辑:验证优惠券有效性,应用优惠券后返回更新后的订单回顾区域HTML
- 前端交互:拦截按钮点击事件,发送AJAX请求更新页面内容,全程不刷新页面,保留用户已填信息
- 样式优化:调整优惠券表单的显示样式,提升页面美观度
内容的提问来源于stack exchange,提问作者eMikkelsen
相关产品推荐
相关产品推荐

