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

如何结合WooCommerce钩子实现仅同步Processing状态的已支付订单

解决方案

核心问题分析

woocommerce_new_order钩子在订单刚创建时触发,此时订单默认状态通常是pending(待支付),无法直接满足“仅在订单变为processing时同步”的需求。更可靠的方式是监听订单状态变更为processing的事件,或者在原钩子中增加严格的状态校验(但后者存在异步支付场景下漏同步的风险)。


方案一:替换为状态变更专用钩子(推荐)

使用woocommerce_order_status_processing钩子,该钩子仅在订单状态变为processing时触发,完美匹配你的需求。同时增加“已同步”标记,避免重复发送请求。

修改后的完整代码:

// 替换原钩子,监听订单状态变为processing的事件
add_action('woocommerce_order_status_processing', 'call_order_to_tsm', 10, 1);

function call_order_to_tsm($order_id) {
    $order = wc_get_order($order_id);
    
    // 检查是否已同步过,避免重复请求
    if ($order->get_meta('_tsm_sync_completed')) {
        return;
    }
    
    // 获取订单信息(保留你原有的逻辑)
    $first_name = $order->get_billing_first_name();
    $last_name = $order->get_billing_last_name();
    $phone = $order->get_billing_phone();
    $email = $order->get_billing_email();
    $city = $order->get_billing_city();
    $address = $order->get_billing_address_1();
    $price = $order->get_total();
    $items = $order->get_items();
    $status = $order->get_status();

    // 处理支付日期(注意判断是否为空,避免报错)
    $datePayment = '';
    $payment_date = $order->get_date_paid();
    if ($payment_date) {
        $temp2 = date_create($payment_date);
        $datePayment = date_format($temp2, "Y/m/d H:i:s");
    }

    $order_date = $order->get_date_created();
    $temp = date_create($order_date);
    $date = date_format($temp, "Y/m/d H:i:s");

    $products = [];
    foreach ($items as $index => $item) {
        $product = [];
        $product_name = $item->get_name();
        $product_quantity = $item->get_quantity();
        $product['produktas'] = $product_name;
        $product['kiekis'] = $product_quantity;
        $products[] = $product;
    }

    $json = json_encode($products, JSON_UNESCAPED_UNICODE);

    $message =
        'Užsakymo data: ' . $date . "\n" .
        'Vardas: ' . $first_name . "\n" .
        'Pavardė: ' . $last_name . "\n" .
        'Miestas: ' . $city . "\n" .
        'Adresas: ' . $address . "\n" .
        'Prekės: ' . $json ."\n" .
        'Kaina: ' . $price . "\n" .
        'Apmokejimo data: ' . $datePayment . "\n" .
        'Statusas: ' . $status;

    $TotalOrders = [
        'email' => $email,
        'phone' => $phone,
        'objectname' => 'web_testas',
        'msg' => $message
    ];

    // CURL请求优化:捕获错误并记录日志
    $curl = curl_init();
    curl_setopt_array($curl, array(
        CURLOPT_URL => 'https://www.url.com', // 注意补全协议头(http/https)
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS => http_build_query($TotalOrders), // 若接口需要JSON格式,改为json_encode($TotalOrders)
        CURLOPT_HTTPHEADER => array(
            'HTTP_X_REQUESTED_WITH: XMLHttpRequest'
        ),
    ));

    $response = curl_exec($curl);
    $error = curl_error($curl);
    curl_close($curl);

    // 记录同步结果,方便排查问题
    if ($error) {
        $order->add_meta_data('_tsm_sync_error', $error, true);
        error_log('TSM同步失败,订单ID:'.$order_id.',错误信息:'.$error);
    } else {
        $order->add_meta_data('_tsm_sync_completed', 'yes', true);
        $order->add_meta_data('_tsm_sync_response', $response, true);
        error_log('TSM同步成功,订单ID:'.$order_id);
    }
    $order->save();
}

关键优化点:

  • 替换为woocommerce_order_status_processing钩子,确保仅在订单支付完成、状态变为processing时触发
  • 增加_tsm_sync_completed自定义字段,标记订单是否已同步,避免重复发送请求
  • 增加支付日期的非空判断,避免因异常场景导致的报错
  • 补全CURL请求的协议头(https://),避免请求失败
  • 捕获CURL错误并记录日志,同时保存同步结果到订单元数据,方便后续排查问题
  • 可根据外部接口要求调整CURLOPT_POSTFIELDS格式:若需要JSON,将http_build_query($TotalOrders)改为json_encode($TotalOrders),并添加Content-Type: application/json请求头

方案二:在原woocommerce_new_order钩子中增加状态校验(仅适用于即时支付场景)

如果你的支付方式都是即时完成(比如信用卡、PayPal即时到账),订单创建后立刻变为processing,可以在原函数开头增加状态判断:

add_action('woocommerce_new_order', 'call_order_to_tsm', 2 );
function call_order_to_tsm($order_id)
{
    $order = wc_get_order($order_id);
    
    // 仅处理processing状态的订单,直接跳过其他状态
    if ($order->get_status() !== 'processing') {
        return;
    }
    
    // 以下保留你原有的订单信息获取、CURL请求逻辑...
}

注意事项:

  • 该方案仅适用于即时支付场景,若用户使用异步支付(比如银行转账、COD),订单创建时状态是pending,后续支付完成后状态变为processing,此时woocommerce_new_order钩子已经触发过,会导致漏同步。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 04:31:06