mirror of
https://gitee.com/liuxioabin/fengketrade.git
synced 2026-04-17 12:57:32 +08:00
代码优化
This commit is contained in:
parent
cd983a25c3
commit
267a76bd2c
@ -88,19 +88,19 @@ return [
|
||||
|
||||
/**
|
||||
* 支付位图 - 控制支付方式
|
||||
* 格式: 6位字符串,每位对应一个支付方式(1=开启,0=关闭)
|
||||
* 位置: [生活钱包][龙支付][微信][数字人民币][信用付][快贷]
|
||||
* 示例: '111111' = 全部开启, '110000' = 仅生活钱包和龙支付
|
||||
* 格式: ⚠️ 必须是10位数字字符串(文档强制要求)
|
||||
* 位置: [生活钱包][龙支付][微信][数字人民币][信用付][快贷][保留][保留][保留][保留]
|
||||
* 示例: '1111110000' = 前6种支付方式全开启, '1100000000' = 仅生活钱包和龙支付
|
||||
*/
|
||||
'pay_bitmap' => Env::get('ccb.pay_bitmap', '110000'),
|
||||
'pay_bitmap' => Env::get('ccb.pay_bitmap',''),
|
||||
|
||||
/**
|
||||
* 账户位图 - 控制支付账户类型
|
||||
* 格式: 5位字符串,每位对应一个账户类型(1=开启,0=关闭)
|
||||
* 位置: [建行借记卡][建行贷记卡][他行借记卡][他行贷记卡][建行钱包]
|
||||
* 示例: '11111' = 全部开启, '11000' = 仅建行卡
|
||||
* 格式: ⚠️ 必须是10位数字字符串(文档强制要求)
|
||||
* 位置: [建行借记卡][建行贷记卡][他行借记卡][他行贷记卡][建行钱包][保留][保留][保留][保留][保留]
|
||||
* 示例: '1111100000' = 前5种账户全开启, '1100000000' = 仅建行借记卡和贷记卡
|
||||
*/
|
||||
'account_bitmap' => Env::get('ccb.account_bitmap', '11000'),
|
||||
'account_bitmap' => Env::get('ccb.account_bitmap',''),
|
||||
|
||||
/**
|
||||
* 分期付款期数
|
||||
|
||||
@ -46,110 +46,6 @@ class CcbMD5
|
||||
return $expectedSignature === strtoupper($signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成支付字符串签名
|
||||
*
|
||||
* ⚠️ 注意:建行收银台支付串签名使用小写MD5
|
||||
* 签名规则:MD5(支付参数按顺序拼接 + 商户私钥) → 保持小写
|
||||
*
|
||||
* 示例:
|
||||
* paymentString = 'MERCHANTID=xxx&POSID=xxx&...&TIMEOUT=xxx' + privateKey
|
||||
* mac = md5(paymentString) // 小写
|
||||
*
|
||||
* @param array $params 支付参数
|
||||
* @param string $privateKey 商户私钥
|
||||
* @return string 小写的32位MD5签名
|
||||
*/
|
||||
public static function signPaymentString($params, $privateKey)
|
||||
{
|
||||
// 构建支付字符串(按照建行要求的顺序)
|
||||
$fields = [
|
||||
'MERCHANTID',
|
||||
'POSID',
|
||||
'BRANCHID',
|
||||
'ORDERID',
|
||||
'PAYMENT',
|
||||
'CURCODE',
|
||||
'TXCODE',
|
||||
'REMARK1',
|
||||
'REMARK2',
|
||||
'TIMEOUT'
|
||||
];
|
||||
|
||||
$parts = [];
|
||||
foreach ($fields as $field) {
|
||||
$value = isset($params[$field]) ? $params[$field] : '';
|
||||
$parts[] = $field . '=' . $value;
|
||||
}
|
||||
|
||||
// 拼接支付字符串并添加私钥
|
||||
$paymentString = implode('&', $parts) . $privateKey;
|
||||
|
||||
// 计算MD5(保持小写,建行要求)
|
||||
return md5($paymentString);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据完整技术方案生成标准支付字符串签名
|
||||
* 按照文档要求的格式生成签名
|
||||
*
|
||||
* @param string $merchantId 商户号
|
||||
* @param string $posId POS号
|
||||
* @param string $branchId 分行号
|
||||
* @param string $orderId 订单号
|
||||
* @param string $payment 支付金额
|
||||
* @param string $privateKey 商户私钥
|
||||
* @param string $curCode 币种,默认01(人民币)
|
||||
* @param string $txCode 交易码,默认530550
|
||||
* @param string $timeout 超时时间,默认空
|
||||
* @return array 包含支付字符串和签名
|
||||
*/
|
||||
public static function generatePaymentSignature($merchantId, $posId, $branchId, $orderId, $payment, $privateKey, $curCode = '01', $txCode = '530550', $timeout = '')
|
||||
{
|
||||
// 构建支付参数
|
||||
$params = [
|
||||
'MERCHANTID' => $merchantId,
|
||||
'POSID' => $posId,
|
||||
'BRANCHID' => $branchId,
|
||||
'ORDERID' => $orderId,
|
||||
'PAYMENT' => $payment,
|
||||
'CURCODE' => $curCode,
|
||||
'TXCODE' => $txCode,
|
||||
'REMARK1' => '',
|
||||
'REMARK2' => '',
|
||||
'TIMEOUT' => $timeout
|
||||
];
|
||||
|
||||
// 生成签名
|
||||
$mac = self::signPaymentString($params, $privateKey);
|
||||
|
||||
// 构建完整的支付字符串(不包含私钥)
|
||||
$fields = [];
|
||||
foreach ($params as $key => $value) {
|
||||
$fields[] = $key . '=' . $value;
|
||||
}
|
||||
$paymentString = implode('&', $fields);
|
||||
|
||||
return [
|
||||
'payment_string' => $paymentString,
|
||||
'mac' => $mac,
|
||||
'params' => $params
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证支付字符串签名
|
||||
*
|
||||
* @param array $params 支付参数
|
||||
* @param string $mac 待验证的MAC值
|
||||
* @param string $privateKey 商户私钥
|
||||
* @return bool 签名是否有效
|
||||
*/
|
||||
public static function verifyPaymentSignature($params, $mac, $privateKey)
|
||||
{
|
||||
$expectedMac = self::signPaymentString($params, $privateKey);
|
||||
return $expectedMac === strtolower($mac);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成交易流水号
|
||||
|
||||
@ -115,8 +115,8 @@ class CcbPaymentService
|
||||
$macParams['REGINFO'] = ''; // 客户注册信息(空字符串)
|
||||
|
||||
// 商品信息(escape编码)
|
||||
$proinfo = $this->buildProductInfo($order);
|
||||
$macParams['PROINFO'] = $proinfo;
|
||||
// $proinfo = $this->buildProductInfo($order);
|
||||
$macParams['PROINFO'] = '';
|
||||
|
||||
$macParams['REFERER'] = ''; // 商户URL(空字符串)
|
||||
|
||||
@ -252,6 +252,17 @@ class CcbPaymentService
|
||||
// 4. 生成MAC签名(32位小写MD5)
|
||||
$mac = strtolower(md5($macSignString));
|
||||
|
||||
// ⚠️ 调试输出:输出完整签名字符串用于排查
|
||||
Log::info('[建行支付] ========== 完整MAC签名字符串 ==========');
|
||||
Log::info('[建行支付] ' . $macSignString);
|
||||
Log::info('[建行支付] ========== 生成的MAC签名 ==========');
|
||||
Log::info('[建行支付] ' . $mac);
|
||||
Log::info('[建行支付] ========== 参数详情 ==========');
|
||||
Log::info('[建行支付] 参数数量: ' . count($macParams));
|
||||
foreach ($macParams as $key => $value) {
|
||||
Log::info('[建行支付] ' . $key . ' = ' . (strlen($value) > 100 ? substr($value, 0, 100) . '...(共' . strlen($value) . '字符)' : $value));
|
||||
}
|
||||
|
||||
Log::info('[建行支付] MAC签名字符串(前500字符): ' . mb_substr($macSignString, 0, 500));
|
||||
Log::info('[建行支付] 生成MAC: ' . $mac);
|
||||
|
||||
@ -482,45 +493,6 @@ class CcbPaymentService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化公钥为PEM格式
|
||||
*
|
||||
* 支持三种输入格式:
|
||||
* 1. PEM格式(已包含BEGIN/END标记)
|
||||
* 2. BASE64格式(不含PEM头尾)
|
||||
* 3. 十六进制格式(DER编码的十六进制字符串)
|
||||
*
|
||||
* @param string $publicKey 公钥(PEM/BASE64/HEX格式)
|
||||
* @return string PEM格式的公钥
|
||||
*/
|
||||
private function formatPublicKeyToPem($publicKey)
|
||||
{
|
||||
// 移除可能存在的空格和换行
|
||||
$publicKey = preg_replace('/\s+/', '', $publicKey);
|
||||
|
||||
// 如果已经是PEM格式,直接返回
|
||||
if (strpos($publicKey, '-----BEGIN PUBLIC KEY-----') !== false) {
|
||||
return $publicKey;
|
||||
}
|
||||
|
||||
// ✅ 判断是否为十六进制格式(只包含0-9a-fA-F字符)
|
||||
if (ctype_xdigit($publicKey)) {
|
||||
// 十六进制格式 → 解码为二进制 → 转BASE64
|
||||
$binaryKey = hex2bin($publicKey);
|
||||
if ($binaryKey === false) {
|
||||
throw new \Exception('十六进制公钥解码失败');
|
||||
}
|
||||
$publicKey = base64_encode($binaryKey);
|
||||
}
|
||||
|
||||
// 转换为PEM格式
|
||||
$pem = "-----BEGIN PUBLIC KEY-----\n";
|
||||
$pem .= rtrim(chunk_split($publicKey, 64, "\n"), "\n") . "\n";
|
||||
$pem .= "-----END PUBLIC KEY-----\n";
|
||||
|
||||
return $pem;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理支付回调
|
||||
* 建行支付完成后的同步回调
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user