前言

前段时间自己撸了一套授权系统,这两天也没啥事就想着接入下支付宝当面付好方便用户充值。

正文

1、先去支付宝开放平台申请APPID那些东西,这东西自己百度一下吧

2、安装支付宝的SDK,在项目根目录通过Composer安装

composer require alipaysdk/easysdk:^2.0

SDKgithub地址:https://github.com/alipay/alipay-easysdk

3、在config目录创建配置文件,自己看着来,我的文件名就是 alipay.php

return [
    'protocol' => 'https',
    'gatewayHost' => 'openapi.alipay.com',
    'signType' => 'RSA2',
    'appId' => '你的AppID',
    'merchantPrivateKey' => '你的应用私钥',
    'alipayPublicKey' => '支付宝公钥',
    'notifyUrl' => '异步通知地址',
    'returnUrl' => '同步跳转地址',
];

这里需要注意的是支付宝的网关地址,如果是沙箱环境的话自己看下沙箱环境里的那个,因为不确定每个账号的是不是一样的,就像我这个的话在gatewayHostopenapi-sandbox.dl.alipaydev.com就行

image-20230922151521234

4、创建一个服务类,可以在app/common/service目录创建一个AlipayService.php文件,然后初始化支付宝的SDK

<?php
declare (strict_types=1);

namespace app\common\service;

use Exception;
use Alipay\EasySDK\Kernel\Config;
use Alipay\EasySDK\Kernel\Factory;
class AlipayService
{
    public function __construct()
    {
        $config = new Config();
        $config->protocol = config('alipay.protocol');
        $config->gatewayHost = config('alipay.gatewayHost');
        $config->signType = config('alipay.signType');
        $config->appId = config('alipay.appId');
        $config->merchantPrivateKey = config('alipay.merchantPrivateKey');
        $config->alipayPublicKey = config('alipay.alipayPublicKey');
        $config->notifyUrl = config('alipay.notifyUrl');
        Factory::setOptions($config);
    }

    /**
     * 创建支付宝订单返回url
     * @param $outTradeNo
     * @param $subject
     * @param $totalAmount
     * @return false|string
     */
    public function preCreate($outTradeNo, $subject, $totalAmount)
    {
        try {
            $result = Factory::payment()->faceToFace()->preCreate($subject, $outTradeNo, $totalAmount);

            if ($result->code == 10000 && $result->msg == 'Success') {
                // 返回二维码链接
                return $result->qrCode;
            } else {
                // 创建二维码链接失败
                return false;
            }
        } catch (Exception $e) {
            // 异常处理
            return false;
        }
    }
    
    /**
     * 验证签名
     * @param $data
     * @return bool
     */
    public function verifyNotify($data)
    {
        try {
            return Factory::payment()->common()->verifyNotify($data);
        } catch (Exception $e) {
            // 异常处理
            return false;
        }
    }
}

5、然后创建充值控制器,我是多应用结构的,所以我的文件路径就是app/system/controller/Pay.php,单应用的话直接在app/controller目录创建,下面是具体的函数方法

 /**
     * 生成订单
     * @param $uid
     * @param $money
     * @return false|string
     */
    public function createRechargeOrder($uid, $money)
    {
        $outTradeNo = 'R' . date('YmdHis') . rand(1000, 9999);
        $data = [
            'uid' => $uid,
            'trade_no' => $outTradeNo,
            'money' => $money,
        ];

        //这里自己写逻辑存数据库

        return $outTradeNo;
    }

    /**
     * 发起支付
     * @method POST
     */
    public function pay()
    {
        $userId = '用户ID';
        $amount = '充值金额';

        // 创建充值订单
        $outTradeNo = $this->createRechargeOrder($userId, $amount);

        $subject = '用户充值';
        $alipayService = new AlipayService();
        $qrCodeUrl = $alipayService->preCreate($outTradeNo, $subject, $amount);

        if ($qrCodeUrl) {
            // 创建二维码链接成功,返回给前端
            return json(['qrCodeUrl' => $qrCodeUrl]);
        } else {
            // 创建二维码链接失败,处理错误
        }
    }

    /**
     * 异步通知
     * @method POST
     */
    public function notify()
    {
        $data = $this->request->post();
        $alipayService = new AlipayService();
        if ($alipayService->verifyNotify($data)) {
            // 验证成功,处理业务逻辑
            $tradeStatus = $data['trade_status'];
            $outTradeNo = $data['out_trade_no'];

            $res = $this->updateRechargeOrder($outTradeNo, $tradeStatus);
            if (!$res) {
                return 'fail';
            }
            return 'success'; // 返回支付宝所需的响应
        } else {
            // 验证失败,可能是伪造的通知
            return 'fail';
        }
    }

    /**
     * 更新订单
     * @param $outTradeNo
     * @param $tradeStatus
     * @return bool
     */
    public function updateRechargeOrder($outTradeNo, $tradeStatus)
    {
        // 根据订单号查找订单信息
        // ...

        if ($tradeStatus == 'TRADE_SUCCESS' || $tradeStatus == 'TRADE_FINISHED') {
            // 支付成功,更新订单状态并为用户增加充值金额
            // ...
            return true;
        } else {
            return false;
        }
    }

这里需要注意的是如果有全局接口token校验的,需要将notify的地址加白名单,要不然支付宝无法完成通知

最后修改:2023 年 09 月 22 日
如果觉得我的文章对你有用,请随意赞赏