微信支付(红包)接口的测试

发表于:2017-7-28 11:24

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:转瞬之间    来源:博客

  今天上午研究了一下微信支付的接口,发现网上转的大部分都是从微信支付接口文档上copy下来的,并没有任何实际的代码,因此写了一个微信的支付接口测试的小程序。
  调用微信支付接口其实主要需要两个部分,一个是需要证书,二是组织参数
  1.证书,在微信商户中将证书下载到测试机,注意的是,如果用.NET的话,一定要双击下载的证书并安装,否则后期调试接口的时候会报错,错误为:CA证书出错,请登录微信支付商户平台下载证书;
  2.组织参数的时候主要的就是签名的生成,其实只要按照接口文档的步骤,一个个写下来,是没有任何问题的,容易出错的是当参数有中文的时候,容易出现错误,错误为:签名错误
  下面是我写的主要的代码,以一段段的函数呈现:
  1.组织参数,以字典的结构存储参数:
  public string Create()
          {
              Dictionary<string, string> nativeObj = new Dictionary<string, string>();
              nativeObj.Add("nonce_str", "3857F5B380EA425B91D4DD3D5F5A6594");
              nativeObj.Add("mch_id", "商户号");
              nativeObj.Add("mch_billno",“自己按照接口文档写的”);
              nativeObj.Add("wxappid", "微信公众平台id");
              nativeObj.Add("nick_name", "自定义");
              nativeObj.Add("send_name", "自定义");
              nativeObj.Add("re_openid", "用户的openid");
              nativeObj.Add("total_amount", "100");
              nativeObj.Add("min_value", "100");
              nativeObj.Add("max_value", "100");
              nativeObj.Add("total_num", "1");
              nativeObj.Add("wishing", "感谢您参加猜灯谜活动,祝您元宵节快乐!");
              nativeObj.Add("client_ip", "本机的ip地址");
              nativeObj.Add("act_name", "猜灯谜抢红包活动 ");
              nativeObj.Add("remark", "猜越多得越多,快来抢!");
             //用来生成签名的方法,具体见下面
              string sign = GetSign(nativeObj);
              nativeObj.Add("sign", sign);
           //将参数组织成xml形式的字符串
              return ToXml(nativeObj);
          }
  2.生成签名:
  public string GetSign(Dictionary<string, string> nativeObj)
          {
              string sign = "";
              Dictionary<string, string> newobj = new Dictionary<string, string>();
              string temp = "";
             //参数的排序及去空
              var dicSort = from objDic in nativeObj where objDic.Value != "" orderby objDic.Key select objDic;
              foreach (var item in dicSort)
              {
                  if (temp != "")
                      temp += "&";
                  temp += item.Key + "=" + item.Value;
              }
              temp += "&key=api密钥";
             //MD5加密
              sign = StringToMD5(temp,32).ToUpper();
              return sign;
          }
   public  string StringToMD5(string str, int i)
          {
              //获取要加密的字段,并转化为Byte[]数组
              byte[] data = System.Text.Encoding.Unicode.GetBytes(str.ToCharArray());
              //建立加密服务
              System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
              //加密Byte[]数组
              byte[] result = md5.ComputeHash(data);
              //将加密后的数组转化为字段
              if (i == 16 && str != string.Empty)
              {
                  return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").ToLower().Substring(8, 16);
              }
              else if (i == 32 && str != string.Empty)
              {
                  return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").ToLower();
              }
              else
              {
                  switch (i)
                  {
                      case 16: return "000000000000000";
                      case 32: return "000000000000000000000000000000";
                      default: return "请确保调用函数时第二个参数为16或32";
                  }
              }
          }
  3. 将参数组织成要提交的数据
  public string ToXml(Dictionary<string, string> arr)
          {
              String xml = "<xml>";
              foreach (KeyValuePair<string, string> pair in arr)
              {
                  String key = pair.Key;
                  String val = pair.Value;
                  if (IsNumeric(val))
                  {
                      xml += "<" + key + ">" + val + "</" + key + ">";
                  }
                  else
                      xml += "<" + key + "><![CDATA[" + val + "]]></" + key + ">";
              }
              xml += "</xml>";
              return xml;
          }
  public bool IsNumeric(String str)
          {
              try
              {
                  int.Parse(str);
                  return true;
              }
              catch
              {
                  return false;
              }
          }
  4.模拟post请求提交
   public string Pay()
          {
              int dt = DateTime.Now.Millisecond;
              string url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
              string cert = @"D:\cert\apiclient_cert.p12";//这里是你存储证书的位置
              string password = "**********";//证书密码
              //这一段借鉴的是微信官方提供的DEMO
              ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
              X509Certificate cer = new X509Certificate(cert, password);
              HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url);
              webrequest.ClientCertificates.Add(cer);
              webrequest.Method = "post";
              webrequest.ContentType = "text/xml";
              //这一段是自己写的添加post数据的方法
              string postData = CreateNativePackage();
              StreamWriter myWriter = null;
              //// 要注意的这是这个编码方式,还有内容的Xml内容的编码方式
              //Encoding encoding = Encoding.GetEncoding("UTF-8");
              try
              {
                  myWriter = new StreamWriter(webrequest.GetRequestStream());
                  myWriter.Write(postData);
              }
              catch (Exception e)
              {
              }
              finally
              {
                  myWriter.Close();
              }
              HttpWebResponse webreponse = (HttpWebResponse)webrequest.GetResponse();
              Stream stream = webreponse.GetResponseStream();
              string resp = string.Empty;
              using (StreamReader reader = new StreamReader(stream))
              {
                  resp = reader.ReadToEnd();
              }
              string msg = resp;
                return msg;
          }
  private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
          {
              if (errors == SslPolicyErrors.None)
                  return true;
              return false;
          }

《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号