代码优化

This commit is contained in:
Billy 2025-10-21 20:48:28 +08:00
parent 866ca34023
commit 95d2a437d2
4 changed files with 38 additions and 22 deletions

View File

@ -44,8 +44,8 @@ return [
/**
* 服务方私钥 (自己生成的RSA私钥)
* 用途:
* - API请求签名MD5(明文 + 私钥)
* - 解密建行返回的加密数据(ccbParamSJ等)
* - 注意: 不直接参与签名,仅用于解密
* 格式: BASE64格式(不含PEM头尾) PEM格式(含头尾)
*/
'private_key' => $envVars['private_key'] ?? '',
@ -53,7 +53,8 @@ return [
/**
* 服务方公钥 (自己生成的RSA公钥,对应上面的私钥)
* 用途:
* - 参与支付下单的MD5签名计算(PLATFORMPUB字段)
* - 加密API请求报文建行用相同的公钥解密
* - 支付下单的MD5签名计算(PLATFORMPUB字段)
* - 加密商户公钥(ENCPUB字段)
* 格式: BASE64格式(不含PEM头尾) PEM格式(含头尾)
*/
@ -63,7 +64,6 @@ return [
* 建行生活支付验签公钥 (建行生活平台分配的)
* 用途:
* - 验证异步通知中的SIGN字段(NT_TYPE=YS时)
* - ⚠️ 重要: 这不是你自己的公钥!需要联系建行生活技术支持获取
* 获取方式: 联系建行生活平台运营人员或技术支持
* 格式: PEM格式RSA公钥(2048)
*

View File

@ -54,13 +54,13 @@ class CcbHttpClient
Log::info('建行生活API原始请求报文 [txCode=' . $txCode . '] [txSeq=' . $txSeq . ']');
Log::info('原始报文内容: ' . $message);
// 加密报文
// 使用服务方公钥加密报文
$encryptedMessage = CcbRSA::encryptForCcb($message, $this->config['public_key']);
// 移除BASE64中的换行符
$encryptedMessage = str_replace(["\r", "\n", "\r\n"], '', $encryptedMessage);
// 生成签名
// 使用服务方私钥签名
$mac = CcbMD5::signApiMessage($message, $this->config['private_key']);
// 发送HTTP请求
@ -118,26 +118,27 @@ class CcbHttpClient
'svcid' => $this->config['service_id']
];
// ✅ 将请求参数转为JSON格式按照建行报文示例要求
$jsonParams = json_encode($params, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// 📝 记录请求参数(加密后的完整内容)
Log::info('建行生活API加密请求参数 [txCode=' . $txCode . '] [url=' . $apiUrl . '] [timeout=' . self::DEFAULT_TIMEOUT . 's]');
Log::info('加密参数 cnt: ' . $cnt);
Log::info('加密参数 mac: ' . $mac);
Log::info('加密参数 svcid: ' . $this->config['service_id']);
Log::info('建行生活API加密请求 [txCode=' . $txCode . '] [url=' . $apiUrl . '] [timeout=' . self::DEFAULT_TIMEOUT . 's]');
Log::info('JSON请求体: ' . $jsonParams);
// 初始化CURL
$ch = curl_init();
// 设置CURL选项
// 设置CURL选项按照建行要求发送JSON格式
curl_setopt_array($ch, [
CURLOPT_URL => $apiUrl,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($params),
CURLOPT_POSTFIELDS => $jsonParams, // ✅ 发送JSON格式不是URL编码
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => self::DEFAULT_TIMEOUT,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_HTTPHEADER => [
'Content-Type: application/x-www-form-urlencoded',
'Content-Type: application/json; charset=utf-8', // ✅ JSON格式
'Accept: application/json'
]
]);

View File

@ -333,12 +333,22 @@ class CcbOrderService
$discountAmount = number_format($order['total_discount_fee'] ?? 0, 2, '.', '');
$totalRefundAmount = number_format($order['refund_fee'] ?? 0, 2, '.', '');
// 处理订单时间(Shopro的createtime是毫秒时间戳需要除以1000
// 处理订单时间(自动判断秒级或毫秒级时间戳
$createTimeValue = $order['createtime'] ?? null;
if (empty($createTimeValue) || !is_numeric($createTimeValue)) {
$createTimeValue = time() * 1000;
$createTimeValue = time(); // 使用当前秒级时间戳
}
$orderDt = date('YmdHis', intval($createTimeValue / 1000));
// 判断时间戳类型大于9999999999说明是毫秒级13位数否则是秒级10位数
if ($createTimeValue > 9999999999) {
// 毫秒级时间戳除以1000转为秒
$timestamp = intval($createTimeValue / 1000);
} else {
// 秒级时间戳,直接使用
$timestamp = intval($createTimeValue);
}
$orderDt = date('YmdHis', $timestamp);
// 处理订单过期时间
$invDt = '';

View File

@ -255,26 +255,31 @@ https://yunbusiness.ccb.com/tp_service/txCtrl/server?txcode=XX
| 字段 | 说明 |
|------|------|
| cnt | 使用服务方公钥对明文报文进行RSA加密后的BASE64编码内容 |
| mac | MD5(明文报文 + 服务方私钥) 的32位小写签名 |
| mac | MD5(明文报文 + 服务方私钥) 的32位**大写**签名API接口使用大写 |
| svcid | 服务方编号(建行分配) |
**请求方式**
```
```http
POST https://yunbusiness.ccb.com/tp_service/txCtrl/server?txcode=A3341TP01
Content-Type: application/x-www-form-urlencoded
Content-Type: application/json; charset=utf-8
cnt=BASE64加密内容&mac=MD5签名&svcid=服务方编号
{"cnt":"BASE64加密内容","mac":"大写MD5签名","svcid":"服务方编号"}
```
**完整示例**(参考):
**完整示例**(参考 - 来自建行提供的示例文件
```json
{
"cnt": "Y2tFMDFJd2RGMGg5aFdXUGtjVVdaSmo4NHBKQzNNZE1wQTRRSXZVRlhBSWhqVEdXNE1LcE9MOXdxY0hhNUlIZndUU0RLK3NrZ1hpTytJUitpREEwSUp0bktRcWMxRG5hN1R0OEtjcUkxTUFDVE5FY2Z0b3lCeTVTaEo3cmNjSnBOUVFsSjRBR2htSzRheEhNb0p6N215eFViK1ZjeGd5WjVTTjJQcHUxQlBnZXJsQXE2Q1lrQ2VuSmZEYUxVSks5RGx2Yk9YWDlDczJiVVllYjlHSHQrUkFuYTljc2hucGhqVWNwNDgrcThNcGhQOElBL20xNVk5NG9lZEV4SXpmc0pDcDExZjFvQ0E5YkwwOWJOZjM4VHR3TkJkTmhqM3lKSVpWeWVpT0FucGhjS3JpOEs5RnlZbXlNVHF1UER3UjhmQ0p5dk5vYkNMS1BPRmQ3WFdXTVczZ29kSWpLaG5OUnhnaFA3N2txdDU3K2Rkd3hGbDgxUEdYbXJWN1ZKWDFOeXRVUFg2dWp3ZzdsUU1OSTlubU1kVE9nbHZJUHRoS205aEludFc2ZFBVTG1DUlNLNzZDc05qTUIyb1hTR2M2cHBNazMxNDJSa05KR0hvY1ZBNFUzcmc4SVk4ZFlYaTUzZmF3cHRES3pHY2JYVFI0SldRVzRNU2ZmSUxvNFpxTkY=",
"mac": "947cab4dfebe59265dd28246e4465157",
"svcid": "YS44000009001853"
"mac": "947CAB4DFEBE59265DD28246E4465157",
"svcid": "YSTEST"
}
```
**⚠️ 重要说明**
- 请求体必须是**JSON格式**不是URL编码格式
- MAC签名必须是**32位大写MD5**API接口
- Content-Type必须设置为`application/json; charset=utf-8`
---
### 3.2 A3341TP02 - 服务方订单更新