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

使用自定义支付网关时排除订单计入营收的技术需求

WooCommerce Credits支付订单排除营收统计解决方案

核心问题在于:Credits支付的订单实际营收已在购买Credits时产生,需让这类订单总额为0(不计入营收),同时保留「Credits」支付方式显示。之前在process_payment阶段修改总额无效,是因为订单创建后关键数据已固化,需提前在订单生成前处理。

步骤1:购物车阶段添加全额折扣(切换支付方式时生效)

当用户选择Credits支付时,自动添加与订单总额等额的折扣,使最终结算金额为0,同时保留支付方式关联。

add_action('woocommerce_cart_calculate_fees', 'apply_credit_payment_full_discount', 10, 1);
function apply_credit_payment_full_discount($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;
    
    // 替换为你的Credits网关ID(对应WC_Gateway_Credits类的id属性)
    $credit_gateway_id = 'credits';
    $chosen_gateway = WC()->session->get('chosen_payment_method');
    
    if ($chosen_gateway === $credit_gateway_id) {
        $total = $cart->get_total('edit');
        // 添加折扣,备注为Credits支付
        $cart->add_fee(__('Credits支付抵扣', 'your-text-domain'), -$total);
    }
}

步骤2:保存原始订单金额到订单元数据

因为订单最终金额为0,需记录实际扣除的Credits金额,后续在process_payment中使用。

add_action('woocommerce_checkout_create_order', 'save_original_total_for_credit_payment', 10, 2);
function save_original_total_for_credit_payment($order, $data) {
    $credit_gateway_id = 'credits';
    $chosen_gateway = WC()->session->get('chosen_payment_method');
    
    if ($chosen_gateway === $credit_gateway_id) {
        // 保存原始订单总额到自定义元字段
        $order->update_meta_data('_original_order_total', $order->get_total());
        // 强制设置订单总额为0(确保统计时不计入营收)
        $order->set_total(0.00);
    }
}

步骤3:修改process_payment方法

调整Credits网关的支付处理逻辑,使用原始订单金额扣除用户Credits,同时确保支付方式正确显示。

class WC_Gateway_Credits extends WC_Payment_Gateway {
    // ... 其他已有代码 ...

    public function process_payment( $order_id ) {
        $order = wc_get_order( $order_id );
        
        // 获取保存的原始订单金额(而非当前0总额)
        $original_total = $order->get_meta('_original_order_total');
        // 兜底:如果元数据不存在,用订单原始总额
        if (empty($original_total)) {
            $original_total = $order->get_total();
        }
        
        // 扣除用户Credits
        $user_id = $order->get_user_id();
        Subscriber::get_instance($user_id)->credits_used($order_id, $original_total);

        // 确保支付方式正确关联并保存
        $order->set_payment_method($this);
        $order->save();

        $order->payment_complete();

        // 清空购物车
        WC()->cart->empty_cart();

        // 返回感谢页跳转
        return array(
            'result'    => 'success',
            'redirect'  => $this->get_return_url( $order )
        );
    }
}

步骤4:订单详情页补充显示原始金额

让用户在订单详情页看到实际扣除的Credits金额,避免混淆。

add_action('woocommerce_order_details_after_order_table', 'display_credit_payment_info', 10, 1);
function display_credit_payment_info($order) {
    if ($order->get_payment_method() === 'credits') {
        $original_total = $order->get_meta('_original_order_total');
        if ($original_total) {
            echo '<div class="credit-payment-info">';
            echo '<p><strong>原始订单金额:</strong>' . wc_price($original_total) . '</p>';
            echo '<p><strong>Credits支付金额:</strong>' . wc_price($original_total) . '</p>';
            echo '</div>';
        }
    }
}

步骤5:结账页切换支付方式实时更新金额

添加JS代码,确保用户切换支付方式时,购物车金额自动刷新。

add_action('wp_footer', 'refresh_cart_on_gateway_switch');
function refresh_cart_on_gateway_switch() {
    if (is_checkout() && !is_wc_endpoint_url()) :
    ?>
    <script>
        jQuery(document).ready(function($){
            $('form.checkout').on('change', 'input[name="payment_method"]', function() {
                $('body').trigger('update_checkout');
            });
        });
    </script>
    <?php
    endif;
}

关键说明

  • 为什么之前修改process_payment无效:订单创建后,WooCommerce已锁定支付方式与金额的关联,此时修改总额会触发内部校验,导致支付方式丢失。提前在订单生成前调整金额,能同时保留支付方式关联。
  • 营收统计排除:订单总额为0时,WooCommerce不会将其计入营收报表,符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 22:49:54