mirror of
https://gitee.com/liuxioabin/fengketrade.git
synced 2026-04-17 21:03:17 +08:00
代码优化
This commit is contained in:
parent
cd983a25c3
commit
267a76bd2c
@ -88,19 +88,19 @@ return [
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付位图 - 控制支付方式
|
* 支付位图 - 控制支付方式
|
||||||
* 格式: 6位字符串,每位对应一个支付方式(1=开启,0=关闭)
|
* 格式: ⚠️ 必须是10位数字字符串(文档强制要求)
|
||||||
* 位置: [生活钱包][龙支付][微信][数字人民币][信用付][快贷]
|
* 位置: [生活钱包][龙支付][微信][数字人民币][信用付][快贷][保留][保留][保留][保留]
|
||||||
* 示例: '111111' = 全部开启, '110000' = 仅生活钱包和龙支付
|
* 示例: '1111110000' = 前6种支付方式全开启, '1100000000' = 仅生活钱包和龙支付
|
||||||
*/
|
*/
|
||||||
'pay_bitmap' => Env::get('ccb.pay_bitmap', '110000'),
|
'pay_bitmap' => Env::get('ccb.pay_bitmap',''),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 账户位图 - 控制支付账户类型
|
* 账户位图 - 控制支付账户类型
|
||||||
* 格式: 5位字符串,每位对应一个账户类型(1=开启,0=关闭)
|
* 格式: ⚠️ 必须是10位数字字符串(文档强制要求)
|
||||||
* 位置: [建行借记卡][建行贷记卡][他行借记卡][他行贷记卡][建行钱包]
|
* 位置: [建行借记卡][建行贷记卡][他行借记卡][他行贷记卡][建行钱包][保留][保留][保留][保留][保留]
|
||||||
* 示例: '11111' = 全部开启, '11000' = 仅建行卡
|
* 示例: '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);
|
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'] = ''; // 客户注册信息(空字符串)
|
$macParams['REGINFO'] = ''; // 客户注册信息(空字符串)
|
||||||
|
|
||||||
// 商品信息(escape编码)
|
// 商品信息(escape编码)
|
||||||
$proinfo = $this->buildProductInfo($order);
|
// $proinfo = $this->buildProductInfo($order);
|
||||||
$macParams['PROINFO'] = $proinfo;
|
$macParams['PROINFO'] = '';
|
||||||
|
|
||||||
$macParams['REFERER'] = ''; // 商户URL(空字符串)
|
$macParams['REFERER'] = ''; // 商户URL(空字符串)
|
||||||
|
|
||||||
@ -252,6 +252,17 @@ class CcbPaymentService
|
|||||||
// 4. 生成MAC签名(32位小写MD5)
|
// 4. 生成MAC签名(32位小写MD5)
|
||||||
$mac = strtolower(md5($macSignString));
|
$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签名字符串(前500字符): ' . mb_substr($macSignString, 0, 500));
|
||||||
Log::info('[建行支付] 生成MAC: ' . $mac);
|
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