You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce用户账户信用抵扣功能问题及优化需求

WooCommerce账户信用功能问题修复

已实现的基础功能代码

1. 自定义用户账户信用字段

add_action( 'show_user_profile', 'extra_user_profile_fields' );
add_action( 'edit_user_profile', 'extra_user_profile_fields' );

function extra_user_profile_fields( $user ) { ?>
    <h3 style="padding-top:20px"><?php _e("Account Credit", "blank"); ?></h3>

    <table class="form-table">
    <tr>
        <th><label for="credit_amount"><?php _e("Credit Amount (£)"); ?></label></th>
        <td>
            <input type="text" name="credit_amount" id="credit_amount" value="<?php echo esc_attr( get_the_author_meta( 'credit_amount', $user->ID ) ); ?>" class="regular-text" /><br />
            <span class="description"><?php _e("Customer shop credit balance."); ?></span>
        </td>
    </tr>
    </table>
<?php }

add_action( 'personal_options_update', 'save_extra_user_profile_fields' );
add_action( 'edit_user_profile_update', 'save_extra_user_profile_fields' );

function save_extra_user_profile_fields( $user_id ) {
    if ( empty( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'update-user_' . $user_id ) ) {
        return;
    }
    
    if ( !current_user_can( 'edit_user', $user_id ) ) { 
        return false; 
    }
    update_user_meta( $user_id, 'credit_amount', $_POST['credit_amount'] );
}

2. 初始信用抵扣逻辑(存在问题)

function woocommerce_filter_checkout_for_coupons( $subtotal, $compound, $cart ) {     

        // Your logic to get store credit value for a user will go here
        $store_credit = get_user_meta(get_current_user_id(), 'credit_amount', true );
            
        if($store_credit > 0){

            $coupon_name = 'store-credit';
            $coupon = array($coupon_name => $store_credit);

            $cart->applied_coupons = array($coupon_name);
            $cart->set_discount_total($store_credit);
            $cart->set_total( $cart->get_subtotal() - $store_credit);
            $cart->coupon_discount_totals = $coupon;
        }
    
    

    return $subtotal; 
}

add_filter( 'woocommerce_cart_subtotal', 'woocommerce_filter_checkout_for_coupons', 10, 3 );

add_action( 'woocommerce_thankyou', 'checkout_save_user_meta' );
 
function checkout_save_user_meta( $order_id ) {
   $order = wc_get_order( $order_id );
   $user_id = $order->get_user_id(); 
   update_user_meta( $user_id, 'credit_amount', 0 );

}

当前存在的问题

  • VAT(增值税)与订单总计计算错误:原价£109.20抵扣£50后,应按£59.20计算20% VAT(£11.84),总计£71.04,但系统仍按原价计算VAT
  • 订单成功/感谢页无折扣/优惠券显示,税费与总计错误
  • 后台订单页、客户及管理员通知邮件中无折扣显示,税费与总计错误
  • 信用扣除逻辑不合理:无论是否使用信用抵扣,订单完成后都会将用户信用重置为0
  • 无法同时使用用户信用与后台创建的优惠券代码

完整修复代码

替换原有信用抵扣逻辑代码,使用WooCommerce官方钩子实现规范的折扣计算与流程:

// 添加账户信用作为购物车折扣项
add_action( 'woocommerce_cart_calculate_fees', 'apply_account_credit_discount', 10, 1 );
function apply_account_credit_discount( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;

    $user_id = get_current_user_id();
    if ( $user_id == 0 ) return; // 未登录用户不处理

    $available_credit = (float) get_user_meta( $user_id, 'credit_amount', true );
    if ( $available_credit <= 0 ) return;

    // 计算可抵扣金额:不超过购物车税前小计
    $cart_subtotal = (float) $cart->get_subtotal();
    $discount_amount = min( $available_credit, $cart_subtotal );

    // 添加折扣项,标记为账户信用抵扣
    $cart->add_fee( __( 'Account Credit Discount', 'woocommerce' ), -$discount_amount, true, '' );

    // 存储实际抵扣金额到会话,用于后续订单处理
    WC()->session->set( 'used_account_credit', $discount_amount );
}

// 订单完成后扣除实际使用的信用额度
add_action( 'woocommerce_order_status_completed', 'deduct_used_account_credit' );
function deduct_used_account_credit( $order_id ) {
    $order = wc_get_order( $order_id );
    $user_id = $order->get_user_id();
    if ( $user_id == 0 ) return;

    $used_credit = (float) WC()->session->get( 'used_account_credit' );
    if ( $used_credit <= 0 ) return;

    // 更新用户剩余信用
    $current_credit = (float) get_user_meta( $user_id, 'credit_amount', true );
    $new_credit = max( 0, $current_credit - $used_credit );
    update_user_meta( $user_id, 'credit_amount', $new_credit );

    // 清除会话记录
    WC()->session->__unset( 'used_account_credit' );
}

// 在订单详情页显示账户信用抵扣记录
add_action( 'woocommerce_order_details_after_order_table', 'display_account_credit_on_order' );
function display_account_credit_on_order( $order ) {
    $used_credit = (float) get_post_meta( $order->get_id(), '_used_account_credit', true );
    if ( $used_credit <= 0 ) return;

    echo '<tr><th>' . __( 'Account Credit Used', 'woocommerce' ) . '</th><td>£' . number_format( $used_credit, 2 ) . '</td></tr>';
}

// 将信用抵扣金额保存到订单元数据
add_action( 'woocommerce_checkout_create_order', 'save_account_credit_to_order' );
function save_account_credit_to_order( $order ) {
    $used_credit = (float) WC()->session->get( 'used_account_credit' );
    if ( $used_credit > 0 ) {
        $order->update_meta_data( '_used_account_credit', $used_credit );
    }
}

修复说明

  1. VAT计算错误修复:使用woocommerce_cart_calculate_fees钩子添加折扣,WooCommerce会自动基于折扣后的金额计算税费,确保VAT计算准确
  2. 折扣显示问题修复:
    • 购物车、结算页自动显示账户信用折扣项
    • 感谢页、后台订单详情页通过woocommerce_order_details_after_order_table钩子展示信用抵扣记录
    • 订单元数据保存抵扣金额,如需在邮件中显示,可修改WooCommerce订单邮件模板,添加对应元数据调用代码
  3. 信用扣除逻辑优化:仅在订单完成时扣除实际使用的信用额度,未使用信用的订单不会修改用户账户余额
  4. 支持与优惠券同时使用:通过add_fee添加的折扣可与后台创建的优惠券叠加生效,不影响原有优惠券功能

内容的提问来源于stack exchange,提问作者richag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:47:13