
本文详解如何在 laravel cashier 中集成 stripe 多种支付方式(如信用卡、sepa、paypal 等),通过 setupintent + stripe elements 实现安全、合规的支付方法添加与管理。
本文详解如何在 laravel cashier 中集成 stripe 多种支付方式(如信用卡、sepa、paypal 等),通过 setupintent + stripe elements 实现安全、合规的支付方法添加与管理。
Laravel Cashier 默认聚焦于订阅场景,但其底层完全兼容 Stripe 的多支付方式能力(如 Card、SEPA Direct Debit、SOFA、Link、PayPal 等)。关键在于:Cashier 不直接封装前端支付 UI,而是通过 Stripe SetupIntent 协调用户授权并安全绑定多种 PaymentMethod 到 Customer。整个流程分为三步:后端创建 SetupIntent → 前端用 Stripe.js 收集并确认支付信息 → 后端绑定 PaymentMethod。
✅ 第一步:后端生成 SetupIntent
在控制器中(例如 PaymentMethodController@create),为当前用户创建 SetupIntent,并返回客户端所需参数:
// app/Http/Controllers/PaymentMethodController.php
use Illuminate\Http\Request;
public function create(Request $request)
{
$user = $request->user();
$setupIntent = $user->createSetupIntent([
'description' => 'Add new payment method',
'metadata' => ['source' => 'web_checkout'],
]);
return response()->json([
'client_secret' => $setupIntent->client_secret,
'publishable_key' => config('cashier.stripe.key'),
]);
}⚠️ 注意:确保 .env 中已正确配置 STRIPE_KEY 和 STRIPE_SECRET,且 Cashier 已完成初始化(php artisan cashier:install)。
✅ 第二步:前端集成 Stripe Elements(支持多方式)
使用 Stripe.js v3(推荐 @stripe/stripe-js)加载 Elements,并动态渲染支持多种支付方式的 PaymentElement(替代旧版 CardElement):
<!-- resources/views/payment/methods.blade.php --> <div id="payment-element"></div> <button id="submit-button">Save Payment Method</button> <div id="error-message"></div>
// resources/js/app.js
import { loadStripe } from '@stripe/stripe-js';
const stripe = await loadStripe('{{ config("cashier.stripe.key") }}');
const elements = stripe.elements({
clientSecret: '{{ $client_secret }}', // 来自上一步 API 响应
appearance: {
theme: 'stripe',
variables: { colorPrimary: '#0d6efd' }
}
});
const paymentElement = elements.create('payment', {
// 自动根据用户地区和 Stripe 账户启用可用方式(无需硬编码)
defaultValues: { billingDetails: { name: '{{ Auth::user()->name }}' } },
wallets: { applePay: 'auto', googlePay: 'auto' },
});
paymentElement.mount('#payment-element');
document.getElementById('submit-button').addEventListener('click', async (e) => {
e.preventDefault();
const { error, setupIntent } = await stripe.confirmSetup({
elements,
confirmParams: {
return_url: window.location.origin + '/payment-methods/success',
// 可选:设置付款用途(对 SEPA/PayPal 等至关重要)
payment_method_data: {
billing_details: {
name: document.getElementById('name').value || '{{ Auth::user()->name }}',
email: '{{ Auth::user()->email }}',
}
}
},
});
if (error) {
document.getElementById('error-message').textContent = error.message;
} else {
// 成功获取 PaymentMethod ID
const response = await fetch('/api/payment-method', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify({ payment_method: setupIntent.payment_method })
});
const result = await response.json();
if (result.success) {
alert('Payment method added successfully!');
window.location.href = '/payment-methods';
}
}
});✅ 第三步:后端接收并绑定 PaymentMethod
创建 API 接口接收前端传回的 payment_method ID,并通过 Cashier 的 addPaymentMethod() 安全绑定:
// routes/api.php
Route::post('/payment-method', [PaymentMethodController::class, 'store'])
->middleware('auth:sanctum');
// app/Http/Controllers/PaymentMethodController.php
public function store(Request $request)
{
$user = $request->user();
$paymentMethodId = $request->input('payment_method');
try {
$user->addPaymentMethod($paymentMethodId);
return response()->json(['success' => true]);
} catch (\Exception $e) {
\Log::error('Failed to add payment method', [
'user_id' => $user->id,
'payment_method' => $paymentMethodId,
'error' => $e->getMessage()
]);
return response()->json(['success' => false, 'error' => 'Invalid or expired payment method.'], 422);
}
}? 关键注意事项
- SetupIntent ≠ PaymentIntent:createSetupIntent() 仅用于“保存支付方式”,不扣款;后续订阅或单次支付仍需 PaymentIntent 或 Charge。
- 地区与功能匹配:Stripe 自动根据账户国家、用户 IP 和配置启用对应支付方式(如 EU 用户默认显示 SEPA),无需手动判断。
- PCI 合规性:所有敏感卡信息由 Stripe Elements 直接加密传输,你的服务器永不接触原始卡号/CVC,满足 SAQ-A 合规要求。
- 测试环境验证:使用 Stripe 测试卡(如 4242 4242 4242 4242)及测试银行账号(如 DE43500105178212345678)验证 SEPA 流程。
完成以上步骤后,用户即可在你的餐厅应用中自由添加信用卡、SEPA、PayPal、Apple Pay 等 Stripe 支持的全部支付方式——所有方法均统一存储于 Stripe Customer 对象下,并可通过 Cashier 的 $user->paymentMethods() 方法安全调用,为灵活的订单结算与订阅管理打下坚实基础。


















