2025-10-17 17:18:15 +08:00

168 lines
5.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace addons\shopro\library\ccblife;
/**
* 建行生活MD5签名类
* 处理API消息签名和支付字符串签名
*/
class CcbMD5
{
/**
* 生成API消息签名
* 使用大写MD5(源报文 + 私钥)
*
* @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(支付字符串)
* 支付字符串格式: MERCHANTID=xxx&POSID=xxx&BRANCHID=xxx&ORDERID=xxx&PAYMENT=xxx&CURCODE=01&TXCODE=530550&REMARK1=&REMARK2=&TIMEOUT=商户私钥
*
* @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;
}
}