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 }