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

WooCommerce中实现银行转账确认后代码仅执行一次的问题

WooCommerce BACS支付订单状态变更仅触发一次动作的解决方案

针对BACS(银行转账)支付方式,管理员需手动修改订单状态确认付款,订单状态变更路径包含以下三种:

  • 待处理(On Hold)→ 处理中(Processing)
  • 待处理(On Hold)→ 已完成(Completed)
  • 待处理(On Hold)→ 处理中(Processing)→ 已完成(Completed)

需求是每个成功订单仅触发一次业务动作,此前尝试通过! $order->get_date_paid('edit')判断是否执行,但因BACS订单始终能获取到支付日期,该方案无效。

解决方案:通过状态变更路径+自定义字段标记实现

核心思路是:仅在订单从「待处理」首次切换到「处理中」或「已完成」时触发动作,并用自定义字段标记已执行状态,避免后续状态变更重复触发。

修正后的代码如下:

add_action( 'woocommerce_order_status_changed', 'bacs_payment_complete', 10, 4 );
function bacs_payment_complete( $order_id, $old_status, $new_status, $order ) {
    // 过滤非BACS支付的订单
    if ( $order->get_payment_method() !== 'bacs' ) {
        return;
    }

    // 仅允许从「待处理」切换到「处理中」或「已完成」时触发
    if ( $old_status !== 'on-hold' || ! in_array( $new_status, array('processing', 'completed') ) ) {
        return;
    }

    // 检查是否已触发过动作,防止重复执行
    if ( $order->get_meta( '_bacs_action_triggered', true ) ) {
        return;
    }

    // --------------------------
    // 这里编写你的业务逻辑代码
    // Do something
    // --------------------------

    // 标记订单已触发动作,后续状态变更不再执行
    $order->update_meta_data( '_bacs_action_triggered', 'yes' );
    $order->save();
}

代码逻辑说明

  1. 支付方式过滤:先排除非BACS支付的订单,减少不必要的判断
  2. 状态变更校验:只有从on-hold(待处理)切换到processing或completed,才符合管理员确认付款的操作场景,覆盖需求中的三种状态路径的首次触发点
  3. 自定义字段标记:通过_bacs_action_triggered这个自定义字段记录订单是否已执行过动作,确保每个订单仅触发一次

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 15:47:26