Laravel集成Stripe支付时创建Charge报错问题求助
Laravel集成Stripe支付时Charge创建失败的问题排查与解决
我正在Laravel应用里集成Stripe的「Pay with Card」功能,跟着官方快速开始文档操作,但从Stripe重定向回来创建Charge的时候,接连遇到了报错,折腾了好一阵都没解决,来求助各位大佬。
第一次尝试:用application_fee直接报错
最开始我写了这段代码创建Charge:
try { $charge = Charge::create([ 'amount' => $price * 100, 'currency' => 'gbp', 'source' => $request->stripeToken, 'application_fee' => 123, // 把这行删掉就能正常运行,说明问题出在这 ], [ 'stripe_account' => $stripe_id, ]); } catch (Exception $e) { return back()->withError('Something went wrong while processing your payment.'); }
结果直接报错,截图如下:
改用destination参数还是报错
后来我查了点资料,改成用destination来拆分资金,代码变成这样:
try { $charge = Charge::create([ 'amount' => $price * 100, 'currency' => 'gbp', 'source' => $request->stripeToken, "destination" => array( "amount" => 877, "account" => "ca_CxKfJvDzUYe3NUpOYZcRofjlZzE8OYCq", ), ], [ 'stripe_account' => $stripe_id, ]); } catch (Exception $e) { return back()->withError('Something went wrong while processing your payment.'); }
结果还是报错,新的报错截图:
问题分析与解决办法
结合Stripe的官方规则,这两个报错的原因其实都是参数使用场景不对:
1. 为什么application_fee不能这么用?
当你在创建Charge时传入stripe_account参数,本质是代平台上的连接账户创建这笔Charge,此时这笔Charge的归属是连接账户,而不是平台。application_fee参数只适用于平台自己作为收款方,然后拆分资金给连接账户的场景,不能在代连接账户创建Charge时使用。
2. 为什么destination也报错?
同样的逻辑,当你代连接账户创建Charge时,这笔资金本来就会进入连接账户,你不能再指定一个destination账户——相当于你给A账户收钱,却要把钱打到B账户,这不符合Stripe的逻辑。
正确的实现方式分两种情况:
情况一:平台先收全款,再分一部分给连接账户
如果你的业务是平台作为收款主体,之后再把部分资金结算给连接账户,那你应该用平台的API密钥创建Charge,不要传stripe_account参数,直接用destination指定连接账户:
try { $charge = Charge::create([ 'amount' => $price * 100, 'currency' => 'gbp', 'source' => $request->stripeToken, 'destination' => [ 'account' => $stripe_id, // 你的连接账户ID 'amount' => 877 // 要分给连接账户的金额(单位:便士) ] ]); } catch (\Stripe\Exception\ApiErrorException $e) { // 改成捕获Stripe专属异常,能拿到具体错误信息 return back()->withError($e->getMessage()); }
情况二:代连接账户收款,平台直接扣取服务费
如果业务是连接账户作为收款方,平台要直接扣取服务费,那应该用transfer_data参数(Stripe新版推荐的方式),并且确保你的Connect账户配置了对应的权限:
try { $charge = Charge::create([ 'amount' => $price * 100, 'currency' => 'gbp', 'source' => $request->stripeToken, 'transfer_data' => [ 'amount' => 877, // 最终到连接账户的金额(总金额-平台服务费) 'destination' => $stripe_id ] ], [ 'stripe_account' => $stripe_id, ]); } catch (\Stripe\Exception\ApiErrorException $e) { return back()->withError($e->getMessage()); }
额外小提示
- 别再捕获泛泛的
Exception了,改用Stripe的ApiErrorException,能拿到具体的错误原因,比如权限不足、参数格式错误之类的,比你现在的通用提示有用多了。 - 开发的时候打开Stripe的调试模式,看一下API返回的具体响应,比只看截图更容易定位问题。
内容的提问来源于stack exchange,提问作者abu abu
相关产品推荐
相关产品推荐

