13 Commits

Author SHA1 Message Date
技术老胡
1ac1c2fd13 修改用户中心移动端排版问题 2025-03-18 13:53:07 +08:00
技术老胡
d570aa88b3 更新接口文档 2025-03-18 12:47:04 +08:00
技术老胡
a05a5710af 1. 优化数据库结构,增强兼容性
2. 添加手机浏览器跳转支付宝收银
3. 添加手机浏览器跳转微信支付提示信息
2025-03-18 11:49:00 +08:00
技术老胡
b3dd6ba3f0 Merge branch 'setconfig' of https://gitee.com/technical-laohu/mpay into setconfig 2025-03-14 16:06:50 +08:00
技术老胡
d0dd5a3f9b 更新文档 2025-03-14 16:06:46 +08:00
技术老胡
ccb94768d3 update README.md.
Signed-off-by: 技术老胡 <1094551889@qq.com>
2025-03-10 11:32:08 +00:00
技术老胡
7c35519e65 更新 2025-03-07 21:22:19 +08:00
技术老胡
d0fe56bade 优化安装检测程序,增强报错提示 2025-03-07 21:16:58 +08:00
技术老胡
0a270541c7 更新文档 2025-03-07 15:17:28 +08:00
技术老胡
62181cf33d 更新文档 2025-03-06 21:05:10 +08:00
技术老胡
1f98974d5a 新增支付宝免输插件,修复一些小问题 2025-03-05 11:28:44 +08:00
技术老胡
a59a22fe82 修复异次元发卡通知回调问题 2025-03-04 17:27:05 +08:00
技术老胡
e3d7efa60f 更新PC端监听软件 2025-03-03 11:45:39 +08:00
16 changed files with 1039 additions and 1273 deletions

2
.env
View File

@@ -1,4 +1,4 @@
APP_DEBUG = true
APP_DEBUG = false
DB_TYPE = mysql
DB_HOST = 127.0.0.1

View File

@@ -408,7 +408,7 @@ V免签是一款开源免费适用于个人收款使用的收款程序原理
码支付微信PC监听是老胡使用python写的小工具可以监听电脑桌面打开的窗口和内容信息非侵入微信应用内部版本升级不影响监听。需要将被监听的微信聊天界面单独拖出来成独立窗口。
[PC监听软件下载wxmonitor.zip](assets/20250217_103606_wxmonitor.zip)
[PC监听软件下载wxmonitor_v1.2.zip](assets/20250217_103606_wxmonitor_v1.2.zip)
##### 配置信息
@@ -444,6 +444,7 @@ V免签是一款开源免费适用于个人收款使用的收款程序原理
社群答疑、插件定制、技术交流,添加微信拉群,请备注:**码支付**
微信:**K103516**
备用:**HU1094551889**
<img src="assets/wxqrcode.png" width=480 />
@@ -460,6 +461,8 @@ V免签是一款开源免费适用于个人收款使用的收款程序原理
| 云峰 | 8.88 |
| 零零 | 200 |
| 子染 | 88 |
| John | 100 |
| 辰起 | 8.88 |
## 🔗 友情链接

View File

@@ -13,7 +13,7 @@ class ConsoleController extends BaseController
// 后台主页
public function index()
{
View::assign('version', 'v1');
View::assign('version', 'V1');
return View::fetch();
}
// 管理菜单
@@ -28,6 +28,12 @@ class ConsoleController extends BaseController
{
// 加载菜单配置
$message = \Plugin::getNotifyMessage();
if (empty($message)) {
$message = [
["id" => 1, "title" => "应用更新", "children" => []],
["id" => 2, "title" => "官方消息", "children" => []],
];
}
return json($message);
}
// 首页仪表盘

View File

@@ -7,85 +7,178 @@ namespace app\controller;
use think\facade\Db;
use think\Request;
use think\facade\View;
use think\facade\Log;
use think\exception\ValidateException;
use think\Validate;
class InstallController
{
private const INSTALL_LOCK_FILE = 'install.lock';
/**
* 连接数据库
* @return \think\db\Connection
*/
private function connectDatabase()
{
return Db::connect();
}
/**
* 首页,检查是否已安装,若已安装则跳转到登录页,否则显示安装页面
* @return \think\response\Redirect|\think\response\View
*/
public function index()
{
// 检查是否已经安装过
if ($this->checkLock()) {
return redirect('User/login');
};
}
return View::fetch();
}
/**
* 安装操作,检查环境、保存数据库配置信息
* @param Request $request
* @return \think\response\Json
*/
public function install(Request $request)
{
// 检查是否已经安装过
if ($this->checkLock()) {
return json(backMsg(1, '已经安装'));
};
// 检查环境
}
$envCheck = $this->checkEnvironment();
if ($envCheck !== true) {
return json(backMsg(1, $envCheck));
};
// 获取表单提交的数据库配置信息
$dbConfig = $request->post();
// 保存数据库配置信息到配置文件
if ($this->saveDbConfig($dbConfig) === false) {
return json(backMsg(1, '配置保存失败'));
} else {
return json(backMsg(0, '配置保存成功'));
};
}
// 初始化数据库
$dbConfig = $request->post();
try {
$this->validateDbConfig($dbConfig);
$this->saveDbConfig($dbConfig);
return json(backMsg(0, '配置保存成功'));
} catch (ValidateException $e) {
return json(backMsg(1, $e->getMessage()));
} catch (\Exception $e) {
Log::error("保存数据库配置失败: " . $e->getMessage());
return json(backMsg(1, '配置保存失败'));
}
}
/**
* 初始化数据库,创建表并初始化数据
* @param Request $request
* @return \think\response\Json
*/
public function init(Request $request)
{
// 检查是否已经安装过
if ($this->checkLock()) {
return backMsg(1, '已经安装');
};
// 获取表单提交的数据库配置信息
return json(backMsg(1, '已经安装'));
}
$dbConfig = $request->post();
$startTime = microtime(true);
// 连接数据库并建表
$is_succ_tb = $this->createTables();
// 初始化数据记录
$is_succ_data = $this->initData($dbConfig);
// 安装检测
if (!$is_succ_tb) {
return json(backMsg(1, '数据表创建失败'));
}
if (!$is_succ_data) {
return json(backMsg(1, '数据初始化失败'));
}
// 安装成功,写入安装锁文件
try {
$this->validateInitData($dbConfig);
$this->connectDatabase()->transaction(function () use ($dbConfig) {
$this->createTables();
$this->initData($dbConfig);
});
$this->setLock();
$endTime = microtime(true);
Log::info("数据库初始化完成,耗时: " . ($endTime - $startTime) . "");
return json(backMsg(0, '安装成功'));
} catch (ValidateException $e) {
return json(backMsg(1, $e->getMessage()));
} catch (\Exception $e) {
Log::error("数据库初始化失败: " . $e->getMessage());
return json(backMsg(1, '数据库初始化失败'));
}
}
/**
* 检查环境,包括 PHP 版本、文件上传写入权限、Fileinfo 扩展
* @return bool|string
*/
private function checkEnvironment()
{
// 检查PHP版本
if (version_compare(PHP_VERSION, '8.0', '<')) {
return 'PHP版本必须大于等于8.0';
return 'PHP 版本必须大于等于 8.0';
}
// 检查文件上传写入权限
if (!is_writable(sys_get_temp_dir())) {
return '文件上传目录没有写入权限';
}
// 检查Fileinfo扩展是否安装
if (!extension_loaded('fileinfo')) {
return 'Fileinfo扩展未安装';
return 'Fileinfo 扩展未安装';
}
return true;
}
private function saveDbConfig($dbConfig)
/**
* 验证数据库配置信息
* @param array $dbConfig
* @throws ValidateException
*/
private function validateDbConfig(array $dbConfig)
{
$validate = new Validate();
$rule = [
'host' => 'require',
'name' => 'require',
'user' => 'require',
'pass' => 'require',
'port' => 'require|integer',
'charset' => 'require'
];
if (!$validate->rule($rule)->check($dbConfig)) {
throw new ValidateException($validate->getError());
}
}
/**
* 验证初始化数据信息
* @param array $dbConfig
* @throws ValidateException
*/
private function validateInitData(array $dbConfig)
{
$validate = new Validate();
$rule = [
'nickname' => 'require',
'username' => 'require',
'password' => 'require'
];
if (!$validate->rule($rule)->check($dbConfig)) {
throw new ValidateException($validate->getError());
}
}
/**
* 保存数据库配置信息到 .env 文件
* @param array $dbConfig
* @throws \Exception
*/
private function saveDbConfig(array $dbConfig)
{
$envPath = app()->getRootPath() . '.env';
$envContent = <<<EOT
$envContent = $this->generateEnvContent($dbConfig);
if (file_put_contents($envPath, $envContent) === false) {
throw new \Exception("无法写入 .env 文件");
}
}
/**
* 生成 .env 文件内容
* @param array $dbConfig
* @return string
*/
private function generateEnvContent(array $dbConfig): string
{
return <<<EOT
APP_DEBUG = false
DB_TYPE = mysql
@@ -99,131 +192,172 @@ DB_PREFIX = mpay_
DEFAULT_LANG = zh-cn
EOT;
return file_put_contents($envPath, $envContent);
}
/**
* 创建数据库表
* @throws \Exception
*/
private function createTables()
{
// 连接数据库
$db = Db::connect();
if ($db === false) {
return false;
$db = $this->connectDatabase();
$tables = $this->getTableCreationSqls();
foreach ($tables as $tableName => $sql) {
try {
$db->execute("DROP TABLE IF EXISTS `$tableName`;");
$db->execute($sql);
Log::info("$tableName 表创建成功");
} catch (\Exception $e) {
throw new \Exception("创建 $tableName 表失败: " . $e->getMessage());
}
}
// 创建order表的 SQL 语句
$sql = "CREATE TABLE `mpay_order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` int(11) NOT NULL DEFAULT '0' COMMENT '商户ID',
`order_id` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '订单号',
`type` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '支付类型',
`out_trade_no` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '商户订单号',
`notify_url` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '异步通知地址',
`return_url` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '跳转通知地址',
`name` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '商品名称',
`really_price` float NOT NULL DEFAULT '0' COMMENT '实际支付金额',
`money` float NOT NULL DEFAULT '0' COMMENT '订单价格',
`clientip` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '用户IP地址',
`device` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '设备类型',
`param` varchar(720) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '扩展参数',
`state` tinyint(4) NOT NULL DEFAULT '0' COMMENT '订单状态',
`patt` tinyint(4) NOT NULL DEFAULT '0' COMMENT '开启回调监听',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '订单创建时间',
`close_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '订单关闭时间',
`pay_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '支付时间',
`platform_order` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '收款平台订单号',
`aid` int(11) NOT NULL DEFAULT '0' COMMENT '收款账号ID',
`cid` int(11) NOT NULL DEFAULT '0' COMMENT '收款码ID',
`delete_time` timestamp NULL DEFAULT NULL COMMENT '软删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;";
// 执行 SQL 语句创建表
$db->execute("DROP TABLE IF EXISTS `mpay_order`;");
$db->execute($sql);
// 创建pay_account表的 SQL 语句
$sql = "CREATE TABLE `mpay_pay_account` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '收款平台ID',
`pid` int(11) NOT NULL DEFAULT '0' COMMENT '用户ID',
`platform` varchar(255) NOT NULL DEFAULT '' COMMENT '收款平台',
`account` varchar(255) NOT NULL DEFAULT '' COMMENT '账号',
`password` varchar(255) NOT NULL DEFAULT '' COMMENT '密码',
`state` tinyint(4) NOT NULL DEFAULT '1' COMMENT '启用',
`pattern` tinyint(4) NOT NULL DEFAULT '1' COMMENT '账号监听模式',
`params` text NOT NULL COMMENT '自定义查询',
`delete_time` timestamp NULL DEFAULT NULL COMMENT '软删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;";
// 执行 SQL 语句创建表
$db->execute("DROP TABLE IF EXISTS `mpay_pay_account`;");
$db->execute($sql);
// 创建pay_channel表的 SQL 语句
$sql = "CREATE TABLE `mpay_pay_channel` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '渠道ID',
`account_id` int(11) NOT NULL DEFAULT '0' COMMENT '收款平台ID',
`channel` varchar(255) NOT NULL DEFAULT '' COMMENT '收款通道',
`type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '保存类型',
`qrcode` varchar(255) NOT NULL DEFAULT '' COMMENT '二维码',
`last_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最近使用',
`state` tinyint(4) NOT NULL DEFAULT '1' COMMENT '启用',
`delete_time` timestamp NULL DEFAULT NULL COMMENT '软删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;";
// 执行 SQL 语句创建表
$db->execute("DROP TABLE IF EXISTS `mpay_pay_channel`;");
$db->execute($sql);
// 创建user表的 SQL 语句
$sql = "CREATE TABLE `mpay_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` int(11) NOT NULL DEFAULT '0' COMMENT '商户ID',
`secret_key` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '商户秘钥',
`nickname` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '用户昵称',
`username` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '账号',
`password` varchar(255) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '密码',
`state` tinyint(4) NOT NULL DEFAULT '1' COMMENT '启用状态 0:禁用 1:启用',
`role` tinyint(4) NOT NULL DEFAULT '0' COMMENT '用户角色 0:普通用户 1:管理员',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`delete_time` timestamp NULL DEFAULT NULL COMMENT '软删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;";
// 执行 SQL 语句创建表
$db->execute("DROP TABLE IF EXISTS `mpay_user`;");
$db->execute($sql);
return true;
}
private function initData($dbConfig)
/**
* 获取表创建的 SQL 语句
* @return array
*/
private function getTableCreationSqls(): array
{
// 连接数据库
$db = Db::connect();
return [
'mpay_order' => "CREATE TABLE `mpay_order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` int(11) NOT NULL DEFAULT 0,
`order_id` varchar(255) NOT NULL DEFAULT '',
`type` varchar(255) NOT NULL DEFAULT '',
`out_trade_no` varchar(255) NOT NULL DEFAULT '',
`notify_url` varchar(255) NOT NULL DEFAULT '',
`return_url` varchar(255) NOT NULL DEFAULT '',
`name` varchar(255) NOT NULL DEFAULT '',
`really_price` decimal(10, 2) NOT NULL DEFAULT 0.00,
`money` decimal(10, 2) NOT NULL DEFAULT 0.00,
`clientip` varchar(255) NOT NULL DEFAULT '',
`device` varchar(255) NOT NULL DEFAULT '',
`param` varchar(720) NOT NULL DEFAULT '',
`state` tinyint(4) NOT NULL DEFAULT 0,
`patt` tinyint(4) NOT NULL DEFAULT 0,
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`close_time` datetime DEFAULT NULL,
`pay_time` datetime DEFAULT NULL,
`platform_order` varchar(255) NOT NULL DEFAULT '',
`aid` int(11) NOT NULL DEFAULT 0,
`cid` int(11) NOT NULL DEFAULT 0,
`delete_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `idx_order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;",
'mpay_pay_account' => "CREATE TABLE `mpay_pay_account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` int(11) NOT NULL DEFAULT 0,
`platform` varchar(255) NOT NULL DEFAULT '',
`account` varchar(255) NOT NULL DEFAULT '',
`password` varchar(255) NOT NULL DEFAULT '',
`state` tinyint(4) NOT NULL DEFAULT 1,
`pattern` tinyint(4) NOT NULL DEFAULT 1,
`params` text NOT NULL,
`delete_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;",
'mpay_pay_channel' => "CREATE TABLE `mpay_pay_channel` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`account_id` int(11) NOT NULL DEFAULT 0,
`channel` varchar(255) NOT NULL DEFAULT '',
`type` tinyint(4) NOT NULL DEFAULT 0,
`qrcode` varchar(255) NOT NULL DEFAULT '',
`last_time` datetime DEFAULT CURRENT_TIMESTAMP,
`state` tinyint(4) NOT NULL DEFAULT 1,
`delete_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;",
'mpay_user' => "CREATE TABLE `mpay_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` int(11) NOT NULL DEFAULT 0,
`secret_key` varchar(255) NOT NULL DEFAULT '',
`nickname` varchar(255) NOT NULL DEFAULT '',
`username` varchar(255) NOT NULL DEFAULT '',
`password` varchar(255) NOT NULL DEFAULT '',
`state` tinyint(4) NOT NULL DEFAULT 1,
`role` tinyint(4) NOT NULL DEFAULT 0,
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`delete_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;"
];
}
/**
* 初始化数据
* @param array $dbConfig
* @throws \Exception
*/
private function initData(array $dbConfig)
{
$db = $this->connectDatabase();
$info = [
'secret_key' => md5(1000 . time() . mt_rand()),
'nickname' => $dbConfig['nickname'],
'username' => $dbConfig['username'],
'password' => password_hash($dbConfig['password'], PASSWORD_DEFAULT),
'create_time' => date('Y-m-d H:i:s'),
];
// 初始化数据的 SQL 语句
$sql = "INSERT INTO `mpay_user` (`id`, `pid`, `secret_key`, `nickname`, `username`, `password`, `state`, `role`) VALUES (1, 1000, :secret_key, :nickname, :username, :password, 1, 1);";
// 执行 SQL 语句插入初始数据
$is_succ = $db->execute($sql, $info);
if (!$is_succ) {
return false;
$sql = "INSERT INTO `mpay_user` (`id`, `pid`, `secret_key`, `nickname`, `username`, `password`, `state`, `role`, `create_time`) VALUES (1, 1000, :secret_key, :nickname, :username, :password, 1, 1, :create_time);";
try {
$db->execute($sql, $info);
Log::info("mpay_user 表数据初始化成功");
} catch (\Exception $e) {
throw new \Exception("初始化 mpay_user 表数据失败: " . $e->getMessage());
}
return true;
}
/**
* 检查是否已安装
* @return bool
*/
private function checkLock()
{
$path = runtime_path() . 'install.lock';
$path = runtime_path() . self::INSTALL_LOCK_FILE;
return file_exists($path);
}
/**
* 设置安装锁
* @throws \Exception
*/
private function setLock()
{
$path = runtime_path() . 'install.lock';
file_put_contents($path, time());
$path = runtime_path() . self::INSTALL_LOCK_FILE;
if (file_put_contents($path, time()) === false) {
throw new \Exception("无法写入安装锁文件");
}
}
/**
* 更新数据库结构
* @return \think\response\Json
*/
public function update()
{
if ($this->checkLock()) {
return json(backMsg(1, '已经安装'));
}
$db = $this->connectDatabase();
try {
$result = $db->query("SHOW COLUMNS FROM `mpay_pay_account` WHERE Field = 'params'");
if ($result && $result[0]['Type'] != 'text') {
$sql = "ALTER TABLE `mpay_pay_account` MODIFY COLUMN `params` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '自定义查询' AFTER `pattern`;";
$is_succ = $db->execute($sql);
if (!$is_succ) {
throw new \Exception("修改 mpay_pay_account 表 params 列类型失败");
}
}
return json(backMsg(0, '数据库结构检查并更新完成'));
} catch (\Exception $e) {
Log::error("更新数据库结构失败: " . $e->getMessage());
return json(backMsg(1, '数据库结构更新失败'));
}
}
}

View File

@@ -66,7 +66,13 @@ class PayController
View::assign($act_order->toArray());
$passtime = strtotime($act_order->close_time) - time();
View::assign('passtime', $passtime > 0 ? $passtime : 0);
// Alipay免输
if (preg_match('/^alipay4#\d+$/', $channel->channel)) {
$payurl = \payclient\AliPayf::getPayUrl($act_order->order_id, $act_order->money, $channel->qrcode);
View::assign('payUrl', $payurl['data'] ?? $payurl['msg']);
} else {
View::assign('payUrl', $channel->qrcode);
}
View::assign('code_type', $channel->type);
return View::fetch();
} else {
@@ -165,9 +171,17 @@ class PayController
$is_money = $order->really_price == $new_order['price'];
// 订单核对
if ($is_payway && $is_channel && $is_money) {
// 是否免输
if (isset($new_order['remark'])) {
if ($new_order['remark'] == $order->order_id) {
$res = $this->updateOrderState($order, $new_order['order_no']);
$notify[] = $res;
}
} else {
$res = $this->updateOrderState($order, $new_order['order_no']);
$notify[] = $res;
}
}
}
}
if (!$notify) $notify = ['code' => 0, 'msg' => '收款通知无匹配订单'];
@@ -320,6 +334,10 @@ class PayController
// 添加扩展参数
// $notify = array_merge($notify, unserialize($param->param));
$notify['param'] = unserialize($param->param);
// 删除空值
foreach ($notify as $key => $val) {
if ($val === '') unset($notify[$key]);
}
return $notify;
}
// 请求外部资源

View File

@@ -162,6 +162,10 @@ class OrderController extends BaseController
// 添加扩展参数
// $notify = array_merge($notify, unserialize($param->param));
$notify['param'] = unserialize($param->param);
// 删除空值
foreach ($notify as $key => $val) {
if ($val === '') unset($notify[$key]);
}
return $notify;
}
// 请求外部资源

View File

@@ -92,6 +92,7 @@ class PayManageController extends BaseController
if ($check) {
return json(backMsg(1, '编号已存在'));
}
$info['last_time'] = date('Y-m-d H:i:s');
$res = PayChannel::create($info);
if ($res) {
return json(backMsg(0, '添加成功'));

View File

@@ -37,7 +37,7 @@ class Order extends BaseModel
// 商品金额
'money' => $data['money'],
// 实际成交金额
'really_price' => self::checkMoney($data['money'], $data['type'], $channel['aid'], $channel['cid']),
'really_price' => self::checkMoney($data['money'], $data['type'], $channel['aid'], $channel['cid'], $channel['chan']),
// 用户IP
'clientip' => isset($data['clientip']) ? $data['clientip'] : '',
// 设备类型
@@ -145,7 +145,7 @@ class Order extends BaseModel
if (!$channel_info) return backMsg(3, '用户账户无可用收款通道');
// 选取收款通道
$patt = PayAccount::find($channel_info->account_id);
$channel = ['aid' => $channel_info->account_id, 'cid' => $channel_info->id, 'patt' => $patt->getData('pattern')];
$channel = ['aid' => $channel_info->account_id, 'cid' => $channel_info->id, 'patt' => $patt->getData('pattern'), 'chan' => $channel_info->channel];
PayChannel::update(['last_time' => self::getFormatTime(), 'id' => $channel['cid']]);
return backMsg(0, 'ok', $channel);
}
@@ -162,9 +162,13 @@ class Order extends BaseModel
// return $params;
// }
// 检查金额
private static function checkMoney($money, $type, $aid, $cid): float
private static function checkMoney($money, $type, $aid, $cid, $chan): float
{
$money = (float) $money;
// Alipay免输
if (preg_match('/^alipay4#\d+$/', $chan)) {
return $money;
}
// 查询有效订单
$query = self::scope('activeOrder')->where(['type' => $type, 'aid' => $aid, 'cid' => $cid]);
$activeOrders = $query->column('really_price');

Binary file not shown.

View File

@@ -12,23 +12,11 @@ return array (
'price' => NULL,
'describe' => '支持微信个人收款码、赞赏码、经营码、商家码收款,监听回调',
'website' => 'https://weixin.qq.com',
'helplink' => '',
'helplink' => 'https://f0bmwzqjtq2.feishu.cn/docx/JBshdZWokoWzLmxSKQWcSd4Jncg',
'version' => '1.0',
'state' => 1,
),
1 =>
array (
'platform' => 'sqbpay',
'name' => '收钱吧',
'class_name' => 'ShouQianBa',
'price' => NULL,
'describe' => '主流移动支付全能收 信用卡,花呗都能用,生意帮手收钱吧,移动收款就用它!',
'website' => 'https://www.shouqianba.com',
'helplink' => '',
'version' => '1.0',
'state' => 1,
),
2 =>
array (
'platform' => 'alipay',
'name' => '支付宝',
@@ -36,7 +24,19 @@ return array (
'price' => NULL,
'describe' => '支持支付宝个人收款码、经营码收款,监听回调',
'website' => 'https://www.alipay.com',
'helplink' => '',
'helplink' => 'https://f0bmwzqjtq2.feishu.cn/docx/GfltdDrjxoYXwexhtX8ckDCBn9f',
'version' => '1.0',
'state' => 1,
),
2 =>
array (
'platform' => 'sqbpay',
'name' => '收钱吧',
'class_name' => 'ShouQianBa',
'price' => NULL,
'describe' => '主流移动支付全能收 信用卡,花呗都能用,生意帮手收钱吧,移动收款就用它!',
'website' => 'https://www.shouqianba.com',
'helplink' => 'https://f0bmwzqjtq2.feishu.cn/docx/WwN7dRqmuoozlIxgiuFclZhCnte',
'version' => '1.0',
'state' => 1,
),

View File

@@ -63,10 +63,12 @@ class Plugin
public static function getNotifyMessage(): array
{
$message = cache('message');
if ($message) return json_decode($message, true);
if ($message) return $message;
$message = self::getHttpResponse(self::$siteUrl . '/MpayApi', ['action' => 'message']);
cache('message', $message, 36000);
return json_decode($message, true);
$info = json_decode($message, true);
if($info === null) return [];
if ($info['code'] === 0) cache('message', $info['data'], 36000);
return $info['data'];
}
// 安装插件
public static function installPlugin($platform): array

Binary file not shown.

View File

@@ -82,7 +82,7 @@
<div class="layui-side-scroll">
<div id="sideMenu"></div>
</div>
<div id="version"><p>版本号:<?php echo $version ?></p><p>by techhaha</p></div>
<div id="version"><p>版本号:<?php echo $version ?></p><p>by 技术老胡</p></div>
</div>
<!-- 视 图 页 面 -->
<div class="layui-body">

View File

@@ -8,7 +8,6 @@
<head>
<title>开发文档</title>
</head>
<link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/KaTeX/0.7.1/katex.min.css">
<link rel="stylesheet" type="text/css"
href="https://cdn.jsdelivr.net/gh/pandao/editor.md@1.5.0/css/editormd.min.css">
<style type="text/css">
@@ -339,13 +338,111 @@
list-style-type: decimal !important;
}
</style>
<style type="text/css">
/* 新增样式 */
.doc-container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.doc-nav {
position: fixed;
left: 20px;
top: 100px;
width: 200px;
background: #f8f9fa;
padding: 15px;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
@media screen and (max-width: 992px) {
.doc-nav {
display: none;
/* 小屏幕隐藏导航栏 */
}
}
.doc-nav a {
display: block;
padding: 8px 12px;
color: #333;
text-decoration: none;
border-radius: 4px;
transition: all 0.3s;
}
.doc-nav a:hover {
background: #e9ecef;
}
table {
width: 100%;
margin: 20px 0;
border-collapse: collapse;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
table th {
background: #f8f9fa;
font-weight: 600;
padding: 12px;
text-align: left;
}
table td {
padding: 12px;
border-top: 1px solid #eee;
}
table tr:nth-child(even) {
background: #f8f9fa;
}
table tr:hover {
background: #f1f3f5;
}
code {
background: #f8f9fa;
padding: 2px 6px;
border-radius: 4px;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
}
pre code {
display: block;
padding: 15px;
background: #f8f9fa;
border-radius: 4px;
overflow-x: auto;
}
h3 {
margin-top: 40px;
padding-bottom: 10px;
border-bottom: 2px solid #eee;
}
</style>
<body>
<!-- <a href="javascript:window.print();" class="print-btn">打印(Print)</a> -->
<!-- MarkDown Content -->
<div class="doc-container">
<!-- 新增导航菜单 -->
<div class="doc-nav">
<a href="#toc2">协议规则</a>
<a href="#pay0">页面跳转支付</a>
<a href="#pay1">API接口支付</a>
<a href="#pay2">支付结果通知</a>
<a href="#pay3">MD5签名算法</a>
<a href="#pay4">支付方式列表</a>
<a href="#pay5">设备类型列表</a>
</div>
<h3 id="toc2"><a name="协议规则" class="reference-link"></a><span
class="header-link octicon octicon-link"></span>协议规则</h3>
class="header-link octicon octicon-link"></span>协议规则
</h3>
<p>请求数据格式application/x-www-form-urlencode</p>
<p>返回数据格式JSON</p>
<p>签名算法MD5</p>
@@ -353,7 +450,9 @@
<h3 id="pay0"><a name="页面跳转支付" class="reference-link"></a><span
class="header-link octicon octicon-link"></span>页面跳转支付</h3>
<p>此接口可用于用户前台直接发起支付使用form表单跳转或拼接成url跳转。</p>
<p>URL地址<a href="javascript:void(0);"><?php echo $domain ?>/submit.php</a></p>
<p>URL地址<a href="javascript:void(0);">
<?php echo $domain ?>/submit.php
</a></p>
<p>请求方式POST 或 GET推荐POST不容易被劫持或屏蔽</p>
<p>请求参数说明:</p>
<table>
@@ -454,7 +553,9 @@
<h3 id="pay1"><a name="API接口支付" class="reference-link"></a><span
class="header-link octicon octicon-link"></span>API接口支付</h3>
<p>此接口可用于服务器后端发起支付请求会返回支付二维码链接或支付跳转url。</p>
<p>URL地址<a href="javascript:void(0);"><?php echo $domain ?>/mapi.php</a></p>
<p>URL地址<a href="javascript:void(0);">
<?php echo $domain ?>/mapi.php
</a></p>
<p>请求方式POST</p>
<p>请求参数说明:</p>
<table>
@@ -604,8 +705,9 @@
<td>支付跳转url</td>
<td>payurl</td>
<td>String</td>
<td><a
href="javascript:void(0);"><?php echo $domain ?>/pay/wxpay/202010903/</a>
<td><a href="javascript:void(0);">
<?php echo $domain ?>/pay/wxpay/202010903/
</a>
</td>
<td>如果返回该字段则直接跳转到该url支付</td>
</tr>
@@ -790,579 +892,7 @@
</tbody>
</table>
<hr>
<h3 id="api1"><a name="[API]查询商户信息" class="reference-link"></a><span
class="header-link octicon octicon-link"></span>[API]查询商户信息</h3>
<p>URL地址<a
href="javascript:void(0);"><?php echo $domain ?>/api.php?act=query&amp;pid={商户ID}&amp;key={商户密钥}</a>
</p>
<p>请求参数说明:</p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>变量名</th>
<th>必填</th>
<th>类型</th>
<th>示例值</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>操作类型</td>
<td>act</td>
<td></td>
<td>String</td>
<td>query</td>
<td>此API固定值</td>
</tr>
<tr>
<td>商户ID</td>
<td>pid</td>
<td></td>
<td>Int</td>
<td>1001</td>
<td></td>
</tr>
<tr>
<td>商户密钥</td>
<td>key</td>
<td></td>
<td>String</td>
<td>89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i</td>
<td></td>
</tr>
</tbody>
</table>
<p>返回结果:</p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>变量名</th>
<th>类型</th>
<th>示例值</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>返回状态码</td>
<td>code</td>
<td>Int</td>
<td>1</td>
<td>1为成功其它值为失败</td>
</tr>
<tr>
<td>商户ID</td>
<td>pid</td>
<td>Int</td>
<td>1001</td>
<td>商户ID</td>
</tr>
<tr>
<td>商户密钥</td>
<td>key</td>
<td>String(32)</td>
<td>89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i</td>
<td>商户密钥</td>
</tr>
<tr>
<td>商户状态</td>
<td>active</td>
<td>Int</td>
<td>1</td>
<td>1为正常0为封禁</td>
</tr>
<tr>
<td>商户余额</td>
<td>money</td>
<td>String</td>
<td>0.00</td>
<td>商户所拥有的余额</td>
</tr>
<tr>
<td>结算方式</td>
<td>type</td>
<td>Int</td>
<td>1</td>
<td>1:支付宝,2:微信,3:QQ,4:银行卡</td>
</tr>
<tr>
<td>结算账号</td>
<td>account</td>
<td>String</td>
<td><a href="javascript:void(0);">admin@pay.com</a></td>
<td>结算的支付宝账号</td>
</tr>
<tr>
<td>结算姓名</td>
<td>username</td>
<td>String</td>
<td>张三</td>
<td>结算的支付宝姓名</td>
</tr>
<tr>
<td>订单总数</td>
<td>orders</td>
<td>Int</td>
<td>30</td>
<td>订单总数统计</td>
</tr>
<tr>
<td>今日订单</td>
<td>order_today</td>
<td>Int</td>
<td>15</td>
<td>今日订单数量</td>
</tr>
<tr>
<td>昨日订单</td>
<td>order_lastday</td>
<td>Int</td>
<td>15</td>
<td>昨日订单数量</td>
</tr>
</tbody>
</table>
<h3 id="api2"><a name="[API]查询结算记录" class="reference-link"></a><span
class="header-link octicon octicon-link"></span>[API]查询结算记录</h3>
<p>URL地址<a
href="javascript:void(0);"><?php echo $domain ?>/api.php?act=settle&amp;pid={商户ID}&amp;key={商户密钥}</a>
</p>
<p>请求参数说明:</p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>变量名</th>
<th>必填</th>
<th>类型</th>
<th>示例值</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>操作类型</td>
<td>act</td>
<td></td>
<td>String</td>
<td>settle</td>
<td>此API固定值</td>
</tr>
<tr>
<td>商户ID</td>
<td>pid</td>
<td></td>
<td>Int</td>
<td>1001</td>
<td></td>
</tr>
<tr>
<td>商户密钥</td>
<td>key</td>
<td></td>
<td>String</td>
<td>89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i</td>
<td></td>
</tr>
</tbody>
</table>
<p>返回结果:</p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>变量名</th>
<th>类型</th>
<th>示例值</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>返回状态码</td>
<td>code</td>
<td>Int</td>
<td>1</td>
<td>1为成功其它值为失败</td>
</tr>
<tr>
<td>返回信息</td>
<td>msg</td>
<td>String</td>
<td>查询结算记录成功!</td>
<td></td>
</tr>
<tr>
<td>结算记录</td>
<td>data</td>
<td>Array</td>
<td>结算记录列表</td>
<td></td>
</tr>
</tbody>
</table>
<h3 id="api3"><a name="[API]查询单个订单" class="reference-link"></a><span
class="header-link octicon octicon-link"></span>[API]查询单个订单</h3>
<p>URL地址<a
href="javascript:void(0);"><?php echo $domain ?>/api.php?act=order&amp;pid={商户ID}&amp;key={商户密钥}&amp;out_trade_no={商户订单号}</a>
</p>
<p>请求参数说明:</p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>变量名</th>
<th>必填</th>
<th>类型</th>
<th>示例值</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>操作类型</td>
<td>act</td>
<td></td>
<td>String</td>
<td>order</td>
<td>此API固定值</td>
</tr>
<tr>
<td>商户ID</td>
<td>pid</td>
<td></td>
<td>Int</td>
<td>1001</td>
<td></td>
</tr>
<tr>
<td>商户密钥</td>
<td>key</td>
<td></td>
<td>String</td>
<td>89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i</td>
<td></td>
</tr>
<tr>
<td>系统订单号</td>
<td>trade_no</td>
<td>选择</td>
<td>String</td>
<td>20160806151343312</td>
<td></td>
</tr>
<tr>
<td>商户订单号</td>
<td>out_trade_no</td>
<td>选择</td>
<td>String</td>
<td>20160806151343349</td>
<td></td>
</tr>
</tbody>
</table>
<p>提示:系统订单号 和 商户订单号 二选一传入即可,如果都传入以系统订单号为准!</p>
<p>返回结果:</p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>变量名</th>
<th>类型</th>
<th>示例值</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>返回状态码</td>
<td>code</td>
<td>Int</td>
<td>1</td>
<td>1为成功其它值为失败</td>
</tr>
<tr>
<td>返回信息</td>
<td>msg</td>
<td>String</td>
<td>查询订单号成功!</td>
<td></td>
</tr>
<tr>
<td>易支付订单号</td>
<td>trade_no</td>
<td>String</td>
<td>2016080622555342651</td>
<td>聚合易支付订单号</td>
</tr>
<tr>
<td>商户订单号</td>
<td>out_trade_no</td>
<td>String</td>
<td>20160806151343349</td>
<td>商户系统内部的订单号</td>
</tr>
<tr>
<td>第三方订单号</td>
<td>api_trade_no</td>
<td>String</td>
<td>20160806151343349</td>
<td>支付宝微信等接口方订单号</td>
</tr>
<tr>
<td>支付方式</td>
<td>type</td>
<td>String</td>
<td>alipay</td>
<td><a href="#pay4">支付方式列表</a></td>
</tr>
<tr>
<td>商户ID</td>
<td>pid</td>
<td>Int</td>
<td>1001</td>
<td>发起支付的商户ID</td>
</tr>
<tr>
<td>创建订单时间</td>
<td>addtime</td>
<td>String</td>
<td>2016-08-06 22:55:52</td>
<td></td>
</tr>
<tr>
<td>完成交易时间</td>
<td>endtime</td>
<td>String</td>
<td>2016-08-06 22:55:52</td>
<td></td>
</tr>
<tr>
<td>商品名称</td>
<td>name</td>
<td>String</td>
<td>VIP会员</td>
<td></td>
</tr>
<tr>
<td>商品金额</td>
<td>money</td>
<td>String</td>
<td>1.00</td>
<td></td>
</tr>
<tr>
<td>支付状态</td>
<td>status</td>
<td>Int</td>
<td>0</td>
<td>1为支付成功0为未支付</td>
</tr>
<tr>
<td>业务扩展参数</td>
<td>param</td>
<td>String</td>
<td></td>
<td>默认留空</td>
</tr>
<tr>
<td>支付者账号</td>
<td>buyer</td>
<td>String</td>
<td></td>
<td>默认留空</td>
</tr>
</tbody>
</table>
<h3 id="api4"><a name="[API]批量查询订单" class="reference-link"></a><span
class="header-link octicon octicon-link"></span>[API]批量查询订单</h3>
<p>URL地址<a
href="javascript:void(0);"><?php echo $domain ?>/api.php?act=orders&amp;pid={商户ID}&amp;key={商户密钥}</a>
</p>
<p>请求参数说明:</p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>变量名</th>
<th>必填</th>
<th>类型</th>
<th>示例值</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>操作类型</td>
<td>act</td>
<td></td>
<td>String</td>
<td>orders</td>
<td>此API固定值</td>
</tr>
<tr>
<td>商户ID</td>
<td>pid</td>
<td></td>
<td>Int</td>
<td>1001</td>
<td></td>
</tr>
<tr>
<td>商户密钥</td>
<td>key</td>
<td></td>
<td>String</td>
<td>89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i</td>
<td></td>
</tr>
<tr>
<td>查询订单数量</td>
<td>limit</td>
<td></td>
<td>Int</td>
<td>20</td>
<td>返回的订单数量最大50</td>
</tr>
<tr>
<td>页码</td>
<td>page</td>
<td></td>
<td>Int</td>
<td>1</td>
<td>当前查询的页码</td>
</tr>
</tbody>
</table>
<p>返回结果:</p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>变量名</th>
<th>类型</th>
<th>示例值</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>返回状态码</td>
<td>code</td>
<td>Int</td>
<td>1</td>
<td>1为成功其它值为失败</td>
</tr>
<tr>
<td>返回信息</td>
<td>msg</td>
<td>String</td>
<td>查询结算记录成功!</td>
<td></td>
</tr>
<tr>
<td>订单列表</td>
<td>data</td>
<td>Array</td>
<td></td>
<td>订单列表</td>
</tr>
</tbody>
</table>
<h3 id="api5"><a name="[API]提交订单退款" class="reference-link"></a><span
class="header-link octicon octicon-link"></span>[API]提交订单退款</h3>
<p>需要先在商户后台开启订单退款API接口开关才能调用该接口发起订单退款</p>
<p>URL地址<a href="javascript:void(0);"><?php echo $domain ?>/api.php?act=refund</a></p>
<p>请求方式POST</p>
<p>请求参数说明:</p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>变量名</th>
<th>必填</th>
<th>类型</th>
<th>示例值</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>商户ID</td>
<td>pid</td>
<td></td>
<td>Int</td>
<td>1001</td>
<td></td>
</tr>
<tr>
<td>商户密钥</td>
<td>key</td>
<td></td>
<td>String</td>
<td>89unJUB8HZ54Hj7x4nUj56HN4nUzUJ8i</td>
<td></td>
</tr>
<tr>
<td>易支付订单号</td>
<td>trade_no</td>
<td>特殊可选</td>
<td>String</td>
<td>20160806151343349021</td>
<td>易支付订单号</td>
</tr>
<tr>
<td>商户订单号</td>
<td>out_trade_no</td>
<td>特殊可选</td>
<td>String</td>
<td>20160806151343349</td>
<td>订单支付时传入的商户订单号,商家自定义且保证商家系统中唯一</td>
</tr>
<tr>
<td>退款金额</td>
<td>money</td>
<td></td>
<td>String</td>
<td>1.50</td>
<td>少数通道需要与原订单金额一致</td>
</tr>
</tbody>
</table>
<p>trade_no、out_trade_no 不能同时为空如果都传了以trade_no为准</p>
<p>返回结果:</p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>变量名</th>
<th>类型</th>
<th>示例值</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>返回状态码</td>
<td>code</td>
<td>Int</td>
<td>1</td>
<td>1为成功其它值为失败</td>
</tr>
<tr>
<td>返回信息</td>
<td>msg</td>
<td>String</td>
<td>退款成功</td>
<td></td>
</tr>
</tbody>
</table>
</div>
<!-- /MarkDown Content -->
</body>
<html>

View File

@@ -134,6 +134,12 @@
</span><span></span></div>
<div class="qrcode"><img id="qrcode" src="/static/img/loading.gif">
</div>
<!-- 添加跳转按钮 -->
<div style="margin: 16px auto;display: none;">
<button id="openApp" class="layui-btn layui-btn-normal">
打开支付应用
</button>
</div>
<div class="msg">
<p>请付款 <span class="note">
<?php echo htmlentities($really_price); ?>
@@ -180,7 +186,7 @@
}
</script>
<script>
const payCode = '<?php echo htmlentities($payUrl); ?>';
const payCode = '<?php echo $payUrl; ?>';
const codeType = '<?php echo htmlentities($code_type); ?>';
const payType = '<?php echo htmlentities($type); ?>';
const order = '<?php echo htmlentities($order_id); ?>';
@@ -284,6 +290,29 @@
} else if (payType === 'alipay' && environment === 'wxphone') {
layer.alert('请使用支付宝打开此页面');
}
// 添加按钮控制逻辑
const openAppBtn = document.getElementById('openApp');
if (environment === 'phone') {
openAppBtn.parentNode.style.display = 'block';
if (payType === 'wxpay') {
openAppBtn.innerText = '截图并打开微信';
openAppBtn.className = 'layui-btn layui-btn-green';
openAppBtn.onclick = function () {
window.location.href = 'weixin://';
};
} else if (payType === 'alipay') {
openAppBtn.innerText = '打开支付宝付款';
openAppBtn.className = 'layui-btn layui-btn-normal';
openAppBtn.onclick = function () {
if (codeType == 0) {
window.location.href = 'alipays://platformapi/startapp?appId=20000067&&url=' + payCode;
} else {
const currentUrl = window.location.href;
window.location.href = 'alipays://platformapi/startapp?appId=20000067&&url=' + currentUrl;
}
};
}
}
// 生成二维码
async function getQrcode(text, QR) {
const qrcodeUrl = await new Promise((resolve) => {

View File

@@ -19,6 +19,23 @@
align-items: center;
justify-content: center;
}
.infomsg {
display: flex;
align-items: center;
justify-content: space-between;
margin-left: 10px;
width: calc(100% - 20px);
}
.infomsg div:first-child {
width: 100%;
word-break: break-all;
}
.infomsg div:last-child {
text-align: center;
}
</style>
</head>
@@ -55,22 +72,26 @@
<div class="layui-form-item" pane>
<label class="layui-form-label">API 接口</label>
<div class="layui-input-block">
<div class="layui-form-mid" style="margin-left: 10px;color: #5f5f5f;float: none;">
<div class="layui-form-mid infomsg">
<div>
<?php echo $url ?>
<a href="javascript:;" lay-on="copyinfo" data-info="<?php echo $url ?>"
style="float: right;" title="复制"><span
class="icon pear-icon pear-icon-survey"></span></a>
</div>
<div><a href="javascript:;" lay-on="copyinfo" data-info="<?php echo $url ?>"
title="复制"><span class="icon pear-icon pear-icon-survey"></span></a>
</div>
</div>
</div>
</div>
<div class="layui-form-item" pane>
<label class="layui-form-label">商户 PID</label>
<div class="layui-input-block">
<div class="layui-form-mid" style="margin-left: 10px;color: #5f5f5f;float: none;">
<div class="layui-form-mid infomsg">
<div>
<?php echo $pid ?>
<a href="javascript:;" lay-on="copyinfo" data-info="<?php echo $pid ?>"
style="float: right;" title="复制"><span
class="icon pear-icon pear-icon-survey"></span></a>
</div>
<div><a href="javascript:;" lay-on="copyinfo" data-info="<?php echo $pid ?>"
title="复制"><span class="icon pear-icon pear-icon-survey"></span></a>
</div>
</div>
</div>
</div>
@@ -78,11 +99,13 @@
<label class="layui-form-label">商户密钥 <a href="javascript:;" lay-on="resetKey"
title="重置密钥"><span class="icon pear-icon pear-icon-refresh"></span></a></label>
<div class="layui-input-block">
<div class="layui-form-mid layui-elip"
style="margin-left: 10px;color: #5f5f5f;float: none;">
<div class="layui-form-mid infomsg">
<div>
<?php echo $secret_key ?>
<a href="javascript:;" lay-on="copyinfo" data-info="<?php echo $secret_key ?>"
style="float: right;" title="复制"><span
</div>
<div>
<a href="javascript:;" lay-on="copyinfo"
data-info="<?php echo $secret_key ?>" title="复制"><span
class="icon pear-icon pear-icon-survey"></span></a>
</div>
</div>
@@ -90,6 +113,7 @@
</div>
</div>
</div>
</div>
<div class="layui-card">
<div class="layui-card-header">聚合码定时任务<span class="layui-font-gray"> · 监控有效期订单</span></div>
@@ -98,11 +122,12 @@
<div class="layui-form-item" pane>
<label class="layui-form-label">订单监控</label>
<div class="layui-input-block">
<div class="layui-form-mid layui-elip"
style="margin-left: 10px;color: #5f5f5f;float: none;">
<div class="layui-form-mid infomsg">
<div>
<?php echo $orderurl ?>
<a href="javascript:;" lay-on="copyinfo" data-info="<?php echo $orderurl ?>"
style="float: right;" title="复制"><span
</div>
<div><a href="javascript:;" lay-on="copyinfo"
data-info="<?php echo $orderurl ?>" title="复制"><span
class="icon pear-icon pear-icon-survey"></span></a>
</div>
</div>
@@ -111,6 +136,7 @@
</div>
</div>
</div>
</div>
<div class="layui-col-md6">
<div class="layui-card">
@@ -123,54 +149,61 @@
<div class="layui-form-item" pane>
<label class="layui-form-label">Webhook</label>
<div class="layui-input-block">
<div class="layui-form-mid layui-elip"
style="margin-left: 10px;color: #5f5f5f;float: none;">
<div class="layui-form-mid infomsg">
<div>
<?php echo $url . 'mpayNotify' ?>
<a href="javascript:;" lay-on="copyinfo"
data-info="<?php echo $url . 'mpayNotify' ?>" style="float: right;"
title="复制"><span class="icon pear-icon pear-icon-survey"></span></a>
</div>
<div><a href="javascript:;" lay-on="copyinfo"
data-info="<?php echo $url . 'mpayNotify' ?>" title="复制"><span
class="icon pear-icon pear-icon-survey"></span></a>
</div>
</div>
</div>
</div>
<div class="layui-form-item" pane>
<label class="layui-form-label">消息模版</label>
<div class="layui-input-block">
<div class="layui-form-mid layui-elip"
style="margin-left: 10px;color: #5f5f5f;float: none;">
{"action": "mpay","data": "[msg]","time":"[timestamp]","sign": "[sign]"}
<a href="javascript:;" lay-on="copyinfo"
<div class="layui-form-mid infomsg">
<div>{"action": "mpay","data": "[msg]","time":"[timestamp]","sign":
"[sign]"}
</div>
<div><a href="javascript:;" lay-on="copyinfo"
data-info='{"action": "mpay","data": "[msg]","time":"[timestamp]","sign": "[sign]"}'
style="float: right;" title="复制"><span
title="复制"><span
class="icon pear-icon pear-icon-survey"></span></a>
</div>
</div>
</div>
</div>
<div class="layui-form-item" pane>
<label class="layui-form-label">Secret</label>
<div class="layui-input-block">
<div class="layui-form-mid layui-elip"
style="margin-left: 10px;color: #5f5f5f;float: none;">
<div class="layui-form-mid infomsg">
<div>
<?php echo $secret_key ?>
<a href="javascript:;" lay-on="copyinfo"
data-info="<?php echo $secret_key ?>" style="float: right;"
title="复制"><span class="icon pear-icon pear-icon-survey"></span></a>
</div>
<div><a href="javascript:;" lay-on="copyinfo"
data-info="<?php echo $secret_key ?>" title="复制"><span
class="icon pear-icon pear-icon-survey"></span></a>
</div>
</div>
</div>
</div>
<div class="layui-form-item" pane>
<label class="layui-form-label">成功关键字</label>
<div class="layui-input-block">
<div class="layui-form-mid layui-elip"
style="margin-left: 10px;color: #5f5f5f;float: none;">
200
<a href="javascript:;" lay-on="copyinfo" data-info="200"
style="float: right;" title="复制"><span
<div class="layui-form-mid infomsg">
<div>200</div>
<div><a href="javascript:;" lay-on="copyinfo" data-info="200"
title="复制"><span
class="icon pear-icon pear-icon-survey"></span></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</fieldset>
<fieldset class="layui-elem-field">
<legend style="font-size: 14px;">应用转发规则·多重匹配</legend>
@@ -179,26 +212,28 @@
<div class="layui-form-item" pane>
<label class="layui-form-label">微信支付</label>
<div class="layui-input-block">
<div class="layui-form-mid layui-elip"
style="margin-left: 10px;color: #5f5f5f;float: none;">
<div class="layui-form-mid infomsg">
<div>
<?php echo '并且 是 APP包名 相等 com.tencent.mm<br />并且 是 通知标题 相等 微信支付<br />[空格]或者 是 通知标题 相等 微信收款助手<br />[空格]或者 是 通知标题 相等 微信收款商业版' ?>
<a href="javascript:;" lay-on="copyinfo"
</div>
<div><a href="javascript:;" lay-on="copyinfo"
data-info='<?php echo "并且 是 APP包名 相等 com.tencent.mm\n并且 是 通知标题 相等 微信支付\n[空格]或者 是 通知标题 相等 微信收款助手\n[空格]或者 是 通知标题 相等 微信收款商业版" ?>'
style="float: right;" title="复制"><span
class="icon pear-icon pear-icon-survey"></span></a>
title="复制"><span class="icon pear-icon pear-icon-survey"></span></a>
</div>
</div>
</div>
</div>
<div class="layui-form-item" pane>
<label class="layui-form-label">支付宝</label>
<div class="layui-input-block">
<div class="layui-form-mid layui-elip"
style="margin-left: 10px;color: #5f5f5f;float: none;">
<div class="layui-form-mid infomsg">
<div>
<?php echo '并且 是 APP包名 相等 com.eg.android.AlipayGphone<br />并且 是 通知标题 包含 元<br />[空格]或者 是 通知内容 包含 元' ?>
<a href="javascript:;" lay-on="copyinfo"
</div>
<div><a href="javascript:;" lay-on="copyinfo"
data-info='<?php echo "并且 是 APP包名 相等 com.eg.android.AlipayGphone\n并且 是 通知标题 包含 元\n[空格]或者 是 通知内容 包含 元" ?>'
style="float: right;" title="复制"><span
class="icon pear-icon pear-icon-survey"></span></a>
title="复制"><span class="icon pear-icon pear-icon-survey"></span></a>
</div>
</div>
</div>
</div>