印度地区无法使用该Stripe API收款的技术问询及代码适配
解决印度地区Stripe收款API不支持问题
你遇到的错误是因为Stripe在印度地区已停止支持旧的Charge API和直接创建卡片Token的方式,必须使用Payment Intent API配合Stripe Elements处理收款,同时要满足印度当地合规要求。
核心问题点
- 旧的
Stripe\Charge::create()API在印度已被废弃 - 直接收集银行卡号的方式不符合印度PCI合规要求,必须使用Stripe托管的Elements组件
- 印度地区收款必须使用**印度卢比(INR)**作为交易货币,不能用USD
解决方案步骤及代码修改
1. 更新后端Controller(改用Payment Intent API)
替换原stripePost方法,改为创建Payment Intent并处理支付确认:
use Stripe\PaymentIntent; use Stripe\Stripe; use Illuminate\Http\Request; use Illuminate\Support\Facades\Session; public function stripe($totalprice) { Stripe::setApiKey(env('STRIPE_SECRET')); // 转换金额为印度卢比派萨(1INR=100派萨) $amount = $totalprice * 100; // 创建Payment Intent $paymentIntent = PaymentIntent::create([ 'amount' => $amount, 'currency' => 'inr', // 印度地区强制使用INR 'metadata' => ['description' => 'Thanks for payment'] ]); return view('stripe', [ 'clientSecret' => $paymentIntent->client_secret, 'stripeKey' => env('STRIPE_KEY') ]); } public function stripePost(Request $request) { Stripe::setApiKey(env('STRIPE_SECRET')); try { // 确认Payment Intent状态 $paymentIntent = PaymentIntent::retrieve($request->payment_intent_id); $paymentIntent->confirm([ 'payment_method' => $request->payment_method_id ]); Session::flash('success', 'Payment successful!'); return back(); } catch (\Exception $e) { Session::flash('error', $e->getMessage()); return back(); } }
2. 更新前端视图(使用Stripe Elements)
替换原有表单,用Stripe Elements安全收集银行卡信息:
<h1>Pay Using Your Card</h1> <div class="row"> <div class="col-md-6 col-md-offset-3"> <div class="panel panel-default credit-card-box"> <div class="panel-heading display-table"> <h3 class="panel-title">Payment Details</h3> </div> <div class="panel-body"> @if(Session::has('success')) <div class="alert alert-success text-center"> <a href="#" class="close" data-dismiss="alert" aria-label="close">×</a> <p>{{ Session::get('success') }}</p> </div> @endif @if(Session::has('error')) <div class="alert alert-danger text-center"> <a href="#" class="close" data-dismiss="alert" aria-label="close">×</a> <p>{{ Session::get('error') }}</p> </div> @endif <form id="payment-form"> @csrf <div id="card-element" class="form-control mb-3"> <!-- Stripe Elements会自动插入卡片输入组件 --> </div> <div id="card-errors" role="alert" class="text-danger mb-3"></div> <button class="btn btn-primary btn-lg btn-block" id="submit">Pay Now</button> </form> </div> </div> </div> </div> <script src="https://js.stripe.com/v3/"></script> <script> const stripe = Stripe('{{ $stripeKey }}'); const elements = stripe.elements(); // 初始化卡片元素 const cardElement = elements.create('card', { style: { base: { fontSize: '16px', color: '#424770', '::placeholder': { color: '#aab7c4' } } } }); cardElement.mount('#card-element'); // 监听卡片输入错误 cardElement.on('change', function(event) { const displayError = document.getElementById('card-errors'); if (event.error) { displayError.textContent = event.error.message; } else { displayError.textContent = ''; } }); // 处理支付提交 const form = document.getElementById('payment-form'); form.addEventListener('submit', async function(event) { event.preventDefault(); const { paymentIntent, error } = await stripe.confirmCardPayment( '{{ $clientSecret }}', { payment_method: { card: cardElement, billing_details: { name: '请输入持卡人姓名' // 可替换为用户输入字段 } } } ); if (error) { document.getElementById('card-errors').textContent = error.message; } else { // 支付成功后提交到后端记录 const formData = new FormData(form); formData.append('payment_intent_id', paymentIntent.id); formData.append('payment_method_id', paymentIntent.payment_method); fetch('{{ route('stripe.post') }}', { method: 'POST', body: formData }).then(() => window.location.reload()); } }); </script>
3. 路由保持不变(确保金额传递正确)
原路由可直接保留,注意totalprice参数传递的是印度卢比金额:
Route::get('/stripe/{totalprice}', [HomeController::class, 'stripe']); Route::post('stripe', [HomeController::class,'stripePost'])->name('stripe.post');
额外注意事项
- 确保你的Stripe账户是印度地区注册的,且完成了当地KYC合规验证
- 所有交易必须使用印度卢比(INR),禁止使用其他货币
- 禁止自行收集银行卡号、CVC等敏感信息,必须依赖Stripe Elements规避PCI合规风险
内容的提问来源于stack exchange,提问作者Ghanshyam Kumar
相关产品推荐
相关产品推荐

