mirror of
https://gitee.com/liuxioabin/fengketrade.git
synced 2026-04-17 21:03:17 +08:00
180 lines
5.5 KiB
PHP
180 lines
5.5 KiB
PHP
<?php
|
||
|
||
namespace addons\shopro\library\ccblife;
|
||
|
||
/**
|
||
* 建行生活MD5签名类
|
||
* 处理API消息签名和支付字符串签名
|
||
*/
|
||
class CcbMD5
|
||
{
|
||
/**
|
||
* 生成API消息签名
|
||
*
|
||
* ⚠️ 注意:建行API接口签名使用大写MD5
|
||
* 签名规则:MD5(JSON报文 + 服务方私钥) → 转大写
|
||
*
|
||
* 示例:
|
||
* message = '{"CLD_HEADER":{...},"CLD_BODY":{...}}'
|
||
* privateKey = 'MIICeAIBA...'
|
||
* sign = strtoupper(md5(message + privateKey))
|
||
*
|
||
* @param string $message JSON格式的源报文
|
||
* @param string $privateKey 服务方私钥(BASE64格式)
|
||
* @return string 大写的32位MD5签名
|
||
*/
|
||
public static function signApiMessage($message, $privateKey)
|
||
{
|
||
// 移除私钥中的空格和换行
|
||
$privateKey = preg_replace('/\s+/', '', $privateKey);
|
||
|
||
// 计算MD5并转大写(建行要求)
|
||
return strtoupper(md5($message . $privateKey));
|
||
}
|
||
|
||
/**
|
||
* 验证API消息签名
|
||
*
|
||
* @param string $message JSON格式的源报文
|
||
* @param string $signature 待验证的签名
|
||
* @param string $privateKey 商户私钥(BASE64格式)
|
||
* @return bool 签名是否有效
|
||
*/
|
||
public static function verifyApiSignature($message, $signature, $privateKey)
|
||
{
|
||
$expectedSignature = self::signApiMessage($message, $privateKey);
|
||
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);
|
||
}
|
||
|
||
/**
|
||
* 生成交易流水号
|
||
* 格式:YYYYMMDDHHMMSS + 6位随机数
|
||
*
|
||
* @return string 20位交易流水号
|
||
*/
|
||
public static function generateTransactionSeq()
|
||
{
|
||
$timestamp = date('YmdHis');
|
||
$random = str_pad(mt_rand(0, 999999), 6, '0', STR_PAD_LEFT);
|
||
return $timestamp . $random;
|
||
}
|
||
|
||
/**
|
||
* 生成订单号
|
||
* 格式:前缀 + YYYYMMDDHHMMSS + 4位随机数
|
||
*
|
||
* @param string $prefix 订单号前缀,默认'CCB'
|
||
* @return string 订单号
|
||
*/
|
||
public static function generateOrderId($prefix = 'CCB')
|
||
{
|
||
$timestamp = date('YmdHis');
|
||
$random = str_pad(mt_rand(0, 9999), 4, '0', STR_PAD_LEFT);
|
||
return $prefix . $timestamp . $random;
|
||
}
|
||
} |