Files
oil/server-tp6/public/qyt_test.php
T
2026-09-10 20:56:46 +08:00

587 lines
25 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* ============================================================
* 慧明宝入站接口 · 联调测试脚本(模拟「下单平台」)
* ------------------------------------------------------------
* 放在 public/ 下,浏览器访问:http://你的域名/qyt_test.php
* 也可命令行:php qyt_test.php share
*
* 它做五件事:
* 1) 从数据库读取合作商(appKey / RSA 私钥 / orgNo)
* 2) 展示本次下单会用哪个【企油通企业】及其支付通道(口径同后端:
* 合作商绑定的企业 -> 默认企业),含是否要求身份证号、机构号是否已配置
* 3) 按「慧明宝」规范组装 RSA+AES 信封并调用我方入站接口
* 4) 展示明文请求 / 待签串 / 密文报文 / 服务端响应
* 5) act=notify_receiver 作为回调接收端,解密+验签我方推送的
* syb.notify.oilCard.change,并返回 {"code":"00"}
*
* ⚠️ 仅用于联调,正式环境请删除本文件。
* ============================================================
*/
const TEST_APPKEY = 'qyttest0000000000000000000001'; // 测试合作商 appKey
const API_VERSION = '1.0.0';
date_default_timezone_set('Asia/Shanghai');
$ROOT = dirname(__DIR__);
// ------------------------------------------------------------
// 基础工具
// ------------------------------------------------------------
function envConf($root)
{
$file = $root . '/.env';
if (!is_file($file)) {
throw new Exception('.env 不存在:' . $file);
}
$ini = parse_ini_file($file, true, INI_SCANNER_RAW) ?: [];
$db = isset($ini['DATABASE']) ? $ini['DATABASE'] : [];
return [
'host' => isset($db['HOSTNAME']) ? $db['HOSTNAME'] : '127.0.0.1',
'port' => isset($db['HOSTPORT']) ? $db['HOSTPORT'] : '3306',
'name' => isset($db['DATABASE']) ? $db['DATABASE'] : 'oil',
'user' => isset($db['USERNAME']) ? $db['USERNAME'] : 'root',
'pass' => isset($db['PASSWORD']) ? $db['PASSWORD'] : '',
'char' => isset($db['CHARSET']) ? $db['CHARSET'] : 'utf8',
];
}
function db($root)
{
static $pdo = null;
if ($pdo === null) {
$c = envConf($root);
$dsn = 'mysql:host=' . $c['host'] . ';port=' . $c['port'] . ';dbname=' . $c['name'] . ';charset=' . $c['char'];
$pdo = new PDO($dsn, $c['user'], $c['pass'], [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
}
return $pdo;
}
/** 读取合作商(下单平台账户) */
function getPartner($root, $appKey)
{
$st = db($root)->prepare('SELECT * FROM yoshop_partners WHERE appKey = ? LIMIT 1');
$st->execute([$appKey]);
$row = $st->fetch();
if (!$row) {
throw new Exception('未找到合作商,appKey=' . $appKey . '(请先执行 deploy/seed_test_partner.sql)');
}
return $row;
}
/**
* 解析某个合作商下单时实际使用的企油通企业与通道。
* 口径与 app\common\model\qyt\Enterprise::resolve 一致:
* 合作商绑定的企业 -> 默认企业(is_default=1 且启用)
* 接入方级参数(域名 / appId / 密钥)仍取 .env 的 [QYT] 段与后台设置。
* 本脚本是独立入口、不加载 ThinkPHP,所以重新实现了一遍,改动时两边要同步。
*/
function qytConf($root, $partner)
{
static $conf = null;
if ($conf !== null) {
return $conf;
}
$ini = parse_ini_file($root . '/.env', true, INI_SCANNER_RAW) ?: [];
$q = isset($ini['QYT']) ? $ini['QYT'] : [];
$get = function ($k, $d = '') use ($q) {
return isset($q[$k]) && trim((string)$q[$k]) !== '' ? trim((string)$q[$k]) : $d;
};
$conf = [
'base_url' => $get('BASE_URL'),
'no_prefix' => $get('NO_PREFIX', 'HM'),
'source' => '.env',
'enterprise' => null,
];
// 后台「企油通对接设置」覆盖接入方级默认值
try {
$st = db($root)->prepare("SELECT `values` FROM yoshop_store_setting WHERE `key`='qyt' ORDER BY store_id ASC LIMIT 1");
$st->execute();
$json = $st->fetchColumn();
$row = $json ? json_decode($json, true) : null;
if (is_array($row)) {
$conf['source'] = '.env + 后台设置';
foreach (['base_url', 'no_prefix'] as $k) {
if (isset($row[$k]) && trim((string)$row[$k]) !== '') {
$conf[$k] = trim((string)$row[$k]);
}
}
}
} catch (Throwable $e) {
// 忽略
}
// 企业:合作商绑定的 -> 默认企业
try {
$pdo = db($root);
$ent = null;
$bind = (int)(isset($partner['qyt_enterprise_id']) ? $partner['qyt_enterprise_id'] : 0);
if ($bind > 0) {
$st = $pdo->prepare('SELECT * FROM yoshop_qyt_enterprise WHERE enterprise_id = ? AND is_enable = 1 LIMIT 1');
$st->execute([$bind]);
$ent = $st->fetch() ?: null;
}
if (!$ent) {
$st = $pdo->query('SELECT * FROM yoshop_qyt_enterprise WHERE is_enable = 1 AND is_default = 1 ORDER BY enterprise_id ASC LIMIT 1');
$ent = $st->fetch() ?: null;
$conf['from_default'] = (bool)$ent;
} else {
$conf['from_default'] = false;
}
if ($ent) {
$pw = isset($ent['passageway']) && $ent['passageway'] === 'pingan' ? 'pingan' : 'alipay';
$ent['passageway'] = $pw;
$ent['passageway_code'] = $pw === 'pingan' ? 2 : 1;
$ent['passageway_name'] = $pw === 'pingan' ? '平安银行' : '支付宝企业码';
$ent['require_id_card'] = $pw === 'pingan';
// 企业可覆盖编号前缀
if (trim((string)$ent['no_prefix']) !== '') {
$conf['no_prefix'] = trim((string)$ent['no_prefix']);
}
$conf['enterprise'] = $ent;
}
} catch (Throwable $e) {
$conf['enterprise_error'] = $e->getMessage();
}
return $conf;
}
/** 平台公钥:加密 AES 密钥 / 验签我方回调 */
function platformPublicKey($root)
{
$p = $root . '/rsa/public_key.pem';
if (!is_file($p)) {
throw new Exception('平台公钥不存在:' . $p);
}
return file_get_contents($p);
}
function uniqueRequestId($appKey)
{
return $appKey . strtoupper(bin2hex(random_bytes(12)));
}
/**
* 组装请求信封(口径对齐 app\common\crypto\RsaUtil::processResponse)
* 待签串:http_build_query([version, appKey, method, requestId, body])
* body :json_encode($body, JSON_UNESCAPED_UNICODE)
* 签名 :SHA256withRSA,用【合作商私钥】
* AES :AES-256-ECB,随机 32 字节密钥;密钥用【平台公钥】RSA 加密
*/
function buildEnvelope($partner, $platformPub, $method, array $body)
{
$bodyJson = json_encode($body, JSON_UNESCAPED_UNICODE);
$requestId = uniqueRequestId($partner['appKey']);
$signData = http_build_query([
'version' => API_VERSION,
'appKey' => $partner['appKey'],
'method' => $method,
'requestId' => $requestId,
'body' => $bodyJson,
]);
$pkey = openssl_pkey_get_private($partner['privateKey']);
if ($pkey === false) {
throw new Exception('合作商私钥无效:' . openssl_error_string());
}
$signature = '';
openssl_sign($signData, $signature, $pkey, OPENSSL_ALGO_SHA256);
// AES-256-ECB 加密 body(与服务端 encryptData/decryptData 完全一致)
$aesKey = openssl_random_pseudo_bytes(32);
$encBody = base64_encode(openssl_encrypt($bodyJson, 'AES-256-ECB', $aesKey, OPENSSL_PKCS1_PADDING));
// 平台公钥加密 AES 密钥
$pub = openssl_pkey_get_public($platformPub);
if ($pub === false) {
throw new Exception('平台公钥无效:' . openssl_error_string());
}
$encKey = '';
openssl_public_encrypt($aesKey, $encKey, $pub, OPENSSL_PKCS1_PADDING);
return [
'headers' => [
'version' => API_VERSION,
'appKey' => $partner['appKey'],
'method' => $method,
'requestId' => $requestId,
'sign' => base64_encode($signature),
],
'body' => ['key' => base64_encode($encKey), 'data' => $encBody],
'plain' => $body,
'signData' => $signData,
];
}
function httpPost($url, array $headers, array $jsonBody)
{
$h = ['Content-Type: application/json', 'Charset: UTF-8'];
foreach ($headers as $k => $v) {
$h[] = $k . ': ' . $v;
}
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($jsonBody, JSON_UNESCAPED_UNICODE),
CURLOPT_HTTPHEADER => $h,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
]);
$resp = curl_exec($ch);
$err = curl_error($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ['http' => $code, 'body' => $resp, 'error' => $err];
}
/** 入站接口地址:public/partners.php/<控制器>/<方法> */
function apiUrl($path)
{
if (!empty($_GET['api'])) {
return rtrim($_GET['api'], '/') . '/partners.php' . $path;
}
if (PHP_SAPI === 'cli') {
return 'http://127.0.0.1/partners.php' . $path;
}
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
return $scheme . '://' . $_SERVER['HTTP_HOST'] . '/partners.php' . $path;
}
// ------------------------------------------------------------
// 回调接收端(模拟下单平台的 callback 地址)
// 我方 NotifyQueue 用 RsaUtil::prepareRequest 推送,注意它的待签串是
// 「原样拼接」,与入站的 http_build_query 不同。
// ------------------------------------------------------------
function notifyReceiver($root)
{
$raw = file_get_contents('php://input');
$headers = [];
foreach ($_SERVER as $k => $v) {
if (strpos($k, 'HTTP_') === 0) {
$headers[strtolower(str_replace('_', '', substr($k, 5)))] = $v;
}
}
$log = $root . '/runtime/qyt_test_notify.log';
@file_put_contents($log, date('Y-m-d H:i:s') . " 收到回调\nheaders=" . json_encode($headers, 320) . "\nbody=" . $raw . "\n", FILE_APPEND);
try {
$data = json_decode($raw, true);
$appKey = isset($headers['appkey']) ? $headers['appkey'] : TEST_APPKEY;
$partner = getPartner($root, $appKey);
// 1) 合作商私钥解出 AES 密钥
$pkey = openssl_pkey_get_private($partner['privateKey']);
$aesKey = '';
openssl_private_decrypt(base64_decode($data['key']), $aesKey, $pkey, OPENSSL_PKCS1_PADDING);
// 2) 解密 body
$plain = openssl_decrypt(base64_decode($data['data']), 'AES-256-ECB', $aesKey, OPENSSL_PKCS1_PADDING);
$body = json_decode($plain, true);
// 3) 平台公钥验签
$signData = 'version=' . API_VERSION
. '&appKey=' . $partner['appKey']
. '&method=' . (isset($headers['method']) ? $headers['method'] : '')
. '&requestId=' . (isset($headers['requestid']) ? $headers['requestid'] : '')
. '&body=' . json_encode($body);
$sign = isset($headers['sign']) ? $headers['sign'] : '';
$ok = openssl_verify($signData, base64_decode($sign), openssl_pkey_get_public(platformPublicKey($root)), OPENSSL_ALGO_SHA256);
@file_put_contents($log, '解密结果=' . json_encode($body, 320) . ' 验签=' . ($ok === 1 ? 'OK' : 'FAIL') . "\n\n", FILE_APPEND);
header('Content-Type: application/json');
echo json_encode(['code' => '00', 'message' => '请求成功'], JSON_UNESCAPED_UNICODE);
} catch (Throwable $e) {
@file_put_contents($log, '异常:' . $e->getMessage() . "\n\n", FILE_APPEND);
header('Content-Type: application/json');
echo json_encode(['code' => '99', 'message' => $e->getMessage()], JSON_UNESCAPED_UNICODE);
}
exit;
}
// ------------------------------------------------------------
// 各接口默认入参
// ------------------------------------------------------------
function defaultBody($act, $orgNo)
{
$saleOrderNo = 'TEST' . date('YmdHis') . mt_rand(100, 999);
$oilCardNo = isset($_GET['oilCardNo']) ? $_GET['oilCardNo'] : '';
$mobile = isset($_GET['mobile']) ? $_GET['mobile'] : '13800000001';
if ($act === 'share') {
$body = [
'orgNo' => $orgNo,
'amount' => isset($_GET['amount']) ? $_GET['amount'] : '100.00',
'mobile' => $mobile,
'name' => isset($_GET['name']) ? $_GET['name'] : '张三',
'saleOrderNo' => $saleOrderNo,
'oilCardType' => 'zsy_ticket',
];
// 司机身份证号:平安银行通道必传,支付宝企业码通道可不传。
// 加 &noIdCard=1 可故意不传,用来验证实名通道下的 0001 拒单是否生效。
if (empty($_GET['noIdCard'])) {
$body['idCard'] = isset($_GET['idCard']) ? $_GET['idCard'] : '450103199001011238';
}
return [
'method' => 'syb.oil.oilCard.share',
'path' => '/oilCard/share',
'body' => $body,
];
}
if ($act === 'qrcode') {
return [
'method' => 'syb.pay.qrCode.request',
'path' => '/oilCard/getPayQrCode',
'body' => ['orgNo' => $orgNo, 'oilCardNo' => $oilCardNo, 'mobile' => $mobile],
];
}
if ($act === 'status') {
return [
'method' => 'syb.oil.oilCard.orderStatus',
'path' => '/oilCard/orderStatus',
'body' => ['orgNo' => $orgNo, 'oilCardNo' => $oilCardNo],
];
}
if ($act === 'sharelist') {
return [
'method' => 'syb.oil.oilCard.shareList',
'path' => '/oilCard/shareList',
'body' => [
'orgNo' => $orgNo,
'mobile' => $mobile,
'beginDate' => date('Ymd', strtotime('-7 day')),
'endDate' => date('Ymd'),
'pageLimit' => '10',
'pageNum' => '1',
],
];
}
return null;
}
// ------------------------------------------------------------
// 主流程
// ------------------------------------------------------------
$act = isset($_GET['act']) ? $_GET['act'] : (isset($argv[1]) ? $argv[1] : '');
$fatal = '';
$result = null;
$partner = null;
$qconf = null;
try {
if ($act === 'notify_receiver') {
notifyReceiver($ROOT);
}
$partner = getPartner($ROOT, TEST_APPKEY);
$platformPub = platformPublicKey($ROOT);
$qconf = qytConf($ROOT, $partner);
if (in_array($act, ['share', 'qrcode', 'status', 'sharelist'], true)) {
$def = defaultBody($act, $partner['orgNo']);
$env = buildEnvelope($partner, $platformPub, $def['method'], $def['body']);
$url = apiUrl($def['path']);
$rsp = httpPost($url, $env['headers'], $env['body']);
$result = ['def' => $def, 'env' => $env, 'url' => $url, 'rsp' => $rsp];
}
} catch (Throwable $e) {
$fatal = $e->getMessage();
}
// ---------- 命令行输出 ----------
if (PHP_SAPI === 'cli') {
if ($fatal !== '') {
echo '错误:' . $fatal . "\n";
exit(1);
}
$ent = $qconf['enterprise'];
if (!$ent) {
echo "当前企业:【未匹配到可用企业】请先在后台「设置 -> 企业管理」新建企业并设为默认,否则下单会被拒绝
";
} else {
echo '当前企业:' . $ent['company_name'] . '(' . $ent['business_license'] . ')'
. ($qconf['from_default'] ? ' [默认企业]' : ' [合作商绑定]') . "
";
echo '当前通道:' . $ent['passageway_name'] . '(passageway=' . $ent['passageway_code'] . ')'
. ' 身份证号' . ($ent['require_id_card'] ? '必传' : '可不传')
. ' 机构号' . ($ent['institution_id'] !== '' ? '已配置' : '【未配置,下发必失败】')
. ' 企业状态' . $ent['status'] . "
";
echo '编号前缀:' . $qconf['no_prefix'] . ' 接入方配置来源:' . $qconf['source'] . "
";
}
if (!$result) {
echo "用法:php qyt_test.php [share|qrcode|status|sharelist]\n";
exit;
}
echo '接口:' . $result['def']['method'] . "\n";
echo 'URL :' . $result['url'] . "\n";
echo '明文:' . json_encode($result['env']['plain'], 320) . "\n";
echo 'HTTP:' . $result['rsp']['http'] . "\n";
echo '响应:' . $result['rsp']['body'] . "\n";
if ($result['rsp']['error'] !== '') {
echo 'cURL:' . $result['rsp']['error'] . "\n";
}
exit;
}
$rspArr = $result ? json_decode($result['rsp']['body'], true) : null;
$okFlag = is_array($rspArr) && isset($rspArr['code']) && $rspArr['code'] === '00';
$newOil = is_array($rspArr) && isset($rspArr['data']['oilCardNo']) ? $rspArr['data']['oilCardNo'] : '';
$curOil = isset($_GET['oilCardNo']) ? $_GET['oilCardNo'] : '';
?><!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>慧明宝入站接口 · 联调测试</title>
<style>
body{font:14px/1.7 -apple-system,"Microsoft YaHei",sans-serif;margin:0;background:#f5f6f8;color:#222}
.wrap{max-width:1000px;margin:0 auto;padding:24px}
h1{font-size:20px;margin:0 0 4px}
.sub{color:#888;font-size:13px;margin-bottom:18px}
.card{background:#fff;border:1px solid #e6e8eb;border-radius:8px;padding:16px 18px;margin-bottom:16px}
.card h2{font-size:15px;margin:0 0 12px;padding-bottom:8px;border-bottom:1px solid #eee}
.btns a{display:inline-block;margin:0 8px 8px 0;padding:7px 16px;background:#1890ff;color:#fff;
border-radius:4px;text-decoration:none;font-size:13px}
.btns a.g{background:#52c41a}.btns a.o{background:#faad14}.btns a.p{background:#722ed1}
.btns a.r{background:#ff4d4f}
table{border-collapse:collapse;width:100%;font-size:13px}
th,td{border:1px solid #eee;padding:6px 10px;text-align:left;vertical-align:top;word-break:break-all}
th{background:#fafafa;width:150px;font-weight:600;color:#555}
pre{background:#282c34;color:#abb2bf;padding:12px;border-radius:6px;overflow:auto;
font-size:12px;line-height:1.6;margin:0;white-space:pre-wrap;word-break:break-all}
.ok{color:#52c41a;font-weight:600}.err{color:#ff4d4f;font-weight:600}
.tip{background:#fffbe6;border:1px solid #ffe58f;padding:10px 14px;border-radius:6px;font-size:13px;margin-bottom:16px}
.lbl{margin:12px 0 6px;color:#555}
</style>
</head>
<body><div class="wrap">
<h1>慧明宝入站接口 · 联调测试</h1>
<div class="sub">模拟「下单平台」调用我方 API(RSA + AES 信封)。仅供联调,正式环境请删除本文件。</div>
<?php if ($fatal !== ''): ?>
<div class="card"><h2>初始化失败</h2><p class="err"><?php echo htmlspecialchars($fatal); ?></p></div>
<?php else: ?>
<div class="card">
<h2>当前合作商</h2>
<table>
<tr><th>partners_id</th><td><?php echo (int)$partner['partners_id']; ?></td></tr>
<tr><th>名称</th><td><?php echo htmlspecialchars($partner['name']); ?></td></tr>
<tr><th>orgNo</th><td><?php echo htmlspecialchars($partner['orgNo']); ?></td></tr>
<tr><th>appKey</th><td><?php echo htmlspecialchars($partner['appKey']); ?></td></tr>
<tr><th>余额</th><td><b><?php echo htmlspecialchars($partner['balance']); ?></b> 元 (下单会扣减,不足返回 2028)</td></tr>
<tr><th>回调地址</th><td><?php echo htmlspecialchars($partner['callback']); ?></td></tr>
</table>
</div>
<?php $ent = $qconf['enterprise']; ?>
<div class="card">
<h2>本次下单使用的企业与通道</h2>
<?php if (!$ent): ?>
<p class="err">未匹配到可用企业。请先到后台「设置 &rarr; 企业管理」新建企业并设为默认,否则下单接口会直接拒绝。</p>
<?php if (!empty($qconf['enterprise_error'])): ?>
<p class="err">读取企业表出错:<?php echo htmlspecialchars($qconf['enterprise_error']); ?></p>
<?php endif; ?>
<?php else: ?>
<table>
<tr><th>企业</th><td>
<b><?php echo htmlspecialchars($ent['company_name']); ?></b>
<?php echo $qconf['from_default'] ? '(来自<b>默认企业</b>兜底)' : '(该合作商<b>已绑定</b>此企业)'; ?>
</td></tr>
<tr><th>统一社会信用代码</th><td><?php echo htmlspecialchars($ent['business_license']); ?></td></tr>
<tr><th>企业状态</th><td>
<?php if ($ent['status'] === 'approved'): ?><span class="ok">审核通过</span>
<?php else: ?><span class="err"><?php echo htmlspecialchars($ent['status']); ?></span> 未通过审核时 7.15 免登地址会报「企业尚未通过审核」
<?php endif; ?>
</td></tr>
<tr><th>支付通道</th><td>
<b><?php echo htmlspecialchars($ent['passageway_name']); ?></b>(passageway=<?php echo (int)$ent['passageway_code']; ?>)
</td></tr>
<tr><th>司机身份证号</th><td>
<?php if ($ent['require_id_card']): ?>
<span class="err">必传</span> 该通道要求实名,下单不传 idCard 会返回 0001 拒单
<?php else: ?>
<span class="ok">可不传</span> 该通道不要求实名,传了也不会上送给企油通
<?php endif; ?>
</td></tr>
<tr><th>机构号</th><td>
<?php if ($ent['institution_id'] !== ''): ?><span class="ok">已配置</span>
<?php elseif ((int)$ent['passageway_code'] === 1): ?><span class="err">未配置</span> 支付宝企业码通道必填,下发时会失败并原路退回余额
<?php else: ?><span class="ok">平安通道无需机构号</span>
<?php endif; ?>
</td></tr>
<tr><th>编号前缀</th><td><?php echo htmlspecialchars($qconf['no_prefix']); ?></td></tr>
<tr><th>企油通域名</th><td><?php echo $qconf['base_url'] !== '' ? htmlspecialchars($qconf['base_url']) : '<span class="err">未配置</span>'; ?> <span class="sub">来源:<?php echo htmlspecialchars($qconf['source']); ?></span></td></tr>
</table>
<?php endif; ?>
</div>
<div class="tip">
接口地址默认取当前域名;如需指定,链接后加 <code>&amp;api=http://你的域名</code>。<br>
<b>下单前提</b>:三个队列进程已启动(partners:queue / callback:queue / notify:queue)、Redis 可用、合作商余额充足。
</div>
<div class="card">
<h2>发起测试</h2>
<div class="btns">
<a class="g" href="?act=share">① 下单分油 (share)</a>
<a class="o" href="?act=qrcode&amp;oilCardNo=<?php echo urlencode($curOil); ?>">② 获取加油链接 (qrCode)</a>
<a class="p" href="?act=status&amp;oilCardNo=<?php echo urlencode($curOil); ?>">③ 订单状态 (orderStatus)</a>
<a href="?act=sharelist">④ 分油记录 (shareList)</a>
<a class="r" href="?act=share&amp;noIdCard=1">⑤ 下单但不传身份证号</a>
</div>
<div class="sub" style="margin:6px 0 0">
②③ 需要 oilCardNo:先点①拿到后会自动带上。<br>
① 可自定义参数:<code>?act=share&amp;amount=50.00&amp;mobile=13800000002&amp;name=李四&amp;idCard=110101199003071233</code><br>
⑤ 用来验证实名校验:<?php echo !$ent ? '当前无可用企业' : ($ent['require_id_card']
? '当前是<b>' . htmlspecialchars($ent['passageway_name']) . '</b>通道,应当返回 <b>0001</b> 拒单'
: '当前是<b>' . htmlspecialchars($ent['passageway_name']) . '</b>通道,不要求实名,应当<b>正常下单成功</b>'); ?>
</div>
</div>
<?php if ($result): ?>
<div class="card">
<h2>请求 · <?php echo htmlspecialchars($result['def']['method']); ?></h2>
<table>
<tr><th>URL</th><td><?php echo htmlspecialchars($result['url']); ?></td></tr>
<tr><th>requestId</th><td><?php echo htmlspecialchars($result['env']['headers']['requestId']); ?></td></tr>
</table>
<p class="lbl">明文 body</p>
<pre><?php echo htmlspecialchars(json_encode($result['env']['plain'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); ?></pre>
<p class="lbl">待签串(http_build_query)</p>
<pre><?php echo htmlspecialchars($result['env']['signData']); ?></pre>
<p class="lbl">实际发送(密文信封)</p>
<pre><?php echo htmlspecialchars(json_encode($result['env']['body'], JSON_PRETTY_PRINT)); ?></pre>
</div>
<div class="card">
<h2>响应 <?php echo $okFlag ? '<span class="ok">成功</span>' : '<span class="err">失败</span>'; ?></h2>
<table>
<tr><th>HTTP 状态</th><td><?php echo (int)$result['rsp']['http']; ?></td></tr>
<?php if ($result['rsp']['error'] !== ''): ?>
<tr><th>cURL 错误</th><td class="err"><?php echo htmlspecialchars($result['rsp']['error']); ?></td></tr>
<?php endif; ?>
</table>
<p class="lbl">响应体</p>
<pre><?php echo htmlspecialchars(is_array($rspArr) ? json_encode($rspArr, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : $result['rsp']['body']); ?></pre>
<?php if ($newOil !== ''): ?>
<div class="btns" style="margin-top:14px">
<a class="o" href="?act=qrcode&amp;oilCardNo=<?php echo urlencode($newOil); ?>">用 <?php echo htmlspecialchars($newOil); ?> 取加油链接</a>
<a class="p" href="?act=status&amp;oilCardNo=<?php echo urlencode($newOil); ?>">查该单状态</a>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<?php endif; ?>
</div></body></html>