专栏名称: 51Testing软件测试网
51Testing软件测试网,人气最旺的软件测试技术门户,提供软件测试社区交流,软件测试博客,人才服务,测试沙龙,测试杂志,测试资料下载等全方位信息服务,是国内最专业的软件测试就业培训、企业服务供应商...
目录
相关文章推荐
51好读  ›  专栏  ›  51Testing软件测试网

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

51Testing软件测试网  · 公众号  · 测试  · 2017-08-03 17:30

正文


  今天上午研究了一下微信支付的接口,发现网上转的大部分都是从微信支付接口文档上copy下来的,并没有任何实际的代码,因此写了一个微信的支付接口测试的小程序。

  调用微信支付接口其实主要需要两个部分,一个是需要证书,二是组织参数

  1.证书,在微信商户中将证书下载到测试机,注意的是,如果用.NET的话,一定要双击下载的证书并安装,否则后期调试接口的时候会报错,错误为:CA证书出错,请登录微信支付商户平台下载证书;

  2.组织参数的时候主要的就是签名的生成,其实只要按照接口文档的步骤,一个个写下来,是没有任何问题的,容易出错的是当参数有中文的时候,容易出现错误,错误为:签名错误

  下面是我写的主要的代码,以一段段的函数呈现:

  1.组织参数,以字典的结构存储参数:

  public string Create()

  {

  Dictionary nativeObj = new Dictionary();

  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 nativeObj)

  {

  string sign = "";

  Dictionary newobj = new Dictionary();

  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 arr)

  {

  String xml = "";

  foreach (KeyValuePair pair in arr)

  {

  String key = pair.Key;

  String val = pair.Value;

  if (IsNumeric(val))

  {

  xml += "" + val + "" + key + ">";

  }

  else

  xml += "" + key + ">";

  }

  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;

  }

 
推荐阅读

点击阅读☞通用接口测试用例设计

点击阅读☞软件测试工程师必知必会:如何做好接口测试

点击阅读☞测试女巫之接口测试篇

点击阅读☞Python自动化测试番外篇—接口测试

点击阅读☞基于Python的接口测试框架实例


点击左下角“阅读原文”,查看全文内容
推荐文章
咱是闽南人  ·  医院内部视频,不忍直视..
7 年前
营销兵法  ·  顾客老说贵、贵、贵......怎么办?
7 年前
互联网十体育  ·  2亿美元“贫富鸿沟”,NBA怎么填补
7 年前