前言
前段时间自己撸了一套授权系统,这两天也没啥事就想着接入下支付宝当面付好方便用户充值。
正文
1、先去支付宝开放平台申请APPID
那些东西,这东西自己百度一下吧
2、安装支付宝的SDK
,在项目根目录通过Composer
安装
composer require alipaysdk/easysdk:^2.0
SDK
的github
地址: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' => '同步跳转地址',
];
这里需要注意的是支付宝的网关地址,如果是沙箱环境的话自己看下沙箱环境里的那个,因为不确定每个账号的是不是一样的,就像我这个的话在gatewayHost
填openapi-sandbox.dl.alipaydev.com
就行
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
的地址加白名单,要不然支付宝无法完成通知