chore(addon/huaweipay): 支持证书文本填写模式

This commit is contained in:
2025-12-03 10:37:39 +08:00
parent ca07a6cea5
commit f5ac4d10c0
4 changed files with 291 additions and 141 deletions

View File

@@ -32,6 +32,45 @@ 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 = "\n-----END PRIVATE KEY-----";
} elseif ($type == 'public_key') {
$header = "-----BEGIN PUBLIC KEY-----\n";
$footer = "\n-----END PUBLIC KEY-----";
}
// 每64个字符添加一个换行
$formattedContent = $header;
$length = strlen($content);
for ($i = 0; $i < $length; $i += 64) {
$formattedContent .= substr($content, $i, 64) . "\n";
}
$formattedContent .= $footer;
return $formattedContent;
}
/**
* 构造函数
* @param array $config 华为支付配置
@@ -53,37 +92,58 @@ class HuaweiPayClient
try {
// 加载商户应用私有证书
if (!empty($this->config['private_key'])) {
$private_key_content = '';
if (!empty($this->config['private_key_text'])) {
// 文本模式,需要格式化
$private_key_content = $this->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']);
if (!$private_key_path) {
throw new \Exception('商户应用私有证书文件不存在: ' . $this->config['private_key']);
}
$private_key_content = file_get_contents($private_key_path);
$this->private_key_certificate_instance = openssl_pkey_get_private($private_key_content);
if (!$this->private_key_certificate_instance) {
throw new \Exception('加载商户应用私有证书失败,请检查证书格式是否正确');
}
} else {
throw new \Exception('缺少必要配置private_key');
throw new \Exception('缺少必要配置private_key或private_key_text');
}
$this->private_key_certificate_instance = openssl_pkey_get_private($private_key_content);
if (!$this->private_key_certificate_instance) {
throw new \Exception('加载商户应用私有证书失败,请检查证书格式是否正确');
}
// 加载华为平台支付证书
if (!empty($this->config['huawei_public_key'])) {
$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');
} elseif (!empty($this->config['huawei_public_key'])) {
// 文件模式
$huawei_public_key_path = realpath($cert_base_path . $this->config['huawei_public_key']);
if (!$huawei_public_key_path) {
throw new \Exception('华为平台支付证书文件不存在: ' . $this->config['huawei_public_key']);
}
$huawei_public_key_content = file_get_contents($huawei_public_key_path);
$this->huawei_public_key_certificate_instance = openssl_pkey_get_public($huawei_public_key_content);
if (!$this->huawei_public_key_certificate_instance) {
throw new \Exception('加载华为平台支付证书失败,请检查证书格式是否正确');
}
} else {
throw new \Exception('缺少必要配置huawei_public_key');
throw new \Exception('缺少必要配置huawei_public_key或huawei_public_key_text');
}
$this->huawei_public_key_certificate_instance = openssl_pkey_get_public($huawei_public_key_content);
if (!$this->huawei_public_key_certificate_instance) {
throw new \Exception('加载华为平台支付证书失败,请检查证书格式是否正确');
}
// 加载华为平台支付服务加密证书(可选)
if (!empty($this->config['huawei_public_key_for_sessionkey'])) {
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');
$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('加载华为平台支付服务加密证书失败');
}
$this->has_huawei_public_key_certificate_instance_encrypt = true;
} elseif (!empty($this->config['huawei_public_key_for_sessionkey'])) {
// 文件模式
$huawei_public_key_encrypt_path = realpath($cert_base_path . $this->config['huawei_public_key_for_sessionkey']);
if (!$huawei_public_key_encrypt_path) {
throw new \Exception('华为平台支付服务加密证书文件不存在: ' . $this->config['huawei_public_key_for_sessionkey']);