laravel 支付宝流程

本文介绍如何使用yansongda/pay库简化支付宝和微信支付的集成,通过配置参数、注入容器、测试支付流程和设置回调,实现快速支付功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 引入支付库

yansongda/pay 这个库封装了支付宝和微信支付的接口,通过这个库我们就不需要去关注不同支付平台的接口差异,使用相同的方法、参数来完成支付功能,节省开发时间。

首先通过 composer 引入这个包:

$ composer require yansongda/pay

2. 配置参数

我们创建一个新的配置文件来保存支付所需的参数:

$ touch config/pay.php

config/pay.php

<?php

return [
    'alipay' => [
        'app_id'         => '',
        'ali_public_key' => '',
        'private_key'    => '',
        'log'            => [
            'file' => storage_path('logs/alipay.log'),
        ],
    ],

    'wechat' => [
        'app_id'      => '',
        'mch_id'      => '',
        'key'         => '',
        'cert_client' => '',
        'cert_key'    => '',
        'log'         => [
            'file' => storage_path('logs/wechat_pay.log'),
        ],
    ],
];

现在这些参数先留空,后面的章节我们再填入具体的值。

3. 容器

容器是现代 PHP 开发的一个重要概念,Laravel 就是在容器的基础上构建的。我们将支付操作类实例注入到容器中,在以后的代码里就可以直接通过 app('alipay') 来取得对应的实例,而不需要每次都重新创建。

我们通常在 AppServiceProviderregister() 方法中往容器中注入实例:

app/Providers/AppServiceProvider.php

use Monolog\Logger;
use Yansongda\Pay\Pay;
.
.
.
    public function register()
    {
        // 往服务容器中注入一个名为 alipay 的单例对象
        $this->app->singleton('alipay', function () {
            $config = config('pay.alipay');
            // 判断当前项目运行环境是否为线上环境
            if (app()->environment() !== 'production') {
                $config['mode']         = 'dev';
                $config['log']['level'] = Logger::DEBUG;
            } else {
                $config['log']['level'] = Logger::WARNING;
            }
            // 调用 Yansongda\Pay 来创建一个支付宝支付对象
            return Pay::alipay($config);
        });

        $this->app->singleton('wechat_pay', function () {
            $config = config('pay.wechat');
            if (app()->environment() !== 'production') {
                $config['log']['level'] = Logger::DEBUG;
            } else {
                $config['log']['level'] = Logger::WARNING;
            }
            // 调用 Yansongda\Pay 来创建一个微信支付对象
            return Pay::wechat($config);
        });
    }

代码解析:

  • $this->app->singleton() 往服务容器中注入一个单例对象,第一次从容器中取对象时会调用回调函数来生成对应的对象并保存到容器中,之后再去取的时候直接将容器中的对象返回。
  • app()->environment() 获取当前运行的环境,线上环境会返回 production。对于支付宝,如果项目运行环境不是线上环境,则启用开发模式,并且将日志级别设置为 DEBUG。由于微信支付没有开发模式,所以仅仅将日志级别设置为 DEBUG

4. 测试

接下来我们来测试一下刚刚注入到容器中的实例,进入 tinker:

$ php artisan tinker

然后分别输入 app('alipay')app('wechat_pay')

>>> app('alipay')
>>> app('wechat_pay')

1541647567567

可以看到返回了 Yansongda\Pay\Gateways\AlipayYansongda\Pay\Gateways\Wechat 类型的对象,说明注入成功。

5 支付宝 支付配置

###配置参数

接下来将这些参数放到配置文件中:

config/pay.php

'app_id' => '你在支付宝沙箱看到的appid',
'ali_public_key' => '支付宝沙箱显示的公钥',
'private_key' => '刚刚生成的私钥',

支付测试

接下来我们要试一下能否正常跳转到支付宝的支付界面,在路由文件中新增一个临时的路由:

routes/web.php

Route::get('alipay', function() {
    return app('alipay')->web([
        'out_trade_no' => time(),
        'total_amount' => '1',
        'subject' => 'test subject - 测试',
    ]);
});

6. 支付回调

支付宝的支付回调分为 前端回调服务器回调

  • 前端回调 是指当用户支付成功之后支付宝会让用户浏览器跳转回项目页面并带上支付成功的参数,也就是说前端回调依赖于用户浏览器,如果用户在跳转之前关闭浏览器,将无法收到前端回调。
  • 服务器回调 是指支付成功之后支付宝的服务器会用订单相关数据作为参数请求项目的接口,不依赖用户浏览器。

因此我们判断支付是否成功要以服务器端回调为准。

我们需要在 PaymentController 中新增两个方法,分别用于处理前端和服务器端回调。

app/Http/Controllers/PaymentController.php

.
.
.
    // 前端回调页面
    public function alipayReturn()
    {
        // 校验提交的参数是否合法
        $data = app('alipay')->verify();
        dd($data);
    }

    // 服务器端回调
    public function alipayNotify()
    {
        $data = app('alipay')->verify();
        \Log::debug('Alipay notify', $data->all());
    }

代码解析:

  • app('alipay')->verify() 用于校验提交的参数是否合法,支付宝的前端跳转会带有数据签名,通过校验数据签名可以判断参数是否被恶意用户篡改。同时该方法还会返回解析后的参数。
  • dd($data); 输出解析后的数据,我们要先看看会返回什么再决定如何处理。
  • \Log::debug('Alipay notify', $data->all()); 由于服务器端的请求我们无法看到返回值,使用 dd 就不行了,所以需要通过日志的方式来保存。

接下来将这两个方法注册到路由:

routes/web.php

.
.
.
Route::group(['middleware' => 'auth'], function () {
    .
    .
    .
    Route::group(['middleware' => 'email_verified'], function () {
        .
        .
        .
        Route::get('payment/alipay/return', 'PaymentController@alipayReturn')->name('payment.alipay.return');
    });
});
Route::post('payment/alipay/notify', 'PaymentController@alipayNotify')->name('payment.alipay.notify');

服务器端回调的路由不能放到带有 auth 中间件的路由组中,因为支付宝的服务器请求不会带有认证信息。

接下来我们把这两个回调地址配置到支付宝的支付实例里:

app/Providers/AppServiceProvider.php

.
.
.
        $this->app->singleton('alipay', function () {
            $config               = config('pay.alipay');
            $config['notify_url'] = route('payment.alipay.notify');
            $config['return_url'] = route('payment.alipay.return');
            .
            .
            .
        });
.
.
.

notify_url 代表服务器端回调地址,return_url 代表前端回调地址。

注意:回调地址必须是完整的带有域名的 URL,不可以是相对路径。使用 route() 函数生成的 URL 默认就是带有域名的完整地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值