文件
xionggeshop/addons/shopro_huifu/library/HuifuNotifyParser.php

90 行
3.1 KiB
PHP

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?php
namespace addons\shopro_huifu\library;
use think\Request;
/**
* 解析汇付异步通知原始报文(不可走 htmlspecialchars 等全局 filter)
*/
class HuifuNotifyParser
{
public static function parse(Request $request = null)
{
$request = $request ?: Request::instance();
// 优先从原始 body 解析,避免 PHP 将 form 中 Base64 签名的 + 转成空格
$raw = method_exists($request, 'getInput') ? (string) $request->getInput() : '';
if ($raw === '') {
$raw = (string) file_get_contents('php://input');
}
if ($raw !== '') {
$contentType = strtolower((string) $request->contentType());
if (strpos($contentType, 'application/json') !== false) {
$decoded = json_decode($raw, true);
if (is_array($decoded)) {
$sign = self::normalizeSign((string) ($decoded['sign'] ?? ''));
$respData = $decoded['resp_data'] ?? '';
if (is_array($respData)) {
$respData = json_encode($respData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
return [
'sign' => $sign,
'resp_data' => (string) $respData,
];
}
} else {
$parsed = self::parseFormPreservePlus($raw);
if (!empty($parsed['resp_data']) || !empty($parsed['sign'])) {
return $parsed;
}
}
}
if (!empty($_POST['resp_data']) || !empty($_POST['sign'])) {
return [
'sign' => self::normalizeSign((string) ($_POST['sign'] ?? '')),
'resp_data' => (string) ($_POST['resp_data'] ?? ''),
];
}
return ['sign' => '', 'resp_data' => ''];
}
/**
* parse_str 会把 + 解码为空格,会破坏 Base64 签名
*/
protected static function parseFormPreservePlus($raw)
{
$parsed = [];
parse_str(str_replace('+', '%2B', $raw), $parsed);
$sign = self::normalizeSign((string) ($parsed['sign'] ?? ''));
$respData = (string) ($parsed['resp_data'] ?? '');
if ($respData === '' && isset($parsed['data']) && is_string($parsed['data'])) {
$inner = json_decode($parsed['data'], true);
if (is_array($inner)) {
$respData = $inner['resp_data'] ?? '';
if (is_array($respData)) {
$respData = json_encode($respData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
$respData = (string) $respData;
if ($sign === '' && !empty($inner['sign'])) {
$sign = self::normalizeSign((string) $inner['sign']);
}
}
}
return [
'sign' => $sign,
'resp_data' => $respData,
];
}
public static function normalizeSign($sign)
{
return str_replace(' ', '+', trim((string) $sign));
}
}