收藏
评论

.NET 对接V3 接口

不知道为什么网上资料好少,有也是java的。 也不知道是不是我太菜了搞了一天才搞定,最后发现是被自己坑了。。。。借助于fiddler才找的问题。

A.  V3加密使用的是  SHA256-RSA 直接代码,我用的是p12直接解析。

// 1-  拼接待加密的字符串
 
                string timestamp = GetTimeStamp();//获取时间戳
 
            string body = "{\"stock_id\": \"\",\"out_request_no\": \"\",\"appid\": \"\",\"stock_creator_mchid\": \"\"\"coupon_value\": null,\"coupon_minimum\": null}";//这里只是一个例子
 
            string method = "POST";
 
            string apiurl = "/v3/marketing/favor/users/1211111/coupons";//
 
            string nonce_str = "3fefdfc321ba5bfb60849d8d0f4ebf08";//32位的随机字符串
 
            StringBuilder sbstrhead = new StringBuilder();
 
            sbstrhead.Append(method + "\n");
 
            sbstrhead.Append(apiurl + "\n");
 
            sbstrhead.Append(timestamp + "\n");
 
            sbstrhead.Append(nonce_str + "\n");
 
            sbstrhead.Append(body + "\n");  

 

          string pfxFilePath =@"F:\";

 

    // 2- 调用加密方法传入
 
 
 string signstr =SHA256Encrypt(sbstrhead.ToString(), pfxFilePath, "1234567");
 
       /// <summary>
 
        /// Allen -获取时间戳
 
        /// </summary>
 
        /// <returns></returns>
 
        public static string GetTimeStamp()
 
        {
 
            //生成1970年到现在的秒数
 
            TimeSpan timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1));
 
            //TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
 
            return Convert.ToInt64(timeSpan.TotalSeconds).ToString();
 
        }
 
 
  /// <summary>
 
        /// Allen - sha256签名带密钥
 
       /// </summary>
 
       /// <param name="data2">加密数据</param>
 
        /// <param name="pfxFilePath">P12对应的物理地址  @"F:\key\xxxxxx_cert.p12";</param>
 
       /// <param name="pwd">证书密码微信一般是商户号</param>
 
       /// <returns></returns>
 
        public static string SHA256Encrypt(string data2, string pfxFilePath,string pwd)      
 
 {
 
            X509Certificate2 privateCert = new X509Certificate2(pfxFilePath, pwd, X509KeyStorageFlags.Exportable);
 
            RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)privateCert.PrivateKey;
 
            // This one can:
 
            RSACryptoServiceProvider privateKey1 = new RSACryptoServiceProvider();
 
            privateKey1.ImportParameters(privateKey.ExportParameters(true));
 
            byte[] data = Encoding.UTF8.GetBytes(data2);
 
            byte[] signature = privateKey1.SignData(data, "SHA256");
 
            //密文
 
            string sign = Convert.ToBase64String(signature);
 
            return sign;
 
        }


B - 请求方法

//请求 Authorization 信息
var authormessage = "WECHATPAY2-SHA256-RSA2048 mchid=\"\",serial_no=\"\",nonce_str=\"" + nonce_str + "\",timestamp=\"" + timestamp + "\",signature=\"" + signstr + "\"";
 
/// <summary>
       /// Allen - POST V3 微信请求代码上叠加修正
       /// </summary>
       /// <param name="json"></param>
       /// <param name="url"></param>
       /// <param name="timeout"></param>
       /// <param name="encoding"></param>
       /// <param name="authormessage"></param>
       /// <param name="method"></param>
       /// <returns></returns>
        public static string PostV3(string json, string url, int timeout, Encoding encoding, string authormessage, string method)
        {
            System.GC.Collect();//垃圾回收,回收没有正常关闭的http连接
 
            string result = "";//返回结果
 
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            Stream reqStream = null;
 
            try
            {
                //设置最大连接数
                ServicePointManager.DefaultConnectionLimit = 200;
                //设置https验证方式
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
                    ServicePointManager.ServerCertificateValidationCallback =
                            new RemoteCertificateValidationCallback(CheckValidationResult);
                }
                
                /***************************************************************
                * 下面设置HttpWebRequest的相关属性
                * ************************************************************/
                request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
 
                request.Timeout = timeout * 1000;
 
                //设置代理服务器
                //WebProxy proxy = new WebProxy();                          //定义一个网关对象
                //proxy.Address = new Uri(WxPayConfig.PROXY_URL);              //网关服务器端口:端口
                //request.Proxy = proxy;
 
                //设置POST的数据类型和长度
                request.ContentType = "application/json";
                request.Accept = "application/json";
                request.UserAgent="Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36";
                request.Headers.Add("Authorization", authormessage);
                //request.
 
                byte[] data = System.Text.Encoding.UTF8.GetBytes(json);
                request.ContentLength = data.Length;
 
                //往服务器写入数据
                reqStream = request.GetRequestStream();
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();
 
                //获取服务端返回
                response = (HttpWebResponse)request.GetResponse();
              // WebResponse response2 = request.GetResponseAsync();
                //获取服务端返回数据
                StreamReader sr = new StreamReader(response.GetResponseStream(), encoding);
                result = sr.ReadToEnd().Trim();
                sr.Close();
                
            }
            catch (System.Threading.ThreadAbortException e)
            {
                System.Threading.Thread.ResetAbort();
            }
            catch (WebException e)
            {
                //这里有异常的这里最重要因为非200返回的时候这里可以知道什么原因
                response = (HttpWebResponse)e.Response;
                //获取服务端返回数据
                StreamReader sr = new StreamReader(response.GetResponseStream(), encoding);
                result = sr.ReadToEnd().Trim();
                sr.Close();
            }
            catch (Exception e)
            {
                throw new Exception(e.ToString());
            }
            finally
            {
                //关闭连接和流
                if (response != null)
                {
                    response.Close();
                }
                if (request != null)
                {
                    request.Abort();
                }
            }
 
            
 
            return result;
        }


希望能帮到某些人。

最后一次编辑于  11-17
赞 0
收藏