微信异步通知:

  1. [AcceptVerbs("POST")]
  2. public void Notify()
  3. {
  4. //编码(101-登录无效,102-账号无效,200-成功,201-失败,202~299-其他原因1-99,300-无效提交方式,400-无效参数)
  5. MessagesDataCodeModel json = new MessagesDataCodeModel(false, "无效参数", 401);
  6. int notify_id = 0;
  7. string result = "failed";
  8. try
  9. {
  10. //得到微信推送来的xml数据
  11. Stream s = System.Web.HttpContext.Current.Request.InputStream;
  12. byte[] b = new byte[s.Length];
  13. s.Read(b, 0, (int)s.Length);
  14. string postStr = Encoding.UTF8.GetString(b);
  15.  
  16. SortedDictionary<string, string> requestXML = Common.TenpayUtil.GetInfoFromXml(postStr);
  17. if (requestXML != null && requestXML.Count > 0)
  18. {
  19. Models.WeiXinNotifyRecords model = GetNotifyModel(requestXML);//将xml数据转换为Model
  20. model.remark = "";//postStr;
  21. model.CreateDate = DateTime.Now;
  22. notify_id = WeiXinNotifyRecordsBLL.Append(model);//记录微信通知
  23. model.ID = notify_id;
  24.  
  25. #region 验签
  26. //微信返回的签名字符串
  27. string sign = requestXML["sign"];
  28. requestXML.Remove("sign");
  29. //待签名字符串
  30. string signStr = AlipaySignature.GetSignContent(requestXML) + "&key=" + Common.ConfigApi.WeiXinPay_API_Key;//借用阿里的方法
  31. string newsign = Utils.GetMD5(signStr).ToUpper();//MD5加密,转大写
  32. bool ValidateSign = sign == newsign;//验证签名是否一致
  33. #endregion
  34.  
  35. #region 处理订单
  36. if (ValidateSign)
  37. {
  38. Models.TradeInfo tradeInfo = TradeInfoBLL.GetEntityByTradeNo(model.out_trade_no);
  39. if (tradeInfo != null && model.appid == ConfigApi.WeiXinPay_App_app_id && model.mch_id == ConfigApi.WeiXinPay_App_mch_id)
  40. {
  41. result = "success";//TODO:处理订单逻辑,完成后 result="success"
  42. }
  43. else
  44. {
  45. result = "TradeError";
  46. logger.Error("WeiXinPayController.Notify【订单数据与通知数据不符】");
  47. }
  48. }
  49. else
  50. {
  51. result = "CheckSignError";
  52. logger.Error("WeiXinPayController.Notify【验签失败】");
  53. }
  54. #endregion
  55. }
  56. }
  57. catch (Exception ex)
  58. {
  59. logger.Error("WeiXinPayController.Notify【程序异常】", ex);
  60. result = "exception";
  61. }
  62.  
  63. string xmlstr = @"<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
  64. if (result != "success")
  65. {
  66. xmlstr = @"<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[FAIL]]></return_msg></xml>";
  67. }
  68. HttpContext.Current.Response.Write(xmlstr);
  69. HttpContext.Current.Response.End();
  70. }

  

把XML数据转换为SortedDictionary<string, string>集合:

  1. /// <summary>
  2. /// 把XML数据转换为SortedDictionary<string, string>集合
  3. /// </summary>
  4. /// <param name="strxml"></param>
  5. /// <returns></returns>
  6. public static SortedDictionary<string, string> GetInfoFromXml(string xmlstring)
  7. {
  8. SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
  9. try
  10. {
  11. XmlDocument doc = new XmlDocument();
  12. doc.LoadXml(xmlstring);
  13. XmlElement root = doc.DocumentElement;
  14. int len = root.ChildNodes.Count;
  15. for (int i = 0; i < len; i++)
  16. {
  17. string name = root.ChildNodes[i].Name;
  18. if (!sParams.ContainsKey(name))
  19. {
  20. sParams.Add(name.Trim(), root.ChildNodes[i].InnerText.Trim());
  21. }
  22. }
  23. }
  24. catch { }
  25. return sParams;
  26. }

  

把参数排序后拼接,得到签名字符串:

  1. public static string GetSignContent(IDictionary<string, string> parameters)
  2. {
  3. // 第一步:把字典按Key的字母顺序排序
  4. IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
  5. IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();
  6.  
  7. // 第二步:把所有参数名和参数值串在一起
  8. StringBuilder query = new StringBuilder("");
  9. while (dem.MoveNext())
  10. {
  11. string key = dem.Current.Key;
  12. string value = dem.Current.Value;
  13. if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
  14. {
  15. query.Append(key).Append("=").Append(value).Append("&");
  16. }
  17. }
  18. string content = query.ToString().Substring(0, query.Length - 1);
  19.  
  20. return content;
  21. }

  

签名算法文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3

微信App支付通知验签的更多相关文章

  1. 支付宝支付集成中:refund_fastpay_by_platform_nopwd接口服务器通知验签不通过

    在做p2p配资平台,也就是公司的项目,遇到了一个问题:refund_fastpay_by_platform_nopwd接口服务器通知验签不通过 下面是实录: 通知服务器的POST过来的数据: 1.si ...

  2. 微信支付-微信公众号支付,微信H5支付,微信APP支付,微信扫码支付

    在支付前,如果使用第三方MVC框架,则使用重写模式,服务器也需要配置该项 if (!-e $request_filename){ rewrite ^/(.*)$ /index.php/$ last; ...

  3. 微信app支付 ci框架做的

    /**     * 组合微信app支付  获得prepayid     * @param int $order_num     */    private function _wxpay_reques ...

  4. .net 微信APP支付接口的开发流程以及坑

    流程 申请APP的微信支付 申请成功之后得到APPID 商户号 以及自己设置商户号的支付密码 这时就可以开发接口了 微信APP支付API:https://pay.weixin.qq.com/wiki/ ...

  5. 微信app支付android客户端以及.net服务端实现

    由于公司运营需要,需要在客户端(android/ios)增加微信以及支付宝支付,在调用微信app支付时遇到一些问题,也算是一些踩过的坑,记录下来 ,希望能对.net开发者服务端网站更快的集成微信app ...

  6. php开发微信APP支付接口

    之前在开发APP中用到了微信支付,因为是第一次用,所以中途也遇到了好多问题,通过查看文档和搜集资料,终于完成了该功能的实现.在这里简单分享一下后台php接口的开发实例. 原文地址:代码汇个人博客 ht ...

  7. Android版-微信APP支付

    首发地址: Android版-微信APP支付 欢迎留言.转发 微信极速开发系列文章(微信支付.授权获取用户信息等):点击这里 目录 1.注册账号.开发者认证 2.添加应用 3.申请微信支付 4.技术开 ...

  8. 微信APP支付 - C#

    最近挺忙的,没时间写东西.然后在弄微信APP支付,网上的搜索一趟,都比较凌乱,我也遇到一些坑,不过也算弄好了,记录分享一下. 1.准备各种调用接口需要的参数,配置app.config. <!-- ...

  9. 微信APP支付整体流程记录备忘

      支付整体流程见文档:https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_3   商户系统和微信支付系统主要交互说明:     步骤1: ...

随机推荐

  1. js中的三元运算符

    <script type="text/javascript"> var b=5; (b == 5) ? a="true" : a="fal ...

  2. 使用archlinux作为日常开发机已经半年了,随便写一下

    机器配置 CPU: Intel Core i5-6200U CPU @ 2.8GHz RAM: 6114MiB / 7421MiB Resolution: 1920x2160 在arch下常用的软件 ...

  3. 高级php面试题(转)

    一.mysql相关知识    1. mysql优化方式            MYSQL 优化常用方法            mysql 性能优化方案      2.如何分库分表            ...

  4. arguments转换为数组格式

    var agArr = []; for(var i = 0; i < arguments.length; i++) { agArr.push(arguments[i]) }

  5. 41个Web开发者JavaScript实用小技巧

    1. 将彻底屏蔽鼠标右键 oncontextmenu="window.event.returnValue=false" < table border oncontextmen ...

  6. 4、Python:strip(),split()

    1.strip()函数 strip()是删除'()'里面的字符,当()为空时,默认删除空白符(包括'\n','\r','\t','') (1)s.strip(rm)        删除s字符串中开头. ...

  7. c#-基础:类的进阶

    类的概述: 类是一个能存储数据并执行代码的数据结构 数据成员:通常模拟该类所表示显示世界的事物特性 函数成员:执行代码.模拟显示世界事物的功能和操作 数据成员:字段,常量 函数成员执行代码:方法 运算 ...

  8. 应用EF访问SQLite数据

    创建项目,应用EF访问SQLite 1.创建项目 项目结构初始结构如下图所示,Netage.Data.SQLite 类库项目用于定义访问数据的接口和方法,Netage.SQLiteTest.UI 控制 ...

  9. JavaScript的eval函数

    eval() 函数可将字符串转换为代码执行,并返回一个或多个值 函数原型为: 返回值 = eval( codeString ) 函数说明: 如果eval函数在执行时遇到错误,则抛出异常给调用者. 类似 ...

  10. 查询数据库最大id加1

    SELECT ISNULL(MAX(id),0)+1 AS MaxId FROM TABLE ISNULL(MAX(id),0) 就是如果id为空 就返回0,然后再加1