编程语言
首页 > 编程语言> > C#微信开发,避雷,防踩坑总结

C#微信开发,避雷,防踩坑总结

作者:互联网

微信支付

1.首先下单接口,选择统一下单
微信统一下单接口:https://api.mch.weixin.qq.com/pay/unifiedorder

防踩雷:并不是JSAPI/小程序下单API https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi

2.微信接口中请求参数需带随机数、签名、签名类型

这是官网给出的
生成随机数算法
微信支付API接口协议中包含字段nonce_str,主要保证签名不可预测。我们推荐生成随机数算法如下:调用随机数函数生成,将得到的值转换为字符串。

16进制,32位随机生成的数
随机数算法代码:

 public static String GetNonceStr()
 {
        String symbols = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Random random = new SecureRandom();
        char[] nonceChars = new char[32];
        for (int index = 0; index < nonceChars.Length; ++index)
        {
              nonceChars[index] = Convert.ToChar(symbols.Substring((random.Next(symbols.Length)), 1));
        }
        return new String(nonceChars);
 }

按照官方给出的文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3

◆ 组合body参数

//设置package订单参数
SortedDictionary<string, string> dic = new SortedDictionary<string, string>();

dic.Add("appid", appid);
dic.Add("mch_id", StoreId);//财付通帐号商家
dic.Add("nonce_str", nonce_str);
dic.Add("trade_type", pay.tradeType());
dic.Add("attach", pay.attach());
dic.Add("openid", order.openid);
dic.Add("out_trade_no", order.out_trade_no);		//商家订单号
dic.Add("total_fee", order.total_fee.ToString()); //商品金额,以分为单位(money * 100).ToString()
dic.Add("notify_url", pay.notify_url());//接收财付通通知的URL
dic.Add("body", pay.body());//商品描述
dic.Add("spbill_create_ip", pay.addrIp());   //用户的公网ip,不是商户服务器IP

string get_sign = BuildRequest(dic, StoreSecret); //进行加密

在这个步骤里面,sign不加入加密

◆ 加密方法

public static string BuildRequest(SortedDictionary<string, string> sParaTemp, string key)
{
      //获取过滤后的数组
      Dictionary<string, string> dicPara = new Dictionary<string, string>();
      dicPara = FilterPara(sParaTemp);

      //组合参数数组
      string prestr = CreateLinkString(dicPara);
      //拼接支付密钥
      string stringSignTemp = prestr + "&key=" + key;

      //获得加密结果
      string myMd5Str = GetMD5(stringSignTemp);

      //返回转换为大写的加密串
      return myMd5Str.ToUpper();
}

◆ 通过ASCII码排序

/// <summary>
/// 除去数组中的空值和签名参数并以字母a到z的顺序排序
/// </summary>
/// <param name="dicArrayPre">过滤前的参数组</param>
/// <returns>过滤后的参数组</returns>
public static Dictionary<string, string> FilterPara(SortedDictionary<string, string> dicArrayPre)
{
      Dictionary<string, string> dicArray = new Dictionary<string, string>();
      foreach (KeyValuePair<string, string> temp in dicArrayPre)
      {
            if (temp.Key != "sign" && !string.IsNullOrEmpty(temp.Value))
            {
                  dicArray.Add(temp.Key, temp.Value);
            }
      }

      return dicArray;
}

◆ 组合参数数组

//组合参数数组
public static string CreateLinkString(Dictionary<string, string> dicArray)
{
      StringBuilder prestr = new StringBuilder();
      foreach (KeyValuePair<string, string> temp in dicArray)
      {
            prestr.Append(temp.Key + "=" + temp.Value + "&");
      }

      int nLen = prestr.Length;
      prestr.Remove(nLen - 1, 1);

      return prestr.ToString();
}

◆ MD5加密

 //加密
public static string GetMD5(string pwd)
{
      MD5 md5Hasher = MD5.Create();

      byte[] data = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(pwd));

      StringBuilder sBuilder = new StringBuilder();
      for (int i = 0; i < data.Length; i++)
      {
            sBuilder.Append(data[i].ToString("x2"));
      }

      return sBuilder.ToString();
}

以上就是生成sign的方法

在拼接参数加入sing,post请求

string _req_data = "<xml>";
_req_data += "<appid><![CDATA[" + appid + "]]></appid>";
_req_data += "<mch_id><![CDATA[" + StoreId + "]]></mch_id> ";
_req_data += "<nonce_str><![CDATA[" + nonce_str + "]]></nonce_str> ";
_req_data += "<trade_type><![CDATA[" + pay.tradeType() + "]]></trade_type> ";
_req_data += "<attach><![CDATA[" + pay.attach() + "]]></attach>";
_req_data += "<openid><![CDATA[" + order.openid + "]]></openid> ";
_req_data += "<out_trade_no><![CDATA[" + order.out_trade_no + "]]></out_trade_no> ";
_req_data += "<total_fee><![CDATA[" + order.total_fee.ToString() + "]]></total_fee> ";
_req_data += "<notify_url><![CDATA[" + pay.notify_url() + "]]></notify_url> ";
_req_data += "<body><![CDATA[" + pay.body() + "]]></body> ";
_req_data += "<spbill_create_ip><![CDATA[" + pay.addrIp() + "]]></spbill_create_ip> ";
_req_data += "<sign><![CDATA[" + get_sign + "]]></sign> ";
_req_data += "</xml>";


var rsultStr = client.PostAsync(url, new StringContent(_req_data, Encoding.UTF8, "application/x-www-form-urlencoded")).Result.Content.ReadAsStringAsync().Result;

微信退款

微信退款参数如上。

退款接口需要接入双向证书,证书需要在微信商户平台里面下载

string path = Path.Combine("", "path");

var cer = new X509Certificate2(path, StoreId);
handler.ClientCertificates.Add(cer);
var clientPost = new HttpClient(handler);
var rsultStr = clientPost.PostAsync(url, new StringContent(_req_data, Encoding.UTF8, "application/x-www-form-urlencoded")).Result.Content.ReadAsStringAsync().Result;

微信服务通知

◆ 需要在商户平台,服务通知添加通知模板,拿到模板ID

string send_url = $"https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={body.access_token}";
character_string1 character_string1 = new character_string1()
{ 
      value=body.sno
};
date2 date2 = new date2()
{
      value = DateTime.Now.ToString("f")
};

Data data = new Data()
{
      character_string1 = character_string1,
      date2 = date2,

};
FromBody from = new FromBody()
{
      access_token= body.access_token,
      touser=body.touser,
      page = "",
      miniprogram_state = "formal",//developer为开发版;trial为体验版;formal为正式版;默认为正式版
      template_id = "模板id",
      data=data
};
var json = JsonConvert.SerializeObject(from);

var clientPost = new HttpClient();
var rsultStr = clientPost.PostAsync(send_url, new StringContent(json, Encoding.UTF8, "application/x-www-form-urlencoded")).Result.Content.ReadAsStringAsync().Result;

实体类

public class Data
{
      public character_string1 character_string1 { get; set; }
      public date2 date2 { get; set; }
}

public class character_string1
{
      public string value { get; set; }
}

public class date2
{
      public string value { get; set; }
}

标签:string,避雷,微信,req,dic,C#,Add,new,data
来源: https://www.cnblogs.com/supreme-fee/p/14247101.html