{"record":{"id":"6c8609df995350f9","repo":"JeffreySu/WeiXinMPSDK","slug":"nameof-data-type-order-paid-nameof-data-detail","errorCode":null,"errorMessage":"{nameof(data.type)}为'Order_Paid'与{nameof(data.detail)}","messagePattern":"(.+?)为'Order_Paid'与(.+?)","errorType":"validation","errorClass":"TenpayApiRequestException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Apis/PayScore/PayScoreApis.cs","lineNumber":302,"sourceCode":"            var url = ReurnPayApiUrl($\"{Senparc.Weixin.Config.TenPayV3Host}/{{0}}v3/payscore/serviceorder/{data.out_order_no}/pay\");\n            TenPayApiRequest tenPayApiRequest = new(_tenpayV3Setting);\n            return await tenPayApiRequest.RequestAsync<PayServiceOrderReturnJson>(url, data, timeOut);\n        }\n\n        /// <summary>\n        /// 同步服务订单信息接口\n        /// <para>由于收款商户进行的某些“线下操作”会导致微信支付侧的订单状态与实际情况不符。例如，用户通过线下付款的方式已经完成支付，而微信支付侧并未支付成功，此时可能导致用户重复支付。因此商户需要通过订单同步接口将订单状态同步给微信支付，修改订单在微信支付系统中的状态。</para>\n        /// <para>特别说明：待支付（USER_PAYING）状态下，当用户正在尝试通过收银台主动支付订单金额时，同步服务订单信息API无法调用成功，可等待3min后重试</para>\n        /// <para>更多详细请参考 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter6_1_20.shtml </para>\n        /// </summary>\n        /// <param name=\"data\">微信支付需要POST的Data数据</param>\n        /// <param name=\"timeOut\">超时时间，单位为ms</param>\n        /// <returns></returns>\n        public async Task<SyncPayServiceOrderReturnJson> SyncPayServiceOrderAsync(SyncPayServiceOrderRequestData data, int timeOut = Config.TIME_OUT)\n        {\n            if (data.type == \"Order_Paid\" && data.detail is null)\n            {\n                throw new TenpayApiRequestException($\"{nameof(data.type)}为'Order_Paid'与{nameof(data.detail)}\");\n            }\n\n            var url = ReurnPayApiUrl($\"{Senparc.Weixin.Config.TenPayV3Host}/{{0}}v3/payscore/serviceorder/{data.out_order_no}/sync\");\n            TenPayApiRequest tenPayApiRequest = new(_tenpayV3Setting);\n            return await tenPayApiRequest.RequestAsync<SyncPayServiceOrderReturnJson>(url, data, timeOut);\n        }\n\n\n        #endregion\n\n        #region 支付即服务\n\n        /// <summary>\n        /// 服务人员注册接口\n        /// <para>用于商户开发者为商户注册服务人员使用。</para>\n        /// <para>注意：调用接口前商家需完成支付即服务产品的开通和设置。若服务商为特约商户调用接口，需在特约商户开通并完成产品设置后，与特约商户建立产品授权关系。</para>\n        /// <para>更多详细请参考 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_4_1.shtml </para>\n        /// </summary>","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.TenPay/Senparc.Weixin.TenPayV3/Apis/PayScore/PayScoreApis.cs#L284-L320","documentation":"SyncPayServiceOrderAsync (PayScoreApis.cs:302) syncs payment state to a Pay Score service order. When data.type is \"Order_Paid\" (order paid), WeChat requires data.detail (payment details) to accompany the request. The library throws TenpayApiRequestException when type is Order_Paid but detail is null; the message is a truncated/awkward phrasing meaning \"when type is 'Order_Paid', detail is required\".","triggerScenarios":"Calling SyncPayServiceOrderAsync with SyncPayServiceOrderRequestData.type == \"Order_Paid\" while leaving data.detail null.","commonSituations":"Reusing a request builder for other sync types (e.g. REVOKED) where detail isn't needed and then switching to Order_Paid; forgetting to attach the payment detail (paid time, paid channel etc.) after handling the payment callback.","solutions":["Populate data.detail with the payment details (detail.payment_information etc.) whenever type is Order_Paid","If no payment detail is available, use the appropriate non-paid sync type instead of Order_Paid","Validate type/detail pairing before calling SyncPayServiceOrderAsync"],"exampleFix":"// before\nvar data = new SyncPayServiceOrderRequestData {\n    out_order_no = orderNo,\n    type = \"Order_Paid\"          // detail missing\n};\n\n// after\ndata.detail = new Detail {\n    payment_information = new PaymentInformation { ... }\n};","handlingStrategy":"validation","validationCode":"if (data.type == \"Order_Paid\" && data.detail == null)\n    throw new InvalidOperationException(\"detail is required when type is Order_Paid\");","typeGuard":"bool SyncRequestValid(SyncPayServiceOrderRequestData d) =>\n    d.type != \"Order_Paid\" || d.detail != null;","tryCatchPattern":"try { await api.SyncPayServiceOrderAsync(data); }\ncatch (TenpayApiRequestException ex) when (ex.Message.Contains(\"Order_Paid\"))\n{ logger.LogError(ex, \"Order_Paid sync sent without detail\"); throw; }","preventionTips":["Attach payment detail immediately when constructing Order_Paid sync requests","Map WeChat payment-callback data into detail in the same code path that sets type","Cover both sync types in unit tests"],"tags":["tenpay","payscore","validation","sync"],"backgroundTag":"missing-required-argument","analyzedSha":"be573f6f94bdbf718dd5f6cdecb137fbc7ff651e","analyzedAt":"2026-09-12T10:01:50.733Z","contentChangedAt":"2026-09-12T10:01:50.733Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}