按国家/地区划分的多个Stripe账户

后端开发 2026-07-11

我有一个 WordPress(WooCommerce) 网站,已集成 Stripe 并连接到一个Stripe账户。

我想基于客户的账单国家使用两个Stripe账户。举例来说,如果客户在账单地址中选择美国,支付应通过默认Stripe账户进行处理。如果账单国家不是美国,支付应通过第二个Stripe账户进行处理。

我目前正在尝试实现自定义功能以实现这一行为。

// 1. Create function to find Product ID

function bbloomer_product_id_in_cart( $id ) {
   if ( ! WC()->cart ) return false;
   $product_cart_id = WC()->cart->generate_cart_id( $id );
   $in_cart = WC()->cart->find_product_in_cart( $product_cart_id );
   if ( $in_cart ) return true;
   return false;
}

// -------------------
// 2. Change Stripe keys on the go

add_filter( 'wc_stripe_upe_params', 'bbloomer_conditional_publishable_key_upe', 9999 );

function bbloomer_conditional_publishable_key_upe( $params ) {

   // PRODUCT ID HERE
if ( WC()->customer && WC()->customer->get_billing_country() == 'US' ) return $params; 
   // STRIPE Live Publishable Key HERE
   $params[ 'key' ] = 'pk_live_................';

   return $params;
}

add_filter( 'wc_stripe_params', 'bbloomer_conditional_publishable_key', 9999 );

function bbloomer_conditional_publishable_key( $params ) {

   // PRODUCT ID HERE
   if ( WC()->customer && WC()->customer->get_billing_country() == 'US' ) return $params;

   // STRIPE Live Publishable Key HERE
   $params[ 'key' ] = 'pk_live_................';

   return $params;
}

add_filter( 'wc_stripe_payment_request_params', 'bbloomer_conditional_publishable_key_request', 9999 );

function bbloomer_conditional_publishable_key_request( $params ) {

   // PRODUCT ID HERE
  if ( WC()->customer && WC()->customer->get_billing_country() == 'US' ) return $params;

   // STRIPE Live Publishable Key HERE
   $params[ 'stripe' ][ 'key' ] = 'pk_live_................';

   return $params;
}

add_filter( 'woocommerce_stripe_request_headers', 'bbloomer_conditional_private_key_headers', 9999 );

function bbloomer_conditional_private_key_headers( $params ) {

   // PRODUCT ID HERE
 if ( WC()->customer && WC()->customer->get_billing_country() == 'US' ) return $params;

   // STRIPE Live Secret Key HERE
   $params[ 'Authorization' ] = 'Basic ' . base64_encode( 'sk_live_..........' . ':' );

   return $params;
}

在结账过程中更改账单国家时会出现问题。

如果账单国家已设为US,支付将进入默认Stripe账户。如果结账加载时已选择了其他国家,则会正确使用第二个Stripe账户。

然而,当用户在结账页将国家从US改为其他国家时,Stripe密钥切换成功(如我在控制台中所看到),但支付会失败,错误信息为:

处理支付时出错:无法处理此笔支付,请重试或使用其他方法。

解决方案

Why your code is failing

核心问题在于后端PHP过滤器与前端 Stripe.js 初始化之间的不同步。

当WooCommerce结账页面首次加载时,为了创建一个安全会话,会发生两件事:

  1. Backend: 你的服务器使用默认账户的 Secret Key 来准备 PaymentIntent
  2. Frontend: WooCommerce将默认的 Publishable Key 传递给浏览器。Stripe.js 脚本使用此密钥将安全的信用卡输入字段(Stripe Elements)挂载到屏幕上。

当用户更改账单国家时,WooCommerce会触发一个AJAX update_checkout 请求。你的自定义PHP函数成功拦截并在后端切换密钥。然而,前端的Stripe Element已经绑定了原始的Publishable Key。你不能在已挂载的Stripe Element上热切换Publishable Key。

因为前端正在以账户A 的身份提交支付,但后端现在使用账户B 的Secret Key进行校验,Stripe会检测到身份验证不匹配并拒绝支付。

如何修复

你有两种选项,取决于你想如何架构你的结账流程。

Option 1: Force a frontend reload (The Workaround)

如果你想保留当前的PHP逻辑,必须在国家改变时强制前端从头重新构建Stripe Elements。你可以通过监听WooCommerce的 updated_checkout 事件,并在国家切换时触发一次硬刷新来实现。

Note: 虽然这解决了结账错误,但通过过滤器动态切换密钥通常不建议,因为它可能破坏自动化的webhooks和未来的退款(WooCommerce不会知道向哪个账户发送退款请求)。

Option 2: Use Multiple Gateways

处理多个区域Stripe账户的最稳妥方法是完全避免过滤核心API密钥。相反,使用WooCommerce内置的网关筛选器,根据用户所在的国家切换可用的支付方式。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章