Laravel集成Cartalyst Stripe实现3D Secure SCA验证问题咨询
解决方案
1. 前置配置(Stripe后台)
先进入Stripe管理后台的「支付设置」页面,将3D Secure的触发规则调整为所有交易强制触发,确保满足SCA合规要求,不会漏掉需要验证的交易。
2. 修改后端支付逻辑
你原有逻辑使用的老旧Charges API原生不支持3D Secure跳转,需要替换为PaymentIntent API,调整后的控制器代码如下:
// 表单提交对应的控制器方法 public function orderFinal(Request $request) { $stripe = new Stripe(env('STRIPE_API_KEY')); // 1. 创建/获取Stripe客户(如果是老用户可以直接把stripe_customer_id存到用户表,不用每次创建) $customer = $stripe->customers()->create([ 'email' => Auth::user()->email, 'name' => Auth::user()->name ]); // 2. 拆分有效期(你后续要实现的步骤,这里先假设已经拆为exp_month和exp_year) $exp = explode('/', $request->expiration_date); $expMonth = trim($exp[0]); $expYear = trim($exp[1]); // 3. 生成卡Token $token = $stripe->tokens()->create([ 'card' => [ 'number' => $request->card_number, 'exp_month' => $expMonth, 'exp_year' => $expYear, 'cvc' => $request->cvc, ], ]); // 4. 保存卡到客户账户(你原有已实现的逻辑不变) $card = $stripe->cards()->create($customer['id'], $token['id']); // 5. 创建PaymentIntent,强制触发3D Secure $paymentIntent = $stripe->paymentIntents()->create([ 'amount' => Session::get('total_payment'), // 注意单位为对应货币的最小单位,如人民币为分、美元为美分 'currency' => Session::get('appcurrency'), 'customer' => $customer['id'], 'payment_method' => $card['id'], 'confirm' => true, // 直接确认支付,触发验证流程 'return_url' => route('payment.callback'), // 这里填你验证完成后跳转回的站点路由,直接用Laravel的route方法生成即可 'payment_method_options' => [ 'card' => [ 'request_three_d_secure' => 'any' // 强制所有卡走3D Secure验证 ] ], 'statement_descriptor' => 'Descriptor.com' ]); // 6. 判断PaymentIntent状态,处理跳转 if ($paymentIntent['status'] == 'requires_action') { // 需要3D Secure验证,直接跳转到Stripe的验证页面 return redirect()->away($paymentIntent['next_action']['redirect_to_url']['url']); } // 如果不需要验证直接支付成功,走后续订单逻辑 if ($paymentIntent['status'] == 'succeeded') { // 你的订单生成、清空购物车等逻辑 return redirect()->route('order.success')->with('msg', '支付成功'); } // 其他状态返回错误 return back()->withErrors('支付失败,请重试'); }
3. 配置支付回调路由及逻辑
新增回调路由对应return_url,处理3D Secure验证完成后的结果:
// routes/web.php Route::get('/payment/callback', [YourController::class, 'paymentCallback'])->name('payment.callback');
对应的控制器回调方法:
public function paymentCallback(Request $request) { $stripe = new Stripe(env('STRIPE_API_KEY')); // 根据回调返回的payment_intent参数查询支付状态 $paymentIntent = $stripe->paymentIntents()->find($request->payment_intent); if ($paymentIntent['status'] == 'succeeded') { // 支付成功,走后续订单逻辑 return redirect()->route('order.success')->with('msg', '支付成功'); } // 验证失败/支付失败 return redirect()->route('order.fail')->withErrors('支付验证失败,请重试'); }
注意事项
- 你现有的Bootstrap表单不需要做任何修改,不会破坏原有样式,全程走服务端跳转逻辑,无需引入Stripe Element组件
- 卡信息会按你原有逻辑自动保存到对应的Stripe客户账户中,无需额外调整
- 测试时可使用Stripe测试卡
4000002500003155验证3D Secure流程,该卡提交后会自动进入验证页面,按提示操作即可完成测试
内容的提问来源于stack exchange,提问作者Ondraasek
相关产品推荐
相关产品推荐

