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

如何通过自定义WP-JSON接口处理WooCommerce未付款订单支付?

实现自定义WP-JSON接口调用支付网关完成订单支付

一、注册自定义REST路由

在主题functions.php或自定义插件中添加代码,注册符合要求的API路由:

add_action('rest_api_init', function() {
    register_rest_route(
        'myapp',
        '/order-payment/(?P<order_id>\d+)/(?P<gateway_id>[a-zA-Z0-9_-]+)',
        [
            'methods' => WP_REST_Server::CREATABLE, // 对应POST请求
            'callback' => 'myapp_process_order_payment',
            'permission_callback' => 'myapp_validate_payment_permission',
            'args' => [
                'order_id' => [
                    'validate_callback' => function($param) {
                        return is_numeric($param) && wc_get_order((int)$param);
                    }
                ],
                'gateway_id' => [
                    'validate_callback' => function($param) {
                        $gateways = WC()->payment_gateways->get_available_payment_gateways();
                        return isset($gateways[$param]);
                    }
                ]
            ]
        ]
    );
});

二、权限验证函数

确保只有订单所属用户或管理员能调用接口:

function myapp_validate_payment_permission($request) {
    $order_id = (int)$request['order_id'];
    $order = wc_get_order($order_id);
    if (!$order) return false;

    $current_user_id = get_current_user_id();
    // 允许订单所有者或管理员操作
    return $current_user_id === $order->get_user_id() || current_user_can('manage_woocommerce');
}

三、核心支付处理函数

根据订单ID和网关ID,调用对应支付网关逻辑处理支付:

function myapp_process_order_payment($request) {
    $order_id = (int)$request['order_id'];
    $gateway_id = sanitize_text_field($request['gateway_id']);
    $order = wc_get_order($order_id);
    $gateways = WC()->payment_gateways->get_available_payment_gateways();
    $gateway = $gateways[$gateway_id];

    // 基础校验
    if (!$order->has_status('pending')) {
        return new WP_REST_Response(['error' => '订单状态不是未付款,无法发起支付'], 400);
    }
    if (!$gateway->is_available()) {
        return new WP_REST_Response(['error' => '该支付网关未激活或不可用'], 400);
    }

    // 按不同网关处理支付
    switch ($gateway_id) {
        case 'stripe':
            // Stripe网关处理:创建支付意向,返回客户端密钥
            try {
                $stripe = $gateway->get_stripe();
                $payment_intent = $stripe->paymentIntents->create([
                    'amount' => $order->get_total() * 100, // Stripe以分为单位
                    'currency' => strtolower(get_woocommerce_currency()),
                    'metadata' => ['order_id' => $order_id],
                ]);
                $order->update_meta_data('_stripe_payment_intent', $payment_intent->id);
                $order->save();

                return new WP_REST_Response([
                    'success' => true,
                    'payment_intent_id' => $payment_intent->id,
                    'client_secret' => $payment_intent->client_secret,
                    'order_id' => $order_id
                ], 200);
            } catch (Exception $e) {
                return new WP_REST_Response(['error' => $e->getMessage()], 500);
            }
            break;

        case 'paypal':
            // PayPal网关处理:创建订单,返回授权链接
            try {
                $paypal_order = $gateway->create_order($order);
                $approval_url = '';
                foreach ($paypal_order->links as $link) {
                    if ($link->rel === 'approve') {
                        $approval_url = $link->href;
                        break;
                    }
                }
                $order->update_meta_data('_paypal_order_id', $paypal_order->id);
                $order->save();

                return new WP_REST_Response([
                    'success' => true,
                    'paypal_order_id' => $paypal_order->id,
                    'approval_url' => $approval_url,
                    'order_id' => $order_id
                ], 200);
            } catch (Exception $e) {
                return new WP_REST_Response(['error' => $e->getMessage()], 500);
            }
            break;

        default:
            // 自定义网关处理:调用网关自带的支付处理方法
            $payment_result = $gateway->process_payment($order_id);
            if ($payment_result['result'] === 'success') {
                return new WP_REST_Response([
                    'success' => true,
                    'redirect' => $payment_result['redirect'],
                    'order_id' => $order_id
                ], 200);
            } else {
                return new WP_REST_Response(['error' => $payment_result['message']], 400);
            }
            break;
    }
}

四、前端调用示例

通过POST请求调用接口,需携带WordPress的CSRF验证nonce:

fetch('https://example.com/wp-json/myapp/order-payment/123/stripe', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-WP-Nonce': wpApiSettings.nonce // 需确保前端已加载wpApiSettings对象
    }
})
.then(response => response.json())
.then(data => {
    if (data.success) {
        // 示例:Stripe前端支付流程
        Stripe('你的Stripe公钥').confirmCardPayment(data.client_secret, {
            payment_method: {
                card: cardElement,
                billing_details: {
                    name: '用户姓名'
                }
            }
        }).then(result => {
            if (result.error) {
                console.error('支付失败:', result.error.message);
            } else {
                window.location.href = '/order-received/' + data.order_id;
            }
        });
    } else {
        console.error('请求失败:', data.error);
    }
});

关键注意事项

  • 确保WooCommerce已激活,目标支付网关已配置并启用。
  • Stripe/PayPal的处理逻辑需对应其官方WooCommerce插件版本调整,避免API变动导致错误。
  • 必须传递X-WP-Nonce头进行CSRF验证,防止恶意请求。
  • 支付完成后,依赖网关的webhook自动更新订单状态(如Stripe webhook会将订单标记为已完成)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:07:50