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

今天上午研究了一下微信支付的接口,发现网上转的大部分都是从微信支付接口文档上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;
        }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值