xiuno 虎皮椒v3在线充值插件lite_pay V1.2
启用后会在用户个人中心显示充值选项,输入金额后,会自动生成微信扫码支付二维码,付款后会直接充值到账户余额。余额与积分的兑换比例为1:100,也就是充值1元,可以兑换成100积分。相关文案可以自行查找替换。
后台能够看到充值记录,包括充值用户的用户名、充值金额、充值时间和订单号,方便与虎皮椒后台的订单号核验,本插件仅作技术交流使用,请勿用于非法用途。
使用效果:

注意:本插件对接的是虎皮椒 V3微信官方支付接口,无需挂机,但需要在虎皮椒 V3侧开通相关渠道并取得APPID和APPSECRET,在插件设置中填入对应的密钥。由于回调接口的限制,需要在网站根目录放置notify.php文件,可以新建该文件后,填入以下内容,否则插件回调会出现异常:
<?php
ini_set('display_errors', '0');
error_reporting(E_ALL & ~E_NOTICE);
set_time_limit(0);
// 仅允许POST方法
if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
header('Content-Type: text/plain; charset=utf-8');
echo 'failed';
exit;
}
// 读取POST数据
$data = $_POST ?: array();
foreach ($data as $k => $v) { $data[$k] = stripslashes($v); }
// 加载配置与支付SDK
define('APP_PATH', rtrim(__DIR__, '/').'/');
define('DEBUG', 0);
$conf_file = APP_PATH . 'conf/conf.php';
if (!file_exists($conf_file)) {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
$conf = include $conf_file;
if (!is_array($conf)) {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
$api_file = APP_PATH.'plugin/lite_pay/lib/api.php';
if (!file_exists($api_file)) {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
require_once $api_file;
// 数据库配置解析
function xiuno_db_conf_normalize($conf) {
$host='127.0.0.1'; $user=''; $password=''; $name=''; $port=3306; $charset='utf8mb4'; $tablepre='';
if (isset($conf['db'])) {
$db = $conf['db'];
if (isset($db['mysql'])) {
$mysql = $db['mysql'];
$m = isset($mysql['master']) && is_array($mysql['master']) ? $mysql['master'] : (is_array($mysql) ? $mysql : array());
} else {
$m = is_array($db) ? $db : array();
}
$tablepre = $m['tablepre'] ?? ($db['tablepre'] ?? '');
} elseif (isset($conf['mysql'])) {
$m = isset($conf['mysql']['master']) ? $conf['mysql']['master'] : $conf['mysql'];
$tablepre = $m['tablepre'] ?? '';
} else {
$m = array();
}
$host = $m['host'] ?? $host;
$user = $m['user'] ?? ($m['username'] ?? $user);
$password = $m['password'] ?? ($m['passwd'] ?? $password);
$name = $m['name'] ?? ($m['dbname'] ?? $name);
$port = intval($m['port'] ?? $port);
$charset = $m['charset'] ?? $charset;
return compact('host','user','password','name','port','charset','tablepre');
}
$dbc = xiuno_db_conf_normalize($conf);
if (empty($dbc['user']) || empty($dbc['name'])) {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
// 连接数据库
$mysqli = @mysqli_connect($dbc['host'], $dbc['user'], $dbc['password'], $dbc['name'], $dbc['port']);
if (!$mysqli) {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
@mysqli_set_charset($mysqli, $dbc['charset'] ?: 'utf8mb4');
// 判断表是否存在
function table_exists($mysqli, $name) {
$name_esc = mysqli_real_escape_string($mysqli, $name);
$sql = "SHOW TABLES LIKE '{$name_esc}'";
if ($res = mysqli_query($mysqli, $sql)) {
$ok = mysqli_num_rows($res) > 0;
mysqli_free_result($res);
return $ok;
}
return false;
}
function resolve_table($base) {
global $dbc, $mysqli;
$cands = array();
if (!empty($dbc['tablepre'])) $cands[] = $dbc['tablepre'].$base;
if ($dbc['tablepre'] !== 'bbs_') $cands[] = 'bbs_'.$base;
$cands[] = $base;
foreach ($cands as $t) {
if (table_exists($mysqli, $t)) return $t;
}
return (!empty($dbc['tablepre']) ? $dbc['tablepre'].$base : $base);
}
$tbl_recharge = resolve_table('recharge_log');
$tbl_user = resolve_table('user');
$tbl_kv = resolve_table('kv');
// 从数据库获取支付配置
function kv_get_db($mysqli, $tbl_kv, $key) {
$sql = "SELECT `v` FROM `{$tbl_kv}` WHERE `k` = ? LIMIT 1";
$stmt = mysqli_prepare($mysqli, $sql);
if (!$stmt) return null;
mysqli_stmt_bind_param($stmt, 's', $key);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $val);
$ret = null;
if (mysqli_stmt_fetch($stmt)) $ret = $val;
mysqli_stmt_close($stmt);
if ($ret === null) return null;
$arr = json_decode($ret, true);
if (json_last_error() === JSON_ERROR_NONE && is_array($arr)) return $arr;
$arr = @unserialize($ret);
if (is_array($arr)) return $arr;
return $ret;
}
$pay_setting = kv_get_db($mysqli, $tbl_kv, 'pay_setting');
if (!is_array($pay_setting)) {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
$conf_appid = trim($pay_setting['appid'] ?? '');
$appsecret = trim($pay_setting['appsecret'] ?? '');
if (!$appsecret) {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
// 验证参数与签名
if (empty($data['hash']) || empty($data['trade_order_id'])) {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
$recv_appid = trim($data['appid'] ?? '');
if ($conf_appid && $recv_appid && $recv_appid !== $conf_appid) {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
if (!class_exists('XH_Payment_Api') || !method_exists('XH_Payment_Api','generate_xh_hash')) {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
$sign_data = $data; unset($sign_data['hash']);
$calc_hash = XH_Payment_Api::generate_xh_hash($sign_data, $appsecret);
if (!hash_equals($data['hash'], $calc_hash)) {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
// 只有 status == 'OD' 时才入账(amount单位为分,余额也是分)
$trade_order_id = $data['trade_order_id'];
$status = $data['status'] ?? '';
$transaction_id = $data['transaction_id'] ?? '';
$total_fee_str = $data['total_fee'] ?? '';
try {
if ($status === 'OD') {
// 查询订单
$sql = "SELECT `uid`,`status`,`amount` FROM `{$tbl_recharge}` WHERE `out_order_id`=? LIMIT 1";
$stmt = mysqli_prepare($mysqli, $sql);
mysqli_stmt_bind_param($stmt, 's', $trade_order_id);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $uid, $order_status, $order_amount_fen);
$found = mysqli_stmt_fetch($stmt);
mysqli_stmt_close($stmt);
if ($found) {
if (intval($order_status) === 0) {
// 开始事务
if (function_exists('mysqli_begin_transaction')) {
mysqli_begin_transaction($mysqli);
} else {
mysqli_query($mysqli, 'START TRANSACTION');
}
// 1)更新订单:status=1, plat_order_id, pay_date
$sql1 = "UPDATE `{$tbl_recharge}` SET `status`=1, `plat_order_id`=?, `pay_date`=? WHERE `out_order_id`=? AND `status`=0";
$stmt1 = mysqli_prepare($mysqli, $sql1);
$now = time();
mysqli_stmt_bind_param($stmt1, 'sis', $transaction_id, $now, $trade_order_id);
mysqli_stmt_execute($stmt1);
$aff1 = mysqli_stmt_affected_rows($stmt1);
mysqli_stmt_close($stmt1);
if ($aff1 > 0) {
// 2)增加用户余额(user.rmbs 单位为分)
$add_fen = intval($order_amount_fen);
$sql2 = "UPDATE `{$tbl_user}` SET `rmbs` = `rmbs` + ? WHERE `uid` = ?";
$stmt2 = mysqli_prepare($mysqli, $sql2);
mysqli_stmt_bind_param($stmt2, 'ii', $add_fen, $uid);
mysqli_stmt_execute($stmt2);
$aff2 = mysqli_stmt_affected_rows($stmt2);
mysqli_stmt_close($stmt2);
if ($aff2 > 0) {
mysqli_commit($mysqli);
// 金额一致性检查:平台 total_fee(元)与 amount(分)/100
if ($total_fee_str !== '') {
$recv_fen = (int) round(floatval($total_fee_str) * 100);
if (abs($recv_fen - $add_fen) > 0) {
// 金额不一致,仅忽略处理
}
}
} else {
mysqli_rollback($mysqli);
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
} else {
// 并发或失败,复查
mysqli_rollback($mysqli);
$sqlc = "SELECT `status` FROM `{$tbl_recharge}` WHERE `out_order_id`=? LIMIT 1";
$stmtc = mysqli_prepare($mysqli, $sqlc);
mysqli_stmt_bind_param($stmtc, 's', $trade_order_id);
mysqli_stmt_execute($stmtc);
mysqli_stmt_bind_result($stmtc, $stc);
$ok = (mysqli_stmt_fetch($stmtc) && intval($stc) === 1);
mysqli_stmt_close($stmtc);
if (!$ok) {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
}
}
} else {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
}
} catch (Throwable $e) {
header('Content-Type: text/plain; charset=utf-8'); echo 'failed'; exit;
}
// 返回成功
header('Content-Type: text/plain; charset=utf-8');
echo 'success';
exit;
?>


评论
0