ASP.NET Core 微信支付(一)【统一下单 APIV3】

  • A+
所属分类:.NET技术
摘要

签名:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_0.shtml 统一下单接口:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_2_1.shtml


官方参考资料

签名:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_0.shtml

统一下单接口:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_2_1.shtml

首先声明,我这个是为APP支付提供的接口!!!

  一、签名

    生成签名

        参考资料里面讲的比较详细,也有官方的文档,不过文档不全,导致我的调试程序一直出现问题,请求微信的统一下单接口总是报400错误(Bad Request)。

      签名生成参考官方代码,代码如下,里面有我标注的请求接口报400错误原因的代码

using System; using System.IO; using System.Net.Http; using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks;  namespace HttpHandlerDemo {     // 使用方法     // HttpClient client = new HttpClient(new HttpHandler("{商户号}", "{商户证书序列号}"));     // ...     // var response = client.GetAsync("https://api.mch.weixin.qq.com/v3/certificates");     public class HttpHandler : DelegatingHandler     {         private readonly string merchantId;         private readonly string serialNo;          public HttpHandler(string merchantId, string merchantSerialNo)         {             InnerHandler = new HttpClientHandler();              this.merchantId = merchantId;             this.serialNo = merchantSerialNo;         }          protected async override Task<HttpResponseMessage> SendAsync(             HttpRequestMessage request,             CancellationToken cancellationToken)         {             var auth = await BuildAuthAsync(request);             string value = $"WECHATPAY2-SHA256-RSA2048 {auth}";             request.Headers.Add("Authorization", value);             request.Headers.Add("Accept", "application/json");//如果缺少这句代码就会导致下单接口请求失败,报400错误(Bad Request)             request.Headers.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");//如果缺少这句代码就会导致下单接口请求失败,报400错误(Bad Request)              return await base.SendAsync(request, cancellationToken);         }          protected async Task<string> BuildAuthAsync(HttpRequestMessage request)         {             string method = request.Method.ToString();             string body = "";             if (method == "POST" || method == "PUT" || method == "PATCH")             {                 var content = request.Content;                 body = await content.ReadAsStringAsync();//debug的时候在这里打个断点,看看body的值是多少,如果跟你传入的参数不一致,说明是有问题的,一定参考我的方法             }              string uri = request.RequestUri.PathAndQuery;             var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();             string nonce = Path.GetRandomFileName();              string message = $"{method}n{uri}n{timestamp}n{nonce}n{body}n";             string signature = Sign(message);             return $"mchid="{merchantId}",nonce_str="{nonce}",timestamp="{timestamp}",serial_no="{serialNo}",signature="{signature}"";         }          protected string Sign(string message)         {             // NOTE: 私钥不包括私钥文件起始的-----BEGIN PRIVATE KEY-----             //        亦不包括结尾的-----END PRIVATE KEY-----             string privateKey = "{你的私钥}";             byte[] keyData = Convert.FromBase64String(privateKey);             using (CngKey cngKey = CngKey.Import(keyData, CngKeyBlobFormat.Pkcs8PrivateBlob))             using (RSACng rsa = new RSACng(cngKey))             {                 byte[] data = System.Text.Encoding.UTF8.GetBytes(message);                 return Convert.ToBase64String(rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));             }         }     } }

  二、统一下单

    使用方法

 var url = "https://api.mch.weixin.qq.com/v3/pay/transactions/app";  var req = new GenerateOrderModelForWxPay                 {                     appid = WxPayConst.appid,                     mchid = WxPayConst.mchid,                     description = "商品名称",                     amount = new WxPayAmountModel                     {                         total = 1                     },                     out_trade_no = orderNumber,                     notify_url = "https://xxx.com/api/WxPayCallback"                 }; HttpClient client = new HttpClient(new HttpHandler("{商户号}", "{商户证书序列号}")); //GET 方式 var response = client.GetAsync("https://api.mch.weixin.qq.com/v3/certificates");  // POST 方式  var bodyJson = new StringContent(req.ToJson(), Encoding.UTF8, "application/json"); //一定要这样传递参数,不然在加密签名的时候获取到的参数就是\u0这种形式的数据了,不是传递的这样的数据了,导致加密的结果不正确 var response = await client.PostAsync(url, bodyJson);  // 读取统一下单之后的返回结果,这样读取出来的直接就是结果,或者错误原因,大家一定要这么搞啊!!!多么痛的领悟,会有具体的错误信息的。 var respStr = await resp.Content.ReadAsStringAsync();//这里面就包含prepay_id了

 三、注意

  大家一定看接口规则里面的说明,我就是没有看,导致我搞了一天没有搞通,下面贴两个截图

ASP.NET Core 微信支付(一)【统一下单 APIV3】

 

 ASP.NET Core 微信支付(一)【统一下单 APIV3】