diff --git a/soul-admin/src/pages/distribution/DistributionPage.tsx b/soul-admin/src/pages/distribution/DistributionPage.tsx index 2c3e3a8f..98706602 100644 --- a/soul-admin/src/pages/distribution/DistributionPage.tsx +++ b/soul-admin/src/pages/distribution/DistributionPage.tsx @@ -221,21 +221,28 @@ export function DistributionPage() { } } - function refreshCurrentTab() { + async function refreshCurrentTab() { setLoadedTabs((prev) => { const next = new Set(prev) next.delete(activeTab) return next }) if (activeTab === 'overview') loadInitialData() - loadTabData(activeTab, true) + await loadTabData(activeTab, true) } async function handleApproveWithdrawal(id: string) { if (!confirm('确认审核通过并打款?')) return try { - await put('/api/admin/withdrawals', { id, action: 'approve' }) - refreshCurrentTab() + const res = await put<{ success?: boolean; error?: string }>('/api/admin/withdrawals', { + id, + action: 'approve', + }) + if (!res?.success) { + alert(res?.error || '操作失败') + return + } + await refreshCurrentTab() } catch (e) { console.error(e) alert('操作失败') @@ -246,8 +253,15 @@ export function DistributionPage() { const reason = prompt('请输入拒绝原因:') if (!reason) return try { - await put('/api/admin/withdrawals', { id, action: 'reject', errorMessage: reason }) - refreshCurrentTab() + const res = await put<{ success?: boolean; error?: string }>( + '/api/admin/withdrawals', + { id, action: 'reject', errorMessage: reason }, + ) + if (!res?.success) { + alert(res?.error || '操作失败') + return + } + await refreshCurrentTab() } catch (e) { console.error(e) alert('操作失败') diff --git a/soul-api/internal/handler/admin_withdrawals.go b/soul-api/internal/handler/admin_withdrawals.go index c354713f..24807021 100644 --- a/soul-api/internal/handler/admin_withdrawals.go +++ b/soul-api/internal/handler/admin_withdrawals.go @@ -201,16 +201,20 @@ func AdminWithdrawalsAction(c *gin.Context) { return } - // 打款已受理,更新为处理中并保存微信批次号 + // 打款已受理,更新为处理中并保存商家批次/明细单号及微信批次号 processingStatus := "processing" batchID := result.BatchID - _ = db.Model(&w).Updates(map[string]interface{}{ + if err := db.Model(&w).Updates(map[string]interface{}{ "status": processingStatus, "batch_no": outBatchNo, "detail_no": outDetailNo, "batch_id": batchID, "processed_at": now, - }).Error + }).Error; err != nil { + fmt.Printf("[AdminWithdrawals] 更新提现状态失败 id=%s: %v\n", body.ID, err) + c.JSON(http.StatusOK, gin.H{"success": false, "error": "更新状态失败: " + err.Error()}) + return + } // 始终返回 out_batch_no 便于追踪;batch_id 为微信返回,可能为空 c.JSON(http.StatusOK, gin.H{ "success": true, diff --git a/soul-api/internal/handler/payment.go b/soul-api/internal/handler/payment.go index e04127ef..759adb8f 100644 --- a/soul-api/internal/handler/payment.go +++ b/soul-api/internal/handler/payment.go @@ -2,7 +2,13 @@ package handler import ( "fmt" + "io" "net/http" + "time" + + "soul-api/internal/database" + "soul-api/internal/model" + "soul-api/internal/wechat" "github.com/gin-gonic/gin" ) @@ -48,38 +54,54 @@ func PaymentWechatNotify(c *gin.Context) { } // PaymentWechatTransferNotify POST /api/payment/wechat/transfer/notify +// 使用 PowerWeChat 验签、解密密文后更新提现状态,并返回微信要求的应答 func PaymentWechatTransferNotify(c *gin.Context) { - // 微信转账回调处理 - // 注意:实际生产环境需要验证签名,这里简化处理 - - var req struct { - ID string `json:"id"` - CreateTime string `json:"create_time"` - EventType string `json:"event_type"` - ResourceType string `json:"resource_type"` - Summary string `json:"summary"` - Resource struct { - Algorithm string `json:"algorithm"` - Ciphertext string `json:"ciphertext"` - AssociatedData string `json:"associated_data"` - Nonce string `json:"nonce"` - } `json:"resource"` - } - - if err := c.ShouldBindJSON(&req); err != nil { - fmt.Printf("[TransferNotify] 解析请求失败: %v\n", err) - c.JSON(http.StatusBadRequest, gin.H{"code": "FAIL", "message": "请求格式错误"}) + resp, err := wechat.HandleTransferNotify(c.Request, func(outBillNo, transferBillNo, state, failReason string) error { + fmt.Printf("[TransferNotify] 解密成功: out_bill_no=%s, transfer_bill_no=%s, state=%s\n", outBillNo, transferBillNo, state) + db := database.DB() + var w model.Withdrawal + if err := db.Where("detail_no = ?", outBillNo).First(&w).Error; err != nil { + fmt.Printf("[TransferNotify] 未找到 detail_no=%s 的提现记录: %v\n", outBillNo, err) + return nil // 找不到也返回成功,避免微信重复推送 + } + // 幂等:仅当当前为处理中/待确认时更新 + cur := "" + if w.Status != nil { + cur = *w.Status + } + if cur != "processing" && cur != "pending_confirm" { + return nil + } + now := time.Now() + up := map[string]interface{}{"processed_at": now} + switch state { + case "SUCCESS": + up["status"] = "success" + case "FAIL", "CANCELLED": + up["status"] = "failed" + if failReason != "" { + up["fail_reason"] = failReason + } + default: + return nil + } + if err := db.Model(&w).Updates(up).Error; err != nil { + return fmt.Errorf("更新提现状态失败: %w", err) + } + fmt.Printf("[TransferNotify] 已更新提现 id=%s -> status=%s\n", w.ID, up["status"]) + return nil + }) + if err != nil { + fmt.Printf("[TransferNotify] 验签/解密/处理失败: %v\n", err) + c.JSON(http.StatusInternalServerError, gin.H{"code": "FAIL", "message": err.Error()}) return } - - fmt.Printf("[TransferNotify] 收到转账回调: event_type=%s\n", req.EventType) - - // TODO: 使用 APIv3 密钥解密 resource.ciphertext - // 解密后可以获取转账详情(outBatchNo、outDetailNo、detailStatus等) - - // 暂时记录日志,实际处理需要解密后进行 - fmt.Printf("[TransferNotify] 转账回调数据: %+v\n", req) - - // 返回成功响应 - c.JSON(http.StatusOK, gin.H{"code": "SUCCESS", "message": "OK"}) + defer resp.Body.Close() + for k, v := range resp.Header { + if len(v) > 0 { + c.Header(k, v[0]) + } + } + c.Status(resp.StatusCode) + io.Copy(c.Writer, resp.Body) } diff --git a/soul-api/internal/wechat/miniprogram.go b/soul-api/internal/wechat/miniprogram.go index 1a721b83..56cd3901 100644 --- a/soul-api/internal/wechat/miniprogram.go +++ b/soul-api/internal/wechat/miniprogram.go @@ -364,6 +364,29 @@ func HandlePayNotify(req *http.Request, handler func(orderSn, transactionID stri }) } +// HandleTransferNotify 处理商家转账结果回调:验签并解密后调用 handler,返回应写回微信的 HTTP 响应 +// handler 参数:outBillNo(商户单号/即我们存的 detail_no)、transferBillNo、state(SUCCESS/FAIL/CANCELLED)、failReason +func HandleTransferNotify(req *http.Request, handler func(outBillNo, transferBillNo, state, failReason string) error) (*http.Response, error) { + if paymentApp == nil { + return nil, fmt.Errorf("支付/转账未初始化") + } + return paymentApp.HandleTransferBillsNotify(req, func(_ *notifyrequest.RequestNotify, bill *models.TransferBills, fail func(string)) interface{} { + if bill == nil { + fail("bill is nil") + return nil + } + outBillNo := bill.OutBillNo + transferBillNo := bill.TransferBillNo + state := bill.State + failReason := bill.FailReason + if err := handler(outBillNo, transferBillNo, state, failReason); err != nil { + fail(err.Error()) + return nil + } + return nil + }) +} + // GenerateOrderSn 生成订单号 func GenerateOrderSn() string { now := time.Now() diff --git a/soul-api/soul-api b/soul-api/soul-api index fc73652b..649ffa96 100644 Binary files a/soul-api/soul-api and b/soul-api/soul-api differ diff --git a/soul-api/tmp/build-errors.log b/soul-api/tmp/build-errors.log new file mode 100644 index 00000000..05e59854 --- /dev/null +++ b/soul-api/tmp/build-errors.log @@ -0,0 +1 @@ +exit status 1 \ No newline at end of file diff --git a/soul-api/tmp/main.exe b/soul-api/tmp/main.exe new file mode 100644 index 00000000..5595eb9f Binary files /dev/null and b/soul-api/tmp/main.exe differ diff --git a/soul-api/wechat/info.log b/soul-api/wechat/info.log index 8454e530..338eff6a 100644 --- a/soul-api/wechat/info.log +++ b/soul-api/wechat/info.log @@ -20,3 +20,11 @@ {"level":"debug","timestamp":"2026-02-09T21:28:10+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 400 Bad Request\r\nContent-Length: 207\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Mon, 09 Feb 2026 13:28:10 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 08EAC1A7CC0610EF0118B3D7BCA80120AD2028BF3A-268435462\r\nServer: nginx\r\nWechatpay-Nonce: a16fd3886807033516450570c6c04a12\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: S0I6R3gPOBPRTDXda0qgP7+htE2eBWPa6ypGyF/dY9CMEs/FAi2sTa9rSGovCTpOT2veC2w6UJZqHOVJ7RYNxyMCHei/mcGg4oZsUcr1qhDBqRkF4GtKQ5VAtxykdyvqoHNEwBG6ZVXaOXvDlIhVer+h8p/ETdmts+m3DSihLZ0ERQakUgilzMkvpCEWtZ9Z0o7zdIjB6dY2fJksQNEoDTsBU4AweU3O+6PIhReJD58iNrJoPdoUmnTedvIUyz4kaCPZo+QKD8k+VdzzuOa7SC1VrDvcnPdWAuEVUtjuZW4lN8VUCD0/I/N2WwYZzxc37Ai081U4u09GZA0TgTcjSQ==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1770643690\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"code\":\"PARAM_ERROR\",\"detail\":{\"location\":\"body\",\"value\":41},\"message\":\"输入源“/body/batch_remark”映射到值字段“批次备注”字符串规则校验失败,字符数 41,大于最大值 32\"}"} {"level":"debug","timestamp":"2026-02-09T21:28:32+08:00","caller":"kernel/baseClient.go:457","content":"POST https://api.mch.weixin.qq.com/v3/transfer/batches request header: { Content-Type:application/jsonAuthorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"gC08Q1aUBPsVnMhCKLKj77AiQIgqxeQk\",timestamp=\"1770643712\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"nMG2gpkUbjGyR/Mp45By3DUxCCL3gaPmhS0rTD3xMhxttP0Bd5n1/urSMMELmfi/y3zU3zlM2mgh4hqrbDWhQ9SQBq6una1b1C+w1S0It2G6pXGdHggpigc7sfjm7kABZaEPcejHiq1+HnKJ7MiCLRP3uf3UKXT4/brcUtVE2TjoBP9+nyMP93FOnqWlsc+FX4nv3RrsBwoIzOYWfSzwZ87DJ+fOAtd2pJiwOEqUPSnbUBaONbHj+aY3xAqTNkzfoMVyFvar6o9L9UFS0CEgjbo3bzVtKW/vT9SSFt9ZLlvSaexadYlrm2jKRSSO6N5KJRxPbgu1HJGcgxKafo5Bgw==\"Accept:*/*} request body:"} {"level":"debug","timestamp":"2026-02-09T21:28:32+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 400 Bad Request\r\nContent-Length: 207\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Mon, 09 Feb 2026 13:28:32 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 0880C2A7CC0610B50218C4D5BCA80120FB3C28DFCE03-268435462\r\nServer: nginx\r\nWechatpay-Nonce: 6b8c6025d942cccc9e5c0c31a6097ff0\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: jLFIoDyTQKuPQlqE8DvyFzcOy/AzkfntI+ifJOCuZA1XZSJ4faNweOJq6uydBhhe9Ibzm5dBxCyzAbzY/HBa5XW60JeNvnytb40xwcTvwKorfBLjZGWATbvrEuFdIoYdlFM5jBOXKndRaxYCUDoRmHAJGSHWOUSt+fJMuF1g9LZ77wRzIZlWJvRFtipzXEcu5/Sg1NjXgJcAKNREdVUxbQuEqqzue7d9gy8Fmqcm2cfZhJBXhw4A9FqauPIQ3prUf9nAEGCIFHm+WLHEFTXAXWsyj2Lynbrb8cwJzG2bkd2yesb0pXKJA0WHhWyqNtauezrwIg/tEyyfvgpVw+yDnA==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1770643712\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"code\":\"PARAM_ERROR\",\"detail\":{\"location\":\"body\",\"value\":41},\"message\":\"输入源“/body/batch_remark”映射到值字段“批次备注”字符串规则校验失败,字符数 41,大于最大值 32\"}"} +{"level":"debug","timestamp":"2026-02-09T21:40:37+08:00","caller":"kernel/baseClient.go:457","content":"POST https://api.mch.weixin.qq.com/v3/transfer/batches request header: { Authorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"fZv1KYtKyOuG9aLenhxnJCwf9JgyhT7v\",timestamp=\"1770644436\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"6Pc6KcE8BXmT4Y00YxjZ2y4dQZd4oMCePk/yugvzDCFw4nyjQ8yoqpcnDuo4QGw5ABlU8NcAtPOPpveyKBpCdY45AneBt9Uh8eHfYI4vWqckre3yNw3UlBxHJ6hbEPxbOnJvvJFW5Rt2Qln6Hke0Oyd1rNlnAaeHHz/ie6pgumiF26Gyp8Mr5XDxl4Gz68esbLpwoLQIjrZaZazd1xlDO/nll9uSLgiOM/RHhoyeAyeVDhJEE+exeSjWDyXft7rN0dPmhxHHWVBltYFw6V1D95s+RC7aRWG5ZEpduLgn+fTUurxtWXETRucZ8XNTuZ6o8y9tobubvO1bJhBwyGodJw==\"Accept:*/*Content-Type:application/json} request body:"} +{"level":"debug","timestamp":"2026-02-09T21:40:37+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 400 Bad Request\r\nContent-Length: 207\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Mon, 09 Feb 2026 13:40:37 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 08D5C7A7CC06106518B3D7BCA80120C82428DF17-268435462\r\nServer: nginx\r\nWechatpay-Nonce: 555ca34e99b229ae8722b17a444fce69\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: kjFHg6PwfDIWTtimgV9Jpps49VqEGZZgKpzhspwqmKkTlCgHaZ5sbxsS6zlu3HLPveMbp1YJT+NsttC29oE2TYQvyT+rb4fM21LiGJMfmzTaHOlm3/Vv3vUmVZKKAqxvsYqV7cXybNL7lkXvIKUPYTsNd6wZTrxp0BLl21HmomJTiwSVi1qdg26TbzJlMN5X1YEYVpID4fKyAi2jwUDR03hon4Nu/zqCDHBGE3uac7qMwZDWmgZ0IY2XU2DJb9Khg85332VueXGcFqS6WdDWs4vpTw0g5HjgsI2RVC34qL4eWlTx7LBiK5MjFiFQQ1EV9fYUJaPm6Iwci0X2LxBzpg==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1770644437\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"code\":\"PARAM_ERROR\",\"detail\":{\"location\":\"body\",\"value\":41},\"message\":\"输入源“/body/batch_remark”映射到值字段“批次备注”字符串规则校验失败,字符数 41,大于最大值 32\"}"} +{"level":"debug","timestamp":"2026-02-09T21:40:42+08:00","caller":"kernel/baseClient.go:457","content":"POST https://api.mch.weixin.qq.com/v3/transfer/batches request header: { Authorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"biCbHi901c0KG3yrtpsUhX10D4jtfv1r\",timestamp=\"1770644442\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"hWFgM9iRsqMOTRPboiHHrusYZTWTlrideAI175XS73cLBl9PaCUaXjmE18O/yrpK2bYDLHlmc73pdIV5HMCbKg6NbbLTMmROAWDtSrKfV9AMuEbzVf2cFxZ1sorDY3/mZHLaRd2saJuXDQZ4/yWVl0VPSLhLLc/CAKReHL4mnzLvNveL6v9ZJTG3iXWJo/nSXhikaKyNjT1vHSm0Mh1KED28/tT1vQjMlTOpLJNhkFUonga7OJepaSN4ZYbYH5kyeaSe1sRAjyA/+AlcCvn3eW2q/y6j4RIL166cx2fsvGbiTlmgJeYE8VZOWthIZ41z++EstuZT8SDtx2zCkWtQhg==\"Accept:*/*Content-Type:application/json} request body:"} +{"level":"debug","timestamp":"2026-02-09T21:40:42+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 400 Bad Request\r\nContent-Length: 207\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Mon, 09 Feb 2026 13:40:43 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 08DAC7A7CC0610B706189DD9BCA80120842328FFEF04-268435462\r\nServer: nginx\r\nWechatpay-Nonce: 74ebb834b8163518927bf67bf8adc4eb\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: Yoxp/JfQruTm1f47SZNMH8Asmj3BpZ9UHQxgUUAEqCLGIx6GeJlR1nbiOH/W4e7fJkkc3R9Tr/hi43msdRJ8um8X2OWSTGoqaRdeQermtVpyH9X5/EMq38WJiIPtX8k6fauCJURZ+XQsE7yxrmjiAQh4TQKMlYveo3af6qD2o+2jR/Dg8c/Wxur4RzYFUxQW9MarBqtZHVmf3pdnOe8ADJRJ352fHw+xbVNvNl+MAOfJhkJ806RPfXcJvR8hDd+SGCMS+sEa8BWPv3wFPvc6IcorzHBp6cySAV6+UxTYnwUXt4Qsb2o1ErWX95oTynnfHn4J6ZmrZbgM5koJBqS7tQ==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1770644442\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"code\":\"PARAM_ERROR\",\"detail\":{\"location\":\"body\",\"value\":41},\"message\":\"输入源“/body/batch_remark”映射到值字段“批次备注”字符串规则校验失败,字符数 41,大于最大值 32\"}"} +{"level":"debug","timestamp":"2026-02-09T21:46:31+08:00","caller":"kernel/baseClient.go:457","content":"POST https://api.mch.weixin.qq.com/v3/transfer/batches request header: { Accept:*/*Content-Type:application/jsonAuthorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"VIIanEIHgM8W03Rcehytyrkb7ExMapie\",timestamp=\"1770644791\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"5skRCvEVzcfiUO0t9ZWK6Xy8+xeQ41vRdPCWYwxLP4RmU1stcJXpw84q3Jr+ITgteSGCylv0v9i5Mo4Lq3aban//0ewF77VConuoaikrj63gxYjs4llOQQouttx80E6CQTPvIgtZjN8Nav41dOU+E85M+8gPVdlEttysg28Q6BnpqAcFaN63zMHsNGkBGst5ooMxrhxDsjECG0QcqQGPMHDx3YHaGS4QY9IaLZuqNsKWm1WoD3Z4SuZEWWXixvYPQf30uWotMxUOdO8sPdfr0zrP4mTapFHksDd+WmuZ5yZy90mxSoqHbqsddc3npDBJKjx/Av4KEa5mZC0gItDDWg==\"} request body:"} +{"level":"debug","timestamp":"2026-02-09T21:46:31+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 400 Bad Request\r\nContent-Length: 207\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Mon, 09 Feb 2026 13:46:31 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 08B7CAA7CC0610EA0418B3D7BCA80120812028ACD903-268435462\r\nServer: nginx\r\nWechatpay-Nonce: d08926059983e7a83c001572543aa0cc\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: DCqVYlZQVZC7VVTr55VqYFA1OxgJ048FAhYFZ2m2rBuMuRxUEF/JlSe3dZjRZUn9ZSUDzROrF5zBMG2phkxa8Qy2O7+hy/mrWd6BVD778TD6TiL2MqwIsj83DoMtV/yFrwlnhDRc4McKnD+NbrWdplVIYnSt1MyKJU1RQEdofGBKlx3p88bn8dgnNwsnokAp7dJBldQapOUCZc5LWJ2ZGEws5uniob6HIeZlQm7a3rgVzBm9VwJEuVpErZE0O5IvXOcZjGg+D1yiEBxLrIquQyjFyajOui4NN6jfCIG+On0YLRuB3IXGS1eOvgJXCZev//VeNq3IXHobIf1F/H65jg==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1770644791\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"code\":\"PARAM_ERROR\",\"detail\":{\"location\":\"body\",\"value\":41},\"message\":\"输入源“/body/batch_remark”映射到值字段“批次备注”字符串规则校验失败,字符数 41,大于最大值 32\"}"} +{"level":"debug","timestamp":"2026-02-09T21:48:08+08:00","caller":"kernel/baseClient.go:457","content":"POST https://api.mch.weixin.qq.com/v3/transfer/batches request header: { Content-Type:application/jsonAuthorization:WECHATPAY2-SHA256-RSA2048 mchid=\"1318592501\",nonce_str=\"wUX5RqmlbUUTEnuzRiD9FAFTFL9zPXLY\",timestamp=\"1770644888\",serial_no=\"4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5\",signature=\"w1YBlKTIo07vfIJbf4IvFf88QKaWXdOS9ulWxMzguvxb6bfgKNZQ1xLdOWlesI+b5KdJr9rpLDc2/7r6sZcqauKTH2mxxcW48VwPkNTzGfb7pqKsCcOHu3xpn6XR+lSPe/qEL4vyxwS83HLJhlRk32opXOFPp/g457D/DJn8X1QDnW0jngLug4SG/uu8J4vqZNGODPvsRyXQZZzPkGAJ3cVYuqLAywkaVxgwKjcB4dVz6PWm58EOakxN1wIkDUIIxkddFqkTg1z9zy3NoFagqwyNXDJ0K4VumBWt3yNThPA376RBF04noV0mrTXzRpylHGeKPp7TLTcEeJYmQUiRtg==\"Accept:*/*} request body:"} +{"level":"debug","timestamp":"2026-02-09T21:48:08+08:00","caller":"kernel/baseClient.go:459","content":"------------------response content:HTTP/1.1 400 Bad Request\r\nContent-Length: 207\r\nCache-Control: no-cache, must-revalidate\r\nConnection: keep-alive\r\nContent-Language: zh-CN\r\nContent-Type: application/json; charset=utf-8\r\nDate: Mon, 09 Feb 2026 13:48:08 GMT\r\nKeep-Alive: timeout=8\r\nRequest-Id: 0898CBA7CC06108803188AD2BCA80120B00B2890DB05-268435462\r\nServer: nginx\r\nWechatpay-Nonce: 28af031c95ea837f0ffb34c27b76c76d\r\nWechatpay-Serial: 5F2543BF58239A4EB68FA4433DF1438A88B34B16\r\nWechatpay-Signature: KtamVaPOVNlk+XuLtBcSUh9sq6B+QVPnupofCmLD95NF3z+uUsu2ia7tOXG6BR8oEOL6z/YVkJ9LmR8sQ/Kmx9/n3wlrQTYzWhesHUNNK/rkzXgefeYofh4LBZKlaaqjJ3PuCafyueBmrW4V6Vqt1XwSbrbLx4MLrR9t2qFrW0xG43Ru0ymA9hN7c0N/XTE/8V8Jl3BB1jJx24NlJr0T+RWEkzDOn54gzRJaGJTdDJYRQCOVterVYQPfMUxPvfIJbRi2/Fh1NXYESrgsq9gKPyc6S/oPgEBGyQXaY8LQDqQgA2NNrn1vVEOiOzvluF2l8CtCNo/RWwfBKmE0jZcj4A==\r\nWechatpay-Signature-Type: WECHATPAY2-SHA256-RSA2048\r\nWechatpay-Timestamp: 1770644888\r\nX-Content-Type-Options: nosniff\r\n\r\n{\"code\":\"PARAM_ERROR\",\"detail\":{\"location\":\"body\",\"value\":41},\"message\":\"输入源“/body/batch_remark”映射到值字段“批次备注”字符串规则校验失败,字符数 41,大于最大值 32\"}"}