微信支付官方给出的解决方案
自己看吧,这个是最基本的问题排查,不赘述,上链接 官方解决方案 ↓↓↓↓↓↓↓↓
一定会往这里看的,如果上面的就已经解决了,说明也太不认真了。
以下的方案包含网上和微信官网给出的一些方案总结,自己亲测可用
常见问题
端口问题
阿里云、腾讯云、天翼云等各种云服务器或者自己的服务器防火墙请确认是否开启了25端口。这个是很多人会忽略的。
具体开房的地址参考微信支付官方文档文档地址最下面的第三点
权限问题
开发webapi的时候经常会在基类里面做了鉴权认证,导致回调接口也继承了基类的鉴权,所以请把回调地址设置为所有人都可以访问,无需鉴权。
配置问题
在商户上配置授权地址的时候一定是以 /
结束的。比如 https://aaa.com/
回调地址尽量保持为 https://aaa/com/回调方法,不要在增加深层目录
错误示范: https://aaa.com/api/v2/回调方法
备注:没有验证过错误示范的是否能够可以,但是正确示例一定可以。
webapi的配置问题
以.netcore为例
.netcore 默认是支持context-type:json/application格式的。
但是微信支付V2版本的回调函数是以xml方式回调的,所以请配置webapi支持xml的解析。
参考代码
using Microsoft.AspNetCore.Mvc.Formatters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace Light.PhoneNumber.WebApi
{
public class ResultTextFormatter : TextInputFormatter
{
public ResultTextFormatter()
{
SupportedMediaTypes.Insert(0, "text/plain");
SupportedMediaTypes.Insert(0, "text/xml");
SupportedEncodings.Add(Encoding.UTF8);
SupportedEncodings.Add(Encoding.Default);
SupportedEncodings.Add(Encoding.Unicode);
}
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
{
using (var reader = context.ReaderFactory(context.HttpContext.Request.Body, encoding))
{
var stringContent = await reader.ReadToEndAsync();
var type = context.ModelType;
var contextType = context.HttpContext.Request.ContentType;
if (contextType == "text/plain")
{
return await Deserialize(stringContent, type);
}
else if (contextType == "text/xml" || context.HttpContext.Request.Path.Value.ToLower().Contains("/payed"))
{
return await DeserializeXML(stringContent, type);
}
return await InputFormatterResult.FailureAsync();
}
}
public static async Task<InputFormatterResult> DeserializeXML(string xml, Type type)
{
using (var reader = new StringReader(xml))
{
var serializer = new XmlSerializer(type, new XmlRootAttribute("xml"));
var result = serializer.Deserialize(reader);
return await InputFormatterResult.SuccessAsync(result);
}
}
private static async Task<InputFormatterResult> Deserialize(string stringContent, Type type)
{
var result = JsonConvert.DeserializeObject(stringContent, type);
return await InputFormatterResult.SuccessAsync(result);
}
}
}
Startup.cs
services.AddMvc(config =>
{
config.InputFormatters.Add(new ResultTextFormatter());
config.Filters.Add<LogFilter>();
}
);
.netcore3.0+版本不支持同步导致无法回调
因为上一个问题的写法导致不支持同步会回调异常
处理办法
services.Configure<KestrelServerOptions>(x => x.AllowSynchronousIO = true)
.Configure<IISServerOptions>(x => x.AllowSynchronousIO = true);