chore(addon/huaweipay): 更新huaweipay

This commit is contained in:
2025-12-04 10:32:00 +08:00
parent 09ed1bd427
commit a793ed541b
14 changed files with 1093 additions and 498 deletions

View File

@@ -9,6 +9,9 @@ namespace addon\huaweipay\data\sdk;
use app\exception\ApiException;
use think\facade\Log;
// 引入工具类
use addon\huaweipay\data\sdk\Utils;
class HuaweiPayClient
{
// 华为支付网关地址
@@ -32,53 +35,14 @@ class HuaweiPayClient
// 是否加载了华为平台支付服务加密证书
private $has_huawei_public_key_certificate_instance_encrypt = false;
/**
* 格式化证书内容,添加适当的格式头尾
* @param string $content 证书内容
* @param string $type 证书类型private_key, public_key
* @return string 格式化后的证书内容
*/
private function formatCertificateContent($content, $type)
{
// 移除空白字符和换行
$content = preg_replace('/\s+/', '', $content);
// 检查是否已经包含格式头尾
if (preg_match('/-----BEGIN.*-----/', $content) && preg_match('/-----END.*-----/', $content)) {
return $content;
}
// 添加适当的格式头尾
$header = '';
$footer = '';
if ($type == 'private_key') {
$header = "-----BEGIN PRIVATE KEY-----\n";
$footer = "-----END PRIVATE KEY-----";
} elseif ($type == 'public_key') {
$header = "-----BEGIN PUBLIC KEY-----\n";
$footer = "-----END PUBLIC KEY-----";
}
// 每64个字符添加一个换行
$formattedContent = $header;
$length = strlen($content);
$lines = [];
for ($i = 0; $i < $length; $i += 64) {
$lines[] = substr($content, $i, 64);
}
$formattedContent .= implode("\n", $lines) . $footer;
return $formattedContent;
}
/**
* 构造函数
* @param array $config 华为支付配置
* @param string $cert_root_path 证书根路径
*/
public function __construct($config)
public function __construct($config, $cert_root_path = '')
{
$this->config = $config;
@@ -89,16 +53,36 @@ class HuaweiPayClient
if (empty($this->config['merc_no'])) {
throw new \Exception('缺少必要配置merc_no');
}
if (empty($this->config['site_id'])) {
throw new \Exception('缺少必要配置site_id');
}
if (empty($this->config['mch_auth_id'])) {
throw new \Exception('缺少必要配置mch_auth_id');
}
if (empty($this->config['private_key_text']) && empty($this->config['private_key'])) {
throw new \Exception('缺少必要配置private_key_text或private_key');
}
if (empty($this->config['huawei_public_key_text']) && empty($this->config['huawei_public_key'])) {
throw new \Exception('缺少必要配置huawei_public_key_text或huawei_public_key');
}
// 证书基础路径
$cert_base_path = app()->getRootPath();
$cert_base_path = $cert_root_path;
if (empty($cert_base_path)) {
// 没有指定证书根路径时,使用默认路径
try {
$cert_base_path = app()->getRootPath();
} catch (\Exception $e) {
// 捕获异常,使用默认路径
}
}
try {
// 加载商户应用私有证书
$private_key_content = '';
if (!empty($this->config['private_key_text'])) {
// 文本模式,需要格式化
$private_key_content = $this->formatCertificateContent($this->config['private_key_text'], 'private_key');
$private_key_content = Utils::formatCertificateContent($this->config['private_key_text'], 'private_key');
} elseif (!empty($this->config['private_key'])) {
// 文件模式
$private_key_path = realpath($cert_base_path . $this->config['private_key']);
@@ -112,14 +96,19 @@ class HuaweiPayClient
$this->private_key_certificate_instance = openssl_pkey_get_private($private_key_content);
if (!$this->private_key_certificate_instance) {
throw new \Exception('加载商户应用私有证书失败,请检查证书格式是否正确');
// 输出详细的openssl错误信息
$error = '';
while ($err = openssl_error_string()) {
$error .= $err . ' ';
}
throw new \Exception('加载商户应用私有证书失败请检查证书格式是否正确。OpenSSL错误: ' . $error . ' 证书内容开头: ' . substr($private_key_content, 0, 100));
}
// 加载华为平台支付证书
$huawei_public_key_content = '';
if (!empty($this->config['huawei_public_key_text'])) {
// 文本模式,需要格式化
$huawei_public_key_content = $this->formatCertificateContent($this->config['huawei_public_key_text'], 'public_key');
$huawei_public_key_content = Utils::formatCertificateContent($this->config['huawei_public_key_text'], 'public_key');
} elseif (!empty($this->config['huawei_public_key'])) {
// 文件模式
$huawei_public_key_path = realpath($cert_base_path . $this->config['huawei_public_key']);
@@ -139,7 +128,7 @@ class HuaweiPayClient
// 加载华为平台支付服务加密证书(可选)
if (!empty($this->config['huawei_public_key_for_sessionkey_text'])) {
// 文本模式,需要格式化
$huawei_public_key_encrypt_content = $this->formatCertificateContent($this->config['huawei_public_key_for_sessionkey_text'], 'public_key');
$huawei_public_key_encrypt_content = Utils::formatCertificateContent($this->config['huawei_public_key_for_sessionkey_text'], 'public_key');
$this->huawei_public_key_certificate_instance_encrypt = openssl_pkey_get_public($huawei_public_key_encrypt_content);
if (!$this->huawei_public_key_certificate_instance_encrypt) {
throw new \Exception('加载华为平台支付服务加密证书失败');
@@ -166,7 +155,7 @@ class HuaweiPayClient
// 根据配置设置网关地址
if (isset($config['sandbox']) && $config['sandbox']) {
$this->gatewayUrl = 'https://pay-drcn.cloud.huawei.com/gateway/api/pay';
$this->gatewayUrl = 'https://petalpay-developer-sandbox.cloud.huawei.com.cn/gateway/api/pay';
}
}