收款通知逻辑更新,完全改为本地接口,避免网络提交带来的延迟

This commit is contained in:
技术老胡 2024-12-12 16:34:39 +08:00
parent 7f77c5a1dd
commit 6a8ec71b8d
4 changed files with 70 additions and 136 deletions

View File

@ -6,6 +6,7 @@ use think\Request;
use think\facade\View; use think\facade\View;
use app\model\User; use app\model\User;
use app\model\Order; use app\model\Order;
use app\model\PayAccount;
use app\model\PayChannel; use app\model\PayChannel;
class PayController class PayController
@ -157,31 +158,20 @@ class PayController
} }
} }
// 处理收款通知 // 处理收款通知
public function payHeart(Request $request) private function payHeart(array $records, array $config)
{ {
$pid = $request->get('pid'); $pid = $config['pid'];
$aid = $request->get('aid'); $aid = $config['aid'];
$sign = $request->get('sign');
// 检测请求参数
if (!($pid && $aid && $sign)) {
return json(['code' => 0, 'msg' => '参数错误']);
}
// 检测收款通知 // 检测收款通知
$payList = $request->post(); if (!$records) {
if (!$payList) {
return json(['code' => 0, 'msg' => '空收款通知']); return json(['code' => 0, 'msg' => '空收款通知']);
} }
// 签名验证
$is_user = User::checkUser($pid, $sign);
if (!$is_user) {
return json(['code' => 0, 'msg' => '签名错误']);
}
// 当前用户账号 // 当前用户账号
$query = ['pid' => $pid, 'aid' => $aid]; $query = ['pid' => $pid, 'aid' => $aid];
// 排除已支付订单 // 排除已支付订单
$doneOrders = Order::scope('dealOrder')->where($query)->column('platform_order'); $doneOrders = Order::scope('dealOrder')->where($query)->column('platform_order');
$new_orders = []; $new_orders = [];
foreach ($payList as $order) { foreach ($records as $order) {
if (!in_array($order['order_no'], $doneOrders)) $new_orders[] = $order; if (!in_array($order['order_no'], $doneOrders)) $new_orders[] = $order;
} }
if (!count($new_orders)) return json(['code' => 0, 'msg' => '收款通知无新消息']); if (!count($new_orders)) return json(['code' => 0, 'msg' => '收款通知无新消息']);
@ -233,66 +223,47 @@ class PayController
return ['order' => $order->order_id, 'code' => 0, 'msg' => 'notify fail']; return ['order' => $order->order_id, 'code' => 0, 'msg' => 'notify fail'];
} }
} }
// [定时任务]获取收款明细,提交收款通知[本地版] // [定时任务]获取收款明细,提交收款通知
public function checkPayResult(Request $request) public function checkPayResult(Request $request)
{ {
$req_info = $request->get(); $req_info = $request->get();
$req_pid = $req_info['pid']; $req_pid = $req_info['pid'];
$req_aid = $req_info['aid']; $req_aid = $req_info['aid'];
// 加载配置文件
$config = \think\facade\Config::load("payconfig/{$req_pid}_{$req_aid}", 'payconfig');
// 用户账号配置
$user_config = isset($config['user']) ? $config['user'] : [];
// 收款平台账号配置
$pay_config = isset($config['pay']) ? $config['pay'] : [];
// 配置检查
if ($user_config && $pay_config) {
// 账号配置信息
$pid = $user_config['pid'];
$aid = $pay_config['aid'];
if (!($req_pid == $pid && $req_aid == $aid)) {
return '监听收款配置不一致';
}
} else {
return '监听收款配置文件名错误';
}
// 当前站点
$user_config['host'] = \request()->domain();
// 实例化支付类
$Mpay = new \MpayClass($user_config);
// 获取订单 // 获取订单
$res_new_order = $Mpay->orderHeart(); $order_path = runtime_path() . '/order.json';
$new_order = json_decode($res_new_order, true); if (!file_exists($order_path)) return json(['code' => 3, 'msg' => '订单文件不存在']);
$new_order = json_decode(file_get_contents($order_path), true);
// 检测新订单 // 检测新订单
if ($new_order['code'] !== 1) return $res_new_order; if ($new_order['code'] !== 1) return json($new_order);
// 订单列表 // 订单列表
$order_list = $new_order['orders']; $order_list = $new_order['orders'];
// 检测本账号订单 // 检测本账号订单
$orders = []; $orders = [];
foreach ($order_list as $key => $val) { foreach ($order_list as $key => $val) {
if ($pid == $val['pid'] && $aid == $val['aid'] && $val['patt'] == 1) { if ($req_pid == $val['pid'] && $req_aid == $val['aid'] && $val['patt'] == 1) {
$orders[] = $order_list[$key]; $orders[] = $order_list[$key];
} }
} }
if (!$orders) { if (!$orders) return json(['code' => 0, 'msg' => '非本账号订单或监听模式不对']);
return \json(['code' => 0, 'msg' => '非本账号订单或监听模式不对']); // 加载配置文件
} $config = PayAccount::getAccountConfig($req_aid);
if ($config === false) return json(['code' => 4, 'msg' => '监听收款配置错误']);
// 登陆账号 // 登陆账号
$config = ['username' => $pay_config['account'], 'password' => $pay_config['password']]; $pay_config = ['username' => $config['account'], 'password' => $config['password']];
// 收款查询 // 收款查询
$query = $pay_config['query']; $query = $config['query'];
// 实例监听客户端 // 实例监听客户端
$payclient_name = $pay_config['payclass']; $payclient_name = $config['payclass'];
$payclient_path = "\\payclient\\{$payclient_name}"; $payclient_path = "\\payclient\\{$payclient_name}";
$Payclient = new $payclient_path($config); $Payclient = new $payclient_path($pay_config);
// 获取支付明细 // 获取支付明细
$records = $Payclient->getOrderInfo($query); $records = $Payclient->getOrderInfo($query);
if ($records) { if ($records) {
// 提交收款记录 // 提交收款记录
$upres = $Mpay->upRecords($records, $aid); $upres = $this->payHeart($records, $config);
return $upres; return $upres;
} else { } else {
return \json(['code' => 0, 'msg' => '查询空订单'], 320); return json(['code' => 0, 'msg' => '查询空订单'], 320);
} }
} }
// [定时任务]监听新订单,生成JSON文件信息 // [定时任务]监听新订单,生成JSON文件信息
@ -337,10 +308,11 @@ class PayController
$action = isset($info['action']) ? $info['action'] : ''; $action = isset($info['action']) ? $info['action'] : '';
if ($action === 'mpay') { if ($action === 'mpay') {
$data = json_decode($info['data'], true); $data = json_decode($info['data'], true);
$config = \think\facade\Config::load("payconfig/{$data['pid']}_{$data['aid']}", 'payconfig'); $config = PayAccount::getAccountConfig($data['aid'], $data['pid']);
$payclient_path = "\\payclient\\{$config['pay']['payclass']}"; $payclient_path = "\\payclient\\{$config['payclass']}";
$Payclient = new $payclient_path($info, $config, $request->domain()); $Payclient = new $payclient_path($info, $config);
$Payclient->notify(); $res = $Payclient->notify();
$this->payHeart($res, $config);
return 200; return 200;
} else { } else {
return 202; return 202;

View File

@ -166,25 +166,17 @@ class PayManageController extends BaseController
$req_pid = $req_info['pid']; $req_pid = $req_info['pid'];
$req_aid = $req_info['aid']; $req_aid = $req_info['aid'];
// 加载配置文件 // 加载配置文件
$config = \think\facade\Config::load("payconfig/{$req_pid}_{$req_aid}", 'payconfig'); $config = PayAccount::getAccountConfig($req_aid);
// 收款平台账号配置 if ($config === false) return json(backMsg(1, '账号配置文件错误'));
$pay_config = isset($config['pay']) ? $config['pay'] : []; if ($req_aid != $config['aid'] || $req_pid != session('pid')) return json(backMsg(1, '监听收款配置不一致'));
// 配置检查
if ($pay_config) {
// 账号配置信息
$aid = $pay_config['aid'];
if ($req_aid != $aid) return '监听收款配置不一致';
} else {
return '监听收款配置文件名错误';
}
// 登陆账号 // 登陆账号
$config = ['username' => $pay_config['account'], 'password' => $pay_config['password']]; $pay_config = ['username' => $config['account'], 'password' => $config['password']];
// 收款查询 // 收款查询
$query = $pay_config['query']; $query = $config['query'];
// 实例监听客户端 // 实例监听客户端
$payclient_name = $pay_config['payclass']; $payclient_name = $config['payclass'];
$payclient_path = "\\payclient\\{$payclient_name}"; $payclient_path = "\\payclient\\{$payclient_name}";
$Payclient = new $payclient_path($config); $Payclient = new $payclient_path($pay_config);
// 获取支付明细 // 获取支付明细
$records = $Payclient->getOrderInfo($query); $records = $Payclient->getOrderInfo($query);
if ($records) { if ($records) {

View File

@ -5,6 +5,8 @@ declare(strict_types=1);
namespace app\model; namespace app\model;
use app\BaseModel; use app\BaseModel;
use app\model\User;
use app\controller\api\PluginController;
class PayAccount extends BaseModel class PayAccount extends BaseModel
{ {
@ -24,6 +26,40 @@ class PayAccount extends BaseModel
} }
return self::withCount(['payChannel' => 'channel'])->where($select); return self::withCount(['payChannel' => 'channel'])->where($select);
} }
// 获取账号配置
public static function getAccountConfig($aid, $pid = null): array|bool
{
$aid_info = self::find($aid);
// 插件配置
$platform = PluginController::getPluginInfo($aid_info->getData('platform'));
// 查询参数
$params = json_decode($aid_info->params, true);
$query = array_merge($platform['query'], $params);
if ($aid_info && $platform) {
$config = [
'pid' => $aid_info->pid,
// 账号id
'aid' => $aid_info->id,
// 收款平台
'platform' => $aid_info->getData('platform'),
// 插件类名
'payclass' => $platform['class_name'],
// 账号
'account' => $aid_info->account,
// 密码
'password' => $aid_info->password,
// 订单查询参数配置
'query' => $query,
];
if ($pid !== null) {
$pid_info = User::where('pid', $pid)->find();
$config['key'] = $pid_info->secret_key;
}
return $config;
} else {
return false;
}
}
// 获取器 // 获取器
public function getPlatformAttr($value) public function getPlatformAttr($value)
{ {

View File

@ -1,66 +0,0 @@
<?php
declare(strict_types=1);
class MpayClass
{
private $pid;
private $key;
private $host;
private $check_neworder_url;
private $submit_records_url;
function __construct($config)
{
$this->pid = $config['pid'];
$this->key = $config['key'];
$this->host = $config['host'];
$this->check_neworder_url = $this->host . '/order.php';
$this->submit_records_url = $this->host . '/payHeart';
}
// 查询新订单
public function orderHeart()
{
$url = $this->check_neworder_url . "?pid={$this->pid}&sign={$this->getSign()}";
$res = $this->getHttpResponse($url);
return $res;
}
// 提交收款明细
public function upRecords($records, $aid)
{
$header = ['Content-Type: application/json;charset=UTF-8'];
$url = $this->submit_records_url . "?pid={$this->pid}&aid={$aid}&sign={$this->getSign()}";
$res = $this->getHttpResponse($url, $header, json_encode($records));
return $res;
}
// 签名方法
private function getSign()
{
return md5($this->pid . $this->key);
}
// 请求外部资源
private function getHttpResponse($url, $header = [], $post = null, $timeout = 10)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
if ($header) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
} else {
$httpheader[] = "Accept: */*";
$httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
$httpheader[] = "Connection: close";
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
}
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if ($post) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
}
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
}