30分钟搞定Laravel支付集成:Stripe与PayPal双方案实操指南

30分钟搞定Laravel支付集成:Stripe与PayPal双方案实操指南

【免费下载链接】laravel Laravel 是一个具有表现力和优雅语法的 web 应用程序框架。我们已经为您下一个重大创意奠定了基础,让您无需在琐碎细节上花费过多精力,可以专注于创造性的开发工作。 【免费下载链接】laravel 项目地址: https://gitcode.com/GitHub_Trending/la/laravel

你是否还在为电商项目的支付模块焦头烂额?集成支付网关时面对文档迷宫无从下手?本文将带你用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
]);

安全最佳实践

  1. 数据验证:所有支付请求必须验证订单ID和金额,防止篡改
  2. CSRF保护:确保所有表单包含@csrf指令
  3. 敏感信息加密:API密钥使用环境变量存储,不要硬编码
  4. IP限制:生产环境可限制支付回调IP
  5. 订单幂等性:使用唯一订单号防止重复支付

测试与上线

  1. 使用测试卡号进行Stripe测试:

    • 卡号:4242 4242 4242 4242
    • 有效期:任意未来日期
    • CVV:123
  2. PayPal测试账号:

    • 买家账号:buyer@example.com
    • 密码:test123456
  3. 上线前检查:

    • 切换PayPal模式为live
    • 更新生产环境API密钥
    • 配置SSL证书确保HTTPS访问

通过本文介绍的方案,你已掌握Laravel框架下Stripe与PayPal支付网关的完整集成流程。实际项目中可根据业务需求扩展退款、订阅等高级功能。完整代码示例可参考项目routes/web.php和app/Http/Controllers/PaymentController.php文件。如需进一步优化,可考虑引入队列处理支付回调和异步通知。

【免费下载链接】laravel Laravel 是一个具有表现力和优雅语法的 web 应用程序框架。我们已经为您下一个重大创意奠定了基础,让您无需在琐碎细节上花费过多精力,可以专注于创造性的开发工作。 【免费下载链接】laravel 项目地址: https://gitcode.com/GitHub_Trending/la/laravel

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值