Ai
1 Star 0 Fork 0

小马哥/php-pay

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
Payment.php 12.37 KB
一键复制 编辑 原始数据 按行查看 历史
小马哥 提交于 2024-08-03 04:12 +08:00 . update
<?php
declare (strict_types=1);
namespace magein\pay;
use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\QrCode;
use GuzzleHttp\Exception\GuzzleException;
use magein\pay\data\PayOrderData;
use magein\pay\platform\AliPay;
use magein\pay\platform\WxPay;
use magein\utils\Result;
use Overtrue\Socialite\Exceptions\AuthorizeFailedException;
class Payment
{
/**
* @param array $data
* @return array
* @throws PayException
*/
public function checkRequestParams(array $data): array
{
if (empty($data)) {
PayException::code(400201);
}
extract($data);
if (empty($sign) || !PayFactory::singer()->verify($data)) {
PayException::code(400203);
}
if (empty($channel_id)) {
PayException::code(400205);
}
if (empty($platform_id)) {
PayException::code(400207);
}
if (empty($trade_type)) {
PayException::code(400209);
}
if (empty($total_amount) || !is_numeric($total_amount) || $total_amount <= 0) {
PayException::code(400211);
}
if (empty($order_no)) {
PayException::code(400213);
}
return $data;
}
/**
* @param $data
* @return Result
*/
public function unify($data): Result
{
try {
$this->checkRequestParams($data);
// 选择使用的收款账号
$pay_account = PayAccount::choose($data);
$config = $pay_account->getConfig();
// 获取支付平台
$platform = PayFactory::platform($data);
// 实例化配置文件
$platform->init($config);
// 实例化订单数据
$pay_no = PayFactory::order()->getPayNo();
$pay_order_data = new PayOrderData($data);
$pay_order_data->setPayNo($pay_no);
$pay_order_data->setAppid($config['appid']);
$pay_order_data->setMerchantId(($config['merchant_id'] ?? '') ? $config['merchant_id'] : $config['appid']);
$pay_order_data->setTradeType($data['trade_type'] ?? '');
$result = $platform->unify($pay_order_data);
if ($result->getCode()) {
return $result;
}
// 支付平台统一下单
return Result::success([
'platform_id' => $data['platform_id'] ?? '',
'account' => $pay_account->getAccount(),
'subject' => $pay_order_data->getSubject(),
'total_amount' => $pay_order_data->getTotalAmount(),
'trade_type' => $pay_order_data->getTradeType(),
'order_no' => $pay_order_data->getOrderNo(),
'pay_no' => $pay_no,
'pay_data' => $result->getData(),
]);
} catch (PayException $exception) {
$result = $exception->toResult();
return Result::error($result->getMsg(), $result->getCode(), $data);
}
}
/**
* 验证二维码是否有效
* @param $pay_no
* @return bool
*/
public function qrcodeAvailable($pay_no): bool
{
try {
$result = PayFactory::qrcode()->available($pay_no);
} catch (PayException $exception) {
$result = false;
}
return $result;
}
/**
* @param array $data
* @return Result
*/
public function qrcode(array $data): Result
{
$temp_save_path = '';
try {
if (empty($data)) {
PayException::code(400201);
}
extract($data);
if (empty($sign) || !PayFactory::singer()->verify($data)) {
PayException::code(400203);
}
if (empty($channel_id)) {
PayException::code(400205);
}
if (empty($total_amount) || !is_numeric($total_amount) || $total_amount <= 0) {
PayException::code(400211);
}
if (empty($order_no)) {
PayException::code(400213);
}
$pay_no = PayFactory::qrcode()->create($data);
if ($pay_no) {
$config = PayConfig::qrcode();
$url = $config['url'] ?? '';
$size = $config['size'] ?? 300;
$save_path = $config['save_path'] ?? '';
if ($url && $save_path) {
$filename = $pay_no . '.png';
$dir = date('Y/m/d/');
$filepath = $save_path . $dir;
if (!is_dir($filepath)) {
mkdir($filepath, 0777, true);
}
$temp_save_path = $filepath . $filename;
$url .= '?pay_no=' . $pay_no;
$qrcode = new QrCode($url);
$qrcode->setSize($size);
$qrcode->setWriterByName('png');
$qrcode->setEncoding('UTF-8');
$qrcode->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH());
$qrcode->setValidateResult(false);
$qrcode->writeFile($temp_save_path);
if (is_file($temp_save_path)) {
$temp_save_path = PayFactory::qrcode()->getTempSavePath($temp_save_path);
} else {
$temp_save_path = '';
}
}
}
} catch (PayException $exception) {
return $exception->toResult();
}
return Result::success(compact('temp_save_path', 'pay_no'));
}
/**
* user-agent
*
* 微信 : Mozilla/5.0 (Linux; Android 14; 2201123C Build/UKQ1.230917.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.122 Mobile Safari/537.36 XWEB/1260059 MMWEBSDK/20240501 MMWEBID/4520 MicroMessenger/8.0.50.2701(0x28003252) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64
*
* 支付宝: Mozilla/5.0 (Linux; Android 14; 2201123C Build/UKQ1.230917.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/105.0.5195.148 MYWeb/0.11.0.240702160459 UWS/3.22.2.9999 UCBS/3.22.2.9999_220000000000 Mobile Safari/537.36 NebulaSDK/1.8.100112 Nebula AlipayDefined(nt:4G,ws:393|0|2.75) AliApp(AP/10.6.18.8000) AlipayClient/10.6.18.8000 Language/zh-Hans useStatusBar/true isConcaveScreen/true Region/CNAriver/1.0.0 DTN/2.0
*
* @param $pay_no
* @return Result
*/
public function scan($pay_no): Result
{
try {
$qrcode = PayFactory::qrcode();
$record = $qrcode->getByPayNo($pay_no);
if (empty($record)) {
PayException::code(400503);
}
$params = $record['params'];
if (!$qrcode->available($record)) {
PayException::code(400505, $params);
}
// 扫码后标记为失效
$qrcode->unavailable($pay_no);
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
$wx = strpos($user_agent, 'MicroMessenger');
if ($wx !== false) {
$params['platform_id'] = PayConfig::qrcode('wx');
$params['trade_type'] = WxPay::TRADE_TYPE_JSAPI;
// 选择账号
$account = PayAccount::choose($params);
$open_id = ($params['open_id'] ?? '') ?: PayFactory::wxOauth()->getWxOpenId($params);
if (empty($open_id)) {
$platform = PayFactory::platform($params);
return Result::success([
'oauth' => $platform->oauth($account->getAccount(), $pay_no)
]);
}
$params['open_id'] = $open_id;
} else {
$params['platform_id'] = PayConfig::qrcode('ali');
$params['trade_type'] = AliPay::TRADE_TYPE_WAP;
}
unset($params['sign']);
$params['sign'] = PayFactory::singer()->create($params);
$result = $this->unify($params);
} catch (PayException $exception) {
$result = $exception->toResult();
}
return $result;
}
/**
* @param $pay_no
* @param $data
* @return string
*/
public function notify($pay_no, $data): string
{
// 获取支付平台
try {
$pay_order = PayFactory::order()->getByPayNo($pay_no);
if (empty($pay_order)) {
return 'success';
}
$platform = PayFactory::platform($pay_order);
$platform->doInit($pay_order);
$notify = $platform->handleNotify($data);
// 更新订单状态
$result = PayFactory::order()->modify($notify);
// 通知支付结果
if ($result) {
PayFactory::notice()->run($notify, $pay_order);
}
// 发送响应
return $notify->getResponse() ?: '';
} catch (PayException $exception) {
}
return 'success';
}
/**
* @param $pay_no
* @return string
*/
public function success($pay_no): string
{
$pay_order = null;
$url = '';
try {
$i = 0;
while (true) {
if ($i >= 10) {
break;
}
$pay_order = PayFactory::order()->getByPayNo($pay_no);
if ($pay_order && $pay_order['result'] != 0) {
break;
}
$i++;
sleep(1);
}
} catch (PayException $exception) {
}
if ($pay_order) {
$url = (new PayNotice())->getReturnUrl($pay_order);
}
return $url;
}
public function oauth($code, $account, $pay_no)
{
try {
$record = PayFactory::qrcode()->getByPayNo($pay_no);
if (empty($record) || empty($record['params'] ?? '')) {
PayException::code(400503);
}
} catch (PayException $exception) {
return $exception->toResult();
}
$params = $record['params'];
$params['platform_id'] = PayConfig::qrcode('wx');
$params['trade_type'] = WxPay::TRADE_TYPE_JSAPI;
$params['account'] = $account;
try {
$pay_account = PayAccount::choose($params);
$config = $pay_account->getConfig();
$platform = PayFactory::platform($params);
$user = $platform->officialAccount($config)->oauth->userFromCode($code);
$params['open_id'] = $user->getId();
PayFactory::wxOauth()->setWxOpenId($params);
unset($params['sign']);
$params['sign'] = PayFactory::singer()->create($params);
return $this->unify($params);
} catch (PayException $exception) {
return $exception->toResult();
} catch (AuthorizeFailedException $exception) {
return Result::error('获取微信授权错误', 400309, $params);
} catch (GuzzleException $exception) {
return Result::error('微信授权请求错误', 400309, $params);
}
}
/**
* @param $pay_no
* @param int $type
* @return Result
*/
public function query($pay_no, int $type): Result
{
try {
if (empty($pay_no)) {
PayException::code(400503);
}
$data = PayFactory::order()->getByPayNo($pay_no);
if (empty($data)) {
PayException::code(400503);
}
$platform_id = $data['platform_id'] ?? '';
// 获取支付平台
$platform_pay_result = function () use ($pay_no, $data) {
$platform = PayFactory::platform($data);
$platform->doInit($data);
return $platform->queryByPayNo($pay_no);
};
$return['platform_id'] = $platform_id;
if ($type == 1) {
$return['pay_res'] = $data;
} elseif ($type == 2) {
$return['platform_res'] = $platform_pay_result();
} else {
$return['pay_res'] = $data;
$return['platform_res'] = $platform_pay_result();
}
$result = Result::success($return);
} catch (PayException $payException) {
$result = $payException->toResult();
}
return $result;
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/magein/php-pay.git
git@gitee.com:magein/php-pay.git
magein
php-pay
php-pay
master

搜索帮助