fudiwei / DotNetCore.SKIT.FlurlHttpClient.Wechat

可能是全网最完整的 C# 版微信 SDK,封装全部已知的微信 OpenAPI,包含微信公众平台(订阅号+服务号+小程序+小游戏+小商店+视频号)、微信开放平台、微信商户平台(微信支付+微企付)、企业微信、微信广告平台、微信智能对话开放平台等模块,可跨平台。持续随官方更新,欢迎 Star/Fork/PR。QQ 交流群 875580418【满】、930461548【满】、611974621。
https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient
MIT License
1.47k stars 285 forks source link

SKIT.FlurlHttpClient.Wechat.TenpayV3 3.2.0 以上版本 Native 下单接口 下单失败 #145

Closed taoranxy closed 2 months ago

taoranxy commented 2 months ago

关于问题的简单描述

SKIT.FlurlHttpClient.Wechat.TenpayV3 升级3.2.0以上版本后,提示下单失败,将其降回3.2.0及以下时,可正常调用。


与问题相关的源代码

        /// <summary>
        /// 微信PC端下单
        /// </summary>
        /// <param name="description">商品描述</param>
        /// <param name="order">本地订单</param>
        /// <returns></returns>
        public async Task<Result<CreatePayTransactionNativeResponse>> WeChatCreatePayTransactionNative(string description, Order order)
        {
            var merchantId = _tenpayOptions.Merchants.FirstOrDefault()?.MerchantId;

            if (string.IsNullOrWhiteSpace(merchantId)) return new Result<CreatePayTransactionNativeResponse>("未查询到配置");

            var client = _tenpayHttpClientFactory.Create(merchantId);

            var request = new CreatePayTransactionNativeRequest()
            {
                OutTradeNumber = order.Number,
                AppId = _tenpayOptions.GZHAppId,
                Description = description,
                NotifyUrl = _tenpayOptions.NotifyUrl,
                Amount = new CreatePayTransactionNativeRequest.Types.Amount() { Total = (int)(order.ActualPayment * 100) }
            };
            var response = await client.ExecuteCreatePayTransactionNativeAsync(request, cancellationToken: _httpContextAccessor.HttpContext.RequestAborted);

            if (!response.IsSuccessful())
            {
                await Log.AddOperationalLog(GetUserId(), GetUserName(), "微信订单下单失败", $"JSAPI 下单失败(状态码:{response.GetRawStatus()},错误代码:{response.ErrorCode},错误描述:{response.ErrorMessage})。");

                return new Result<CreatePayTransactionNativeResponse>("微信端下单失败,请联系管理员");
            }

            return new Result<CreatePayTransactionNativeResponse>(response);
        }

异常堆栈或异常原因

JSAPI 下单失败(状态码:400,错误代码:PARAM_ERROR,错误描述:输入源“/body/scene_info/payer_client_ip”映射到字段“用户终端IP”必填性规则校验失败,此字段为必填项)。


fudiwei commented 2 months ago

首先你调用的是 Native 下单接口,而不是 JSAPI 下单接口。

其次根据官方文档,这个字段是必填的:

REF: https://pay.weixin.qq.com/docs/merchant/apis/native-payment/direct-jsons/native-prepay.html image

taoranxy commented 2 months ago

写记录日志的时候搞错了,是调用的 Native 下单接口,我也查了官方的文档,之前的版本(3.2.0及以前)是可以正常调用并且返回支付链接参数code_url的,可能是之前的版本有为此属性赋值

taoranxy commented 2 months ago

我仔细查询了微信支付的官方文档,属性 payer_client_ip 是在 scene_info 参数下的,scene_info是选填参数,但模型 CreatePayTransactionNativeRequest 在初始化的时候会创建 Scene(即scene_info),不同的是 3.2.0以后的版本未对 ClientIp(即 payer_client_ip)进行赋值,导致下单失败 image image

fudiwei commented 2 months ago

我仔细查询了微信支付的官方文档,属性 payer_client_ip 是在 scene_info 参数下的,scene_info是选填参数,但模型 CreatePayTransactionNativeRequest 在初始化的时候会创建 Scene(即scene_info),不同的是 3.2.0以后的版本未对 ClientIp(即 payer_client_ip)进行赋值,导致下单失败 image image

后续会将 scene_info 初值设为空。暂时可手动强制赋值为 null。

payer_client_ip 空字符串也能正常下单的问题已向官方反馈,后续应该会修复,建议按照规则传递正确的 IP 地址。

image

ZhangYiQiu commented 2 months ago

首先你调用的是 Native 下单接口,而不是 JSAPI 下单接口。

其次根据官方文档,这个字段是必填的:

REF: https://pay.weixin.qq.com/docs/merchant/apis/native-payment/direct-jsons/native-prepay.html image

image 这里的类型应该是可为空类型,不然因为你传递了scene_info字段,微信就会校验内部的payer_client_ip字段了

image 微信文档里scene_info字段也是非必填的