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

如何从Woocommerce Stripe支付网关获取React所需的clientSecret

解决WooCommerce Stripe支付卡在payment_intent.requires_action的问题

核心问题原因

你当前用的stripe.createSource()是Stripe已弃用的Source API,WooCommerce Stripe插件在这个流程下生成的是Source类型的client_secret(src_client_secret_xxx),但stripe.confirmCardPayment()需要的是Payment Intent类型的client_secret(pi_xxx_secret_xxx),两者不兼容,导致3D Secure验证无法正常触发,支付卡在requires_action状态。

解决方案步骤

1. 后端调整:提前生成Payment Intent并返回client_secret

WooCommerce Stripe插件默认支持Payment Intent流程,通过自定义代码在订单创建前生成Payment Intent,把正确的client_secret传递给前端。

在WooCommerce主题的functions.php或自定义插件中添加以下代码:

add_action('woocommerce_checkout_init', 'generate_stripe_payment_intent');
function generate_stripe_payment_intent() {
    if (!is_checkout()) return;

    // 转换购物车总额为分(Stripe API要求单位为最小货币单位)
    $amount = (int)round(WC()->cart->total * 100);
    $currency = strtolower(get_woocommerce_currency());

    // 初始化Stripe SDK
    if (!class_exists('Stripe\Stripe')) {
        require_once WC_STRIPE_PLUGIN_PATH . '/includes/stripe-php/init.php';
    }
    \Stripe\Stripe::setApiKey(get_option('woocommerce_stripe_settings')['secret_key']);

    try {
        // 创建Payment Intent
        $payment_intent = \Stripe\PaymentIntent::create([
            'amount' => $amount,
            'currency' => $currency,
            'payment_method_types' => ['card'],
            'metadata' => [
                'woo_cart_hash' => WC()->cart->get_cart_hash()
            ]
        ]);

        // 将client_secret存入会话,供前端获取
        WC()->session->set('stripe_payment_intent_client_secret', $payment_intent->client_secret);
    } catch (\Exception $e) {
        wc_add_notice(__('生成支付会话失败:' . $e->getMessage()), 'error');
    }
}

// 为GraphQL添加返回client_secret的字段(适配WPGraphQL)
add_action('graphql_register_fields', 'add_stripe_client_secret_field');
function add_stripe_client_secret_field() {
    register_graphql_field('RootQuery', 'stripePaymentIntentClientSecret', [
        'type' => 'String',
        'resolve' => function() {
            return WC()->session->get('stripe_payment_intent_client_secret');
        }
    ]);
}

2. 前端代码修改:改用stripe.confirmCardPayment()

调整前端流程,先获取正确的Payment Intent client_secret,再触发支付验证,最后完成订单提交:

第一步:新增获取client_secret的GraphQL查询

query GetStripeClientSecret {
  stripePaymentIntentClientSecret
}

第二步:修改支付提交逻辑

// 获取Payment Intent的client_secret
const { data: secretData } = useQuery(GetStripeClientSecret);
const clientSecret = secretData?.stripePaymentIntentClientSecret;

const handleSubmit = async (event: React.FormEvent) => {
  event.preventDefault();
  
  if (!clientSecret || !stripe || !elements) {
    throw Error('支付所需参数缺失');
  }

  const cardElement = elements.getElement(CardElement);
  if (!cardElement) {
    throw Error('未找到支付卡片组件');
  }

  try {
    // 触发支付验证(自动处理3D Secure)
    const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
      payment_method: {
        card: cardElement,
        billing_details: {
          name: `${shippingInfo.firstName} ${shippingInfo.lastName}`,
          email: shippingInfo.email,
          phone: shippingInfo.phone,
          address: {
            line1: shippingInfo.address,
            city: shippingInfo.city,
            postal_code: shippingInfo.postalCode,
            country: shippingInfo.country
          }
        }
      }
    });

    if (error) {
      throw Error(error.message);
    }

    // 验证通过后提交订单到WooCommerce
    if (['succeeded', 'requires_capture'].includes(paymentIntent.status)) {
      await checkout({
        variables: {
          input: {
            paymentMethod: 'stripe',
            shippingMethod: 'Flat rate',
            billing: {
              firstName: shippingInfo.firstName,
              // 填充其他账单信息
              phone: shippingInfo.phone,
            },
            metaData: [
              {
                key: `_stripe_payment_intent_id`,
                value: paymentIntent.id,
              },
            ],
          },
        },
      });
    }
  } catch (error) {
    console.error(error);
  }
};

3. 后端关联订单与Payment Intent

确保WooCommerce创建订单时,绑定Payment Intent并更新订单状态:

add_action('woocommerce_checkout_update_order_meta', 'associate_payment_intent_with_order', 10, 2);
function associate_payment_intent_with_order($order_id, $data) {
  $payment_intent_id = isset($_POST['stripe_payment_intent_id']) ? $_POST['stripe_payment_intent_id'] : '';
  if ($payment_intent_id) {
    update_post_meta($order_id, '_stripe_payment_intent_id', $payment_intent_id);
    
    // 根据业务逻辑标记订单状态
    $order = wc_get_order($order_id);
    $order->set_status('processing');
    $order->save();
  }
}

关键说明

  • 改用Payment Intent API后,Stripe会自动处理3D Secure等验证流程,stripe.confirmCardPayment()会直接弹出验证界面,无需手动处理跳转。
  • 确保WooCommerce Stripe插件已更新到最新版本,新版本默认优先使用Payment Intent而非Source。
  • 若使用其他API方式而非WPGraphQL,可通过自定义REST接口返回会话中的client_secret。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 03:01:02