113 lines
3.4 KiB
Go
113 lines
3.4 KiB
Go
package payment
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"time"
|
||
)
|
||
|
||
// BillQuery 查询对账单
|
||
// 对齐 YouChuKoffee 的 AccountBillQuery 流程:
|
||
// 1. 构建完整 {head, body} 结构(body 包含 accountingDate, fileIntfcName)
|
||
// 2. 整个 {head, body} 一起加密
|
||
// 3. head 同时作为 HTTP Header 明文传输
|
||
func (c *Client) BillQuery(date time.Time) (*BillQueryResponse, error) {
|
||
now := time.Now().Format("20060102150405")
|
||
BusiMainId := now + RandomNumber(10)
|
||
|
||
if date.IsZero() {
|
||
date = time.Now().AddDate(0, 0, -1)
|
||
}
|
||
|
||
// 构建完整 request(head+body 一起加密,对齐 YouChuKoffee)
|
||
requestBody := map[string]interface{}{
|
||
"head": map[string]string{
|
||
"partnerTxSriNo": BusiMainId,
|
||
"reqTime": now,
|
||
"method": "ufile.query.commonQuery",
|
||
"version": "1",
|
||
"merchantId": c.cfg.MerchantId,
|
||
"appID": c.cfg.AppID,
|
||
"accessType": "API",
|
||
"reserve": "",
|
||
},
|
||
"body": map[string]string{
|
||
"accountingDate": date.Format("20060102"),
|
||
"fileIntfcName": c.cfg.MchtNo,
|
||
},
|
||
}
|
||
|
||
// 整个 {head, body} 一起加密
|
||
encryptedReq, err := EncryptRequest(requestBody, c.cfg)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("加密请求失败: %v", err)
|
||
}
|
||
|
||
encryptedBytes, _ := json.Marshal(encryptedReq)
|
||
url := c.cfg.FileHost + c.cfg.MerchantId + ".htm?partnerTxSriNo=" + BusiMainId
|
||
|
||
// head 同时作为 HTTP Header 明文传输(对齐 YouChuKoffee 的 doPost 方式)
|
||
body, err := c.doPost(url, BusiMainId, "ufile.query.commonQuery", encryptedBytes)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
responseData, err := c.DecryptResponse(string(body), false)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("解密响应失败: %v,原始响应: %s", err, string(body))
|
||
}
|
||
|
||
var result BillQueryResponse
|
||
if err := json.Unmarshal([]byte(responseData), &result); err != nil {
|
||
return nil, fmt.Errorf("解析响应失败: %v,响应内容: %s", err, responseData)
|
||
}
|
||
|
||
return &result, nil
|
||
}
|
||
|
||
// BillDownload 下载对账单
|
||
// 对齐 YouChuKoffee 的 AccountBillDownload 流程:
|
||
// 1. 构建完整 {head, body} 结构(body 包含 fileIntfcName, sm4Key, fileId)
|
||
// 2. 整个 {head, body} 一起加密
|
||
// 3. head 同时作为 HTTP Header 明文传输
|
||
func (c *Client) BillDownload(fileId string, date time.Time) ([]byte, error) {
|
||
now := time.Now().Format("20060102150405")
|
||
BusiMainId := now + RandomNumber(10)
|
||
|
||
// 构建完整 request(head+body 一起加密,对齐 YouChuKoffee)
|
||
requestBody := map[string]interface{}{
|
||
"head": map[string]string{
|
||
"partnerTxSriNo": BusiMainId,
|
||
"reqTime": now,
|
||
"method": "ufile.download.commonDownload",
|
||
"version": "1",
|
||
"merchantId": c.cfg.MerchantId,
|
||
"appID": c.cfg.AppID,
|
||
"accessType": "API",
|
||
"reserve": "",
|
||
},
|
||
"body": map[string]string{
|
||
"fileIntfcName": c.cfg.MchtNo,
|
||
"sm4Key": "",
|
||
"fileId": fileId,
|
||
},
|
||
}
|
||
|
||
// 整个 {head, body} 一起加密
|
||
encryptedReq, err := EncryptRequest(requestBody, c.cfg)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("加密请求失败: %v", err)
|
||
}
|
||
|
||
encryptedBytes, _ := json.Marshal(encryptedReq)
|
||
url := c.cfg.FileHost + c.cfg.MerchantId + ".htm?partnerTxSriNo=" + BusiMainId
|
||
|
||
// head 同时作为 HTTP Header 明文传输(对齐 YouChuKoffee 的 doPost 方式)
|
||
body, err := c.doPost(url, BusiMainId, "ufile.download.commonDownload", encryptedBytes)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return body, nil
|
||
}
|