30分钟搞定Laravel支付集成:Stripe与PayPal双方案实操指南
你是否还在为电商项目的支付模块焦头烂额?集成支付网关时面对文档迷宫无从下手?本文将带你用Laravel框架快速实现Stripe与PayPal支付功能,无需复杂配置,30分钟即可上线可用的支付系统。读完本文你将掌握:支付控制器设计、双网关无缝切换、订单状态管理、异常处理全流程。
环境准备与依赖安装
在开始前,请确保你的Laravel项目已正确配置。通过Composer安装支付网关依赖包:
composer require stripe/stripe-php paypal/rest-api-sdk-php
如果你尚未安装Composer,可以通过官方脚本快速安装:
curl -sS https://getcomposer.org/installer | php && mv composer.phar /usr/local/bin/composer
配置文件设置
创建支付配置文件config/payments.php,存储双网关的API凭证:
<?php
return [
'stripe' => [
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
],
'paypal' => [
'client_id' => env('PAYPAL_CLIENT_ID'),
'secret' => env('PAYPAL_SECRET'),
'mode' => env('PAYPAL_MODE', 'sandbox'),
]
];
在.env文件中添加支付网关凭证:
STRIPE_KEY=pk_test_你的测试密钥
STRIPE_SECRET=sk_test_你的测试密钥
PAYPAL_CLIENT_ID=你的PayPal客户端ID
PAYPAL_SECRET=你的PayPal密钥
PAYPAL_MODE=sandbox
支付控制器实现
创建支付处理控制器app/Http/Controllers/PaymentController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Stripe\Stripe;
use Stripe\Charge;
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Api\Payment;
class PaymentController extends Controller
{
private $paypal;
public function __construct()
{
$this->paypal = new ApiContext(
new OAuthTokenCredential(
config('payments.paypal.client_id'),
config('payments.paypal.secret')
)
);
$this->paypal->setConfig([
'mode' => config('payments.paypal.mode'),
'log.LogEnabled' => true,
'log.FileName' => storage_path('logs/paypal.log'),
'log.LogLevel' => 'INFO'
]);
}
// Stripe支付处理
public function stripeCharge(Request $request)
{
Stripe::setApiKey(config('payments.stripe.secret'));
try {
$charge = Charge::create([
'amount' => $request->amount * 100, // 金额(分)
'currency' => 'cny',
'source' => $request->stripe_token,
'description' => '订单支付: ' . $request->order_id,
]);
// 更新订单状态逻辑
$this->updateOrderStatus($request->order_id, 'paid');
return response()->json([
'success' => true,
'transaction_id' => $charge->id
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'error' => $e->getMessage()
], 400);
}
}
// PayPal支付创建
public function createPayPalPayment(Request $request)
{
$payment = new Payment();
$payment->setIntent('sale')
->setPayer(['payment_method' => 'paypal'])
->setTransactions([[
'amount' => [
'total' => $request->amount,
'currency' => 'CNY'
],
'description' => '订单支付: ' . $request->order_id
]])
->setRedirectUrls([
'return_url' => url('/payment/paypal/success?order_id=' . $request->order_id),
'cancel_url' => url('/payment/paypal/cancel?order_id=' . $request->order_id)
]);
try {
$payment->create($this->paypal);
return redirect($payment->getApprovalLink());
} catch (\Exception $e) {
return back()->withError('支付创建失败: ' . $e->getMessage());
}
}
// 辅助方法:更新订单状态
private function updateOrderStatus($orderId, $status)
{
// 实现订单状态更新逻辑
\Log::info("Order {$orderId} status updated to {$status}");
}
}
路由配置
在routes/web.php中添加支付相关路由:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PaymentController;
Route::prefix('payment')->group(function () {
Route::post('stripe/charge', [PaymentController::class, 'stripeCharge'])->name('payment.stripe');
Route::post('paypal/create', [PaymentController::class, 'createPayPalPayment'])->name('payment.paypal.create');
Route::get('paypal/success', [PaymentController::class, 'payPalSuccess'])->name('payment.paypal.success');
Route::get('paypal/cancel', [PaymentController::class, 'payPalCancel'])->name('payment.paypal.cancel');
});
支付视图实现
创建支付选择页面resources/views/payment/select.blade.php:
@extends('layouts.app')
@section('content')
<div class="container">
<h2>选择支付方式</h2>
<div class="row mt-4">
<!-- Stripe支付表单 -->
<div class="col-md-6">
<div class="card">
<div class="card-header">信用卡支付 (Stripe)</div>
<div class="card-body">
<form action="{{ route('payment.stripe') }}" method="POST">
@csrf
<input type="hidden" name="order_id" value="{{ $order->id }}">
<input type="hidden" name="amount" value="{{ $order->amount }}">
<div class="form-group">
<label>卡号</label>
<input type="text" class="form-control" placeholder="4242 4242 4242 4242" disabled>
</div>
<div class="form-row">
<div class="col-md-6">
<label>有效期</label>
<input type="text" class="form-control" placeholder="12/25" disabled>
</div>
<div class="col-md-6">
<label>安全码</label>
<input type="text" class="form-control" placeholder="123" disabled>
</div>
</div>
<button type="submit" class="btn btn-primary mt-3">确认支付</button>
</form>
</div>
</div>
</div>
<!-- PayPal支付按钮 -->
<div class="col-md-6">
<div class="card">
<div class="card-header">PayPal支付</div>
<div class="card-body d-flex align-items-center justify-content-center">
<form action="{{ route('payment.paypal.create') }}" method="POST">
@csrf
<input type="hidden" name="order_id" value="{{ $order->id }}">
<input type="hidden" name="amount" value="{{ $order->amount }}">
<button type="submit" class="btn btn-warning">
<i class="fab fa-paypal"></i> 使用PayPal支付
</button>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
异常处理与日志
配置支付日志存储路径config/logging.php,添加支付专用日志通道:
'channels' => [
// ...其他通道
'payment' => [
'driver' => 'single',
'path' => storage_path('logs/payment.log'),
'level' => 'info',
],
],
在支付控制器中使用专用日志通道:
\Log::channel('payment')->info("Order {$orderId} payment processed", [
'gateway' => 'stripe',
'amount' => $amount,
'transaction_id' => $transactionId
]);
安全最佳实践
- 数据验证:所有支付请求必须验证订单ID和金额,防止篡改
- CSRF保护:确保所有表单包含
@csrf指令 - 敏感信息加密:API密钥使用环境变量存储,不要硬编码
- IP限制:生产环境可限制支付回调IP
- 订单幂等性:使用唯一订单号防止重复支付
测试与上线
-
使用测试卡号进行Stripe测试:
- 卡号:4242 4242 4242 4242
- 有效期:任意未来日期
- CVV:123
-
PayPal测试账号:
- 买家账号:buyer@example.com
- 密码:test123456
-
上线前检查:
- 切换PayPal模式为
live - 更新生产环境API密钥
- 配置SSL证书确保HTTPS访问
- 切换PayPal模式为
通过本文介绍的方案,你已掌握Laravel框架下Stripe与PayPal支付网关的完整集成流程。实际项目中可根据业务需求扩展退款、订阅等高级功能。完整代码示例可参考项目routes/web.php和app/Http/Controllers/PaymentController.php文件。如需进一步优化,可考虑引入队列处理支付回调和异步通知。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



