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

印度地区无法使用该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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 22:22:33