自定义WooCommerce支付网关对接:订单提交拦截位置与实现方式
在WooCommerce中拦截订单提交并对接自定义支付网关与CRM的方案
嘿,这个需求我之前帮不少独立开发者和电商团队处理过,刚好可以给你捋清楚具体怎么做——核心是选对WooCommerce的钩子,再把你的API交互逻辑嵌进去。
一、选对拦截订单的核心钩子
WooCommerce提供了几个关键钩子,最适合你的场景的是:
woocommerce_checkout_process:这个钩子是用户点击「下单」按钮后,WooCommerce准备创建订单之前触发的。在这里做验证逻辑刚好,一旦验证不通过,能直接终止订单创建,还给用户友好提示。- 如果你需要提前修改订单数据再做验证,可以搭配
woocommerce_before_checkout_create_order,但核心的支付/CRM验证还是推荐用前者。
二、具体实现步骤(代码示例)
下面是完整的可参考代码,你可以根据自己的API文档调整参数:
// 注册结账流程拦截钩子 add_action('woocommerce_checkout_process', 'custom_order_interception_with_crm_payment'); function custom_order_interception_with_crm_payment() { // 1. 提取结账页面的核心数据 $checkout_data = WC()->checkout->get_posted_data(); $cart_total = WC()->cart->total; $customer_email = WC()->customer->get_billing_email(); $customer_phone = WC()->customer->get_billing_phone(); // 提取购物车商品明细(按需调整字段) $cart_items = array_map(function($item) { return [ 'product_id' => $item->get_product_id(), 'product_name' => $item->get_name(), 'quantity' => $item->get_quantity() ]; }, WC()->cart->get_cart()); // 2. 向CRM发送客户/订单预提交数据 $crm_api_url = 'https://你的CRM接口地址'; $crm_payload = json_encode([ 'email' => $customer_email, 'phone' => $customer_phone, 'expected_total' => $cart_total, 'products' => $cart_items ]); $crm_response = wp_remote_post($crm_api_url, [ 'headers' => ['Content-Type' => 'application/json'], 'body' => $crm_payload, 'timeout' => 15 // 设置超时,避免页面卡死 ]); // 检查CRM请求是否成功 if (is_wp_error($crm_response)) { wc_add_notice(__('抱歉,暂时无法连接客户管理系统,请稍后重试。', 'woocommerce'), 'error'); return; // 终止流程 } // 3. 调用支付网关API做支付可行性验证 $payment_api_url = 'https://你的支付网关验证接口'; $payment_payload = json_encode([ 'amount' => $cart_total, 'currency' => get_woocommerce_currency(), 'customer_email' => $customer_email, 'unique_order_ref' => uniqid('wc_') // 生成唯一订单标识 ]); $payment_response = wp_remote_post($payment_api_url, [ 'headers' => [ 'Content-Type' => 'application/json', 'Authorization' => 'Bearer 你的支付网关API密钥' // 按需添加鉴权 ], 'body' => $payment_payload, 'timeout' => 15 ]); // 处理支付网关响应 if (is_wp_error($payment_response)) { wc_add_notice(__('支付服务暂时不可用,请稍后重试。', 'woocommerce'), 'error'); return; } $payment_result = json_decode(wp_remote_retrieve_body($payment_response), true); if (!$payment_result['success']) { // 支付网关拒绝,终止订单创建并提示用户 wc_add_notice(__('支付验证失败:' . $payment_result['message'], 'woocommerce'), 'error'); } // 所有验证通过,WooCommerce会自动继续创建订单流程 }
三、进阶方案:自定义支付网关类
如果你的需求更复杂(比如需要跳转到第三方支付页面、处理回调),更规范的做法是扩展WooCommerce的WC_Payment_Gateway类,注册成独立的支付方式:
class Custom_CRM_Payment_Gateway extends WC_Payment_Gateway { public function __construct() { $this->id = 'custom_crm_payment'; $this->method_title = '自定义CRM支付'; $this->method_description = '对接自有CRM与支付网关的支付方式'; $this->has_fields = false; // 初始化设置选项 $this->init_form_fields(); $this->init_settings(); $this->title = $this->get_option('title'); $this->api_key = $this->get_option('api_key'); // 注册后台设置保存钩子 add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']); // 注册支付回调处理钩子 add_action('woocommerce_api_custom_crm_payment', [$this, 'handle_payment_callback']); } // 后台设置表单 public function init_form_fields() { $this->form_fields = [ 'enabled' => [ 'title' => '启用/禁用', 'type' => 'checkbox', 'label' => '启用该支付方式', 'default' => 'yes' ], 'title' => [ 'title' => '支付方式名称', 'type' => 'text', 'default' => '自定义支付' ], 'api_key' => [ 'title' => '支付网关API密钥', 'type' => 'password', 'default' => '' ] ]; } // 处理支付请求 public function process_payment($order_id) { $order = wc_get_order($order_id); // 1. 同步订单数据到CRM $crm_payload = json_encode([ 'order_id' => $order_id, 'customer_email' => $order->get_billing_email(), 'total' => $order->get_total(), 'status' => 'pending' ]); wp_remote_post('https://你的CRM订单接口', [ 'headers' => ['Content-Type' => 'application/json'], 'body' => $crm_payload ]); // 2. 发起支付请求到网关 $payment_payload = json_encode([ 'order_id' => $order_id, 'amount' => $order->get_total(), 'return_url' => $this->get_return_url($order), 'cancel_url' => wc_get_checkout_url() ]); $payment_response = wp_remote_post('https://你的支付网关发起接口', [ 'headers' => [ 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $this->api_key ], 'body' => $payment_payload ]); $payment_data = json_decode(wp_remote_retrieve_body($payment_response), true); if ($payment_data['success']) { // 跳转到支付网关页面 return [ 'result' => 'success', 'redirect' => $payment_data['payment_url'] ]; } else { wc_add_notice('支付发起失败:' . $payment_data['message'], 'error'); return ['result' => 'fail']; } } // 处理支付网关回调 public function handle_payment_callback() { $order_id = isset($_GET['order_id']) ? sanitize_text_field($_GET['order_id']) : ''; $payment_status = isset($_GET['status']) ? sanitize_text_field($_GET['status']) : ''; if (!$order_id) exit; $order = wc_get_order($order_id); if ($payment_status === 'success') { $order->payment_complete(); $order->add_order_note('支付成功,已同步到CRM'); // 可选:再次同步订单状态到CRM wp_remote_post('https://你的CRM状态更新接口', [ 'body' => json_encode(['order_id' => $order_id, 'status' => 'completed']) ]); wp_redirect($this->get_return_url($order)); } else { $order->update_status('failed', '支付失败'); wp_redirect(wc_get_checkout_url()); } exit; } } // 注册自定义支付网关 add_filter('woocommerce_payment_gateways', 'register_custom_crm_payment_gateway'); function register_custom_crm_payment_gateway($gateways) { $gateways[] = 'Custom_CRM_Payment_Gateway'; return $gateways; }
四、关键注意事项
- 一定要用WordPress原生的
wp_remote_post发送API请求,不要用原生CURL,它会自动适配服务器环境的SSL、代理等配置。 - 给API请求设置合理的
timeout(比如10-15秒),避免第三方服务响应慢导致结账页面长时间无响应。 - 错误提示要清晰友好,让用户知道具体问题,而不是模糊的“操作失败”。
- 如果需要在订单创建完成后做后续同步(比如更新CRM订单状态),可以用
woocommerce_new_order或者woocommerce_order_status_changed钩子。
内容的提问来源于stack exchange,提问作者eComEvo
相关产品推荐
相关产品推荐

