精华内容
下载资源
问答
  • C#微信公众号支付接口对接

    千次阅读 2017-06-09 16:31:57
    最近做了一次公众号支付接口,跟大家分享一下思路,避免走弯路

    这次是第二次对接微信公众号的支付了,第一次代码写的很乱,没有找现成的SDK,感觉里面乱七八糟的东西太多不够清爽,而我仅仅是做一个小功能,对接又不复杂干脆自己做。

    不想重复做轮子的朋友可以参考一下:Senparc C# SDK  

    这里我只说一下公众号内支付,APP以及其他的支付,等我以后用得到的时候再总结。

    简单的说对接过程分为4步

    1、拿到用户的openid
    2、使用微信接口下单获取preorder_id
    3、前端H5调用微信支付对话框
    4、接收微信支付结果的通知

    好了,现在开始具体过程介绍


    0.公众号信息准备

    1、公众号的appid,appsecret
    登录微信公众平台,在开发一栏里找到基本配置

    这里写图片描述

    这里写图片描述

    2、微信支付平台的商户id(mch_id), 支付key(这个是自己设置的)



    1.获取用户openid

    每个用户在公众号里都有一个唯一的openid,公众号可以通过openid获取用户的信息,当然获取用户信息是需要用户同意的。但是只获取openid不需要用户同意。

    这里没提到的内容可以参考官方文档,:微信网页授权

    要获取openid,首先要获取code,然后根据code获取openid。这个过程是为了要用户授权,也就是下面的绿色页面。

    获取code跳转到这个链接:
    https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

    参数
    appid:是公众号的唯一标识
    redirect_uri:是授权后重定向的回调链接地址,请使用urlEncode对链接进行处理
    response_type:返回类型,请填写code
    scope:是应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
    state:否 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节
    #wechat_redirect 是 无论直接打开还是做页面302重定向时候,必须带此参数

    在这里我们scope参数使用snsapi_base,使用snsapi_userinfo 会弹出绿色页面,但是结果是一样的。

    这里写图片描述

    如果没出错的话,页面会跳转到指定的redirect_uri页面,并附带上code和state参数。

    获取code后,请求以下链接获取access_token:
    https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

    参数
    appid:公众号的唯一标识
    secret:公众号的appsecret
    code:填写第一步获取的code参数
    grant_type:填写authorization_code

    正确时返回的JSON数据包如下

    { "access_token":"ACCESS_TOKEN",    
     "expires_in":7200,    
     "refresh_token":"REFRESH_TOKEN",    
     "openid":"OPENID",    
     "scope":"SCOPE" } 

    看到这里面的openid这个参数没?这时就可以取用了,获取到的refresh_token可以保存起来,以后直接用refresh_token获取openid。


    2.获取prepay_id

    使用微信公众号支付必须在微信留个案底,需要把订单信息提交给微信,这时候就需要使用统一下单接口,官方文档

    处于安全角度,使用这个接口需要对传输的信息加密,为了避免篡改,需要用到支付key,过程是这样的:
    1、生成一个随机数:32位,可以创建一个Guid。
    2、生成安全签名:把提交到微信的参数按照首字母字典排序(a-z),编辑成key=value&key=value…的形式,然后末尾加上key,用md5加个密。
    3、创建提交的xml
    4、使用post提交到微信接口


    · 把要传的参数使用字典排序(除了sign):

    SortedDictionary<String, String> param = new SortedDictionary<string, string>();
    param.Add("appid", appid);
    param.Add("attach", attach);
    param.Add("body", body);
    param.Add("mch_id", config.mchid);
    param.Add("nonce_str", Guid.NewGuid().ToString().Replace("-", "").ToUpper());
    param.Add("notify_url", notifyurl);
    param.Add("openid", openid);
    param.Add("out_trade_no", orderno);
    param.Add("spbill_create_ip", System.Web.HttpContext.Current.Request.UserHostAddress);
    param.Add("total_fee", ((Int32)(price * 100)).ToString());
    param.Add("trade_type", "JSAPI");

    · 参数生成字符串

    private String GetUnEncyptKey(SortedDictionary<String, String> sort)
     {
          List<String> lstParam = new List<String>();
          foreach (var item in sort)
          {
              lstParam.Add(String.Format("{0}={1}", item.Key, item.Value));
          }
          return String.Join("&", lstParam);
    }

    · MD5加密

    /// <summary>
    /// 签名字符串
    /// </summary>
    /// <param name="prestr">需要签名的字符串</param>
    /// <param name="key">密钥</param>
    /// <param name="_input_charset">编码格式</param>
    /// <returns>签名结果</returns>
    public static string Sign(string prestr, string key, string _input_charset)
    {
         StringBuilder sb = new StringBuilder(32);
         prestr = prestr +"&key="+ key;
         MD5 md5 = new MD5CryptoServiceProvider();
         byte[] t = md5.ComputeHash(Encoding.GetEncoding(_input_charset).GetBytes(prestr));
         for (int i = 0; i < t.Length; i++)
         {
             sb.Append(t[i].ToString("x").PadLeft(2, '0'));
         }
         return sb.ToString();
    }

    · 把刚才生成的sign加入到SortedDictionary中然后生成xml:

    param.Add("sign", "签名值");
    /// <summary>
    /// 把提交的参数参数转换为xml
    /// </summary>
    /// <param name="requestInfo"></param>
    /// <returns></returns>
    public static String GetPostXML(SortedDictionary<String, String> requestInfo)
    {
        List<String> xml = new List<String>();
        xml.Add("<xml>");
        SortedDictionary<String, String> post_param = ExcludeEmpty(requestInfo);
        foreach (var item in post_param)
        {
            if (item.Key == "detail")
            {
                xml.Add(String.Format("<{0}><![CDATA[{1}]]</{0}>", item.Key, item.Value));
            }
            else {
                xml.Add(String.Format("<{0}>{1}</{0}>", item.Key, item.Value));
            }
        }
        xml.Add("</xml>");
        return String.Join("", xml);
        }

    (微信的detail 是使用CDATA防止xml转义的,其他参数不能采用)

    好了,把XML使用POST提交到接口吧,地址是:https://api.mch.weixin.qq.com/pay/unifiedorder

    返回结果也是xml的,可以返序列化。使用这段代码可以直接反序列化成实体类:

    /// <summary>
    /// 反序列化xml
    /// </summary>
    /// <param name="xml">XML字符串</param>
    /// <returns></returns>
    public static T Deserialize<T>(string xml)
    {
        try
        {
            String typename=typeof(T).Name;
            xml = xml.Replace("<xml>", "<" + typename + ">").Replace("</xml>", "</" + typename + ">");
            using (StringReader sr = new StringReader(xml))
            {
                XmlSerializer xmldes = new XmlSerializer(typeof(T));
                return (T)xmldes.Deserialize(sr);
            }
        }
         catch (Exception e)
        {
            return default(T);
        }
    }

    好了,正常情况下就可以获取到prepay_id了。


    3.前端H5调用微信支付对话框

    请参考官方文档

    对接过统一下单接口,这个过程就很简单了。按照这个文档做就好了。这里的随机字符串和签名都是重新生成的,生成方式和前面说的一样。

    前端页面JS:

    function onBridgeReady() {
        WeixinJSBridge.invoke(
            'getBrandWCPayRequest', {
                "appId": "wx8888888888888888",     //公众号名称,由商户传入     
                "timeStamp": "1414561699",         //时间戳,自1970年以来的秒数     
                "nonceStr": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS", //随机串     
                "package": "prepay_id=123456789",
                "signType": "MD5",         //微信签名方式:     
                "paySign": "C380BEC2BFD727A4B6845133519F3AD6" //微信签名 
        },
        function (res) {
            if (res.err_msg == "get_brand_wcpay_request:ok") {
               //支付成功,后续自行处理
            }
            else
            {
                //支付取消,或者其他错误,自行处理
            }
        });
    }

    好了,到现在支付就完成了,下面还需要获取一下支付通知,最终确认一下支付状态。


    4.接收支付通知

    请自行阅读一下,官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7

    简单说明一下文档中return_code 和result_code 分别表示通信结果和业务(支付)执行结果。收到参数后自己记录一下信息,尤其是支付单号transaction_id,然后再按照约定格式返回一个xml表示成功就可以了。

    必须要注意的是,一定要对收到的参数进行签名,验证收到的消息来源是否来自微信,千万不可懒。因为加密所需的key只有你和微信知道,所以加密结果可能能对起来。如果key泄漏了会很危险,因为其他人可能会伪造一个结果,告诉你支付成功了。key可以在微信支付平台中修改。



    最后

    这次对接过程还比较顺利,没有遇到什么坑,记得第一次做微信接口的时候,不知道是文档我没理解,还是其他什么原因,用了很长事件。当然只按照上面说的是不行的,这里只是提供一个思路和几个辅助的代码段,还需要按照你自己的业务逻辑进行改造,至于其他接口大同小异,不在叙述了。

    展开全文
  • 这个系列会介绍如何快速上手进行公众号、WEB/小程序、钉钉等平台的开发接入。我肯定不敢说自己写的东西比腾讯、阿里官方文档更好,而且本身我也对这些开发并没有了解得有多深入,只是希望可以筛繁就简,尽自己可能做...
    这个系列会介绍如何快速上手进行公众号、WEB/小程序、钉钉等平台的开发接入。我肯定不敢说自己写的东西比腾讯、阿里官方文档更好,而且本身我也对这些开发并没有了解得有多深入,只是希望可以筛繁就简,尽自己可能做一系列可以快速上手,同时也能为大家降低试错成本的文档。由于水平有限,错误和疏漏再所难免,欢迎讨论和指正。 从微信服务的业务结构上来讲,订阅号和服务号属于同一类应用,小程序、WEB属于另一类应用。 前一类应用关注的是在微信公众号中,访客与公众号本身的互动。 普通的公众号工作流程是:信息发到公众号,公众号后台对消息进行处理,并返回给用户。接入开发以后,不同的地方在于消息不再由公众号后台处理,而是由第三方web后端来处理:公众号收到消息 ,转发到指定URL,由第三方web后端对消息进行处理,进入业务流程,完成后返回消息,最终由公众号后台将后端返回的消息推送给客户。 除了消息、事件通知类的业务之外,系统相关的功能由后端应用向公众平台api发起相应的请求来实现(例如获取accesstoken、菜单管理等功能)。 WEB/小程序应用属于基于微信平台的扩展应用,由项目本身的前端提供交互,微信服务器只提供鉴权、功能服务的接口。小程序项目的前端与后端完全分离,前端代码直接托管在微信服务器,后端自行部署在自己的服务器;而微信web应用前后端均需要自行部署。

    资源

    • 公众号开发文档
      https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html

    • 小程序开发文档
      https://developers.weixin.qq.com/miniprogram/dev/framework/

    • 消息加解密说明

      https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Message_Encryption/Message_encryption_and_decryption.html

    公众号开发接入

        公众号开发最根本的业务逻辑就是接收消息、处理消息,与公众号平台建立联系的凭据就是公众号后台设置的服务器URL,一个公众号项目需要实现的功能入口全在这个URL上,可以按自己需求或喜好为公众号写一个独立的WEB后端应用,也可以将公众号后端服务作为一个功能模块,放到某一个网站中。

        * 除了消息处理接口,还需要准备一个接入验证的接口,公众号配置完成后,会发送验证消息对服务器URL进行有效性验证,该过程只在接入时使用,一旦接入就再也用不到了。

    898be3f1fb70d3a5d284d2b96f2b6821.png

        在公众号后台配置好IP白名单、服务器地址、令牌、消息加解密密钥,再加上系统分配的开发者ID和开发者密码,就可以进行公众号开发了。

        其中服务器地址要求HTTP/HTTPS标准端口,这就有两个选择:备案过的国内服务器,或无需备案的国外服务器(从网络稳定性上讲,有条件的话,尽量使用备案过的国内服务器)。这一项要求比WEB/小程序开发要宽松,后者不仅要求使用80/443,而且要求域名必须备案,也就是国外服务器无法使用。

    0. 超时

    公众号发往web后端的请求超时时间是5秒,一旦连续超时3次,本次请求即视为失败。为了提高稳定性,需要选择响应更快的服务器(一般而言,国内服务器响应速度远快于国外服务器),同时需要减少业务的等待时间(如果业务时间过长,可先返回响应,将业务放到后台慢慢处理)。

    1. 接入验证

    基本配置页面中,填写完服务器地址、令牌、消息加解密密钥,并点击保存时,公众平台会主动向服务器地址发送一个GET请求进行接入验证,这个验证包含参数:签名signature、时间戳timestamp、随机数nonce、随机字符串echostr。这就是后端需要实现的第一个接口——接入验证:接受微信服务器GET请求,对请求中的参数进行校验,比对signature与校验结果是否一致,如果一致,证明请求来源于公众平台,此时将echostr原值返回,一旦微信服务器收到返回值,即视为通过验证,至此,接入就完成了。 校验算法是:timestamp、nonce、token进行字典序排序并拼接,对拼接结果取sha1。
    public IActionResult Index()  string token = WXToken;  string timestamp = Request.Query["timestamp"];  string nonce = Request.Query["nonce"];  string signature = Request.Query["signature"];  string[] plain = { token, timestamp, nonce };  string echostr = Request.Query["echostr"];  Array.Sort(plain);  using SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();  string sig2 = BitConverter.ToString(sha.ComputeHash(Encoding.UTF8.GetBytes(string.Join("", plain)))).Replace("-", "").ToLower();  if (sig2 == signature)  {    return Content(echostr);  }  else  {    return Content("SIGNATURE_NOT_MATCH");  }}
    2. 交互业务

    交互,是指用户在公众号界面的所有操作,包含关注/取消关注公众号,发送文字、图片、语音留言消息,点击菜单项等动作。一旦这些动作发生,公众平台会将对应的事件以特定的数据格式发送到web后端,web后端处理后,对此返回的响应会经由公众号发送给客户。

    交互业务和接入验证均使用公众号后台配置的服务器URL,二者的区别是:交互产生的事件通知会使用POST发送具有固定的XML格式数据,接入验证则是使用GET请求直接在URL传送参数。

    后端和微信服务器通信的消息加解密操作可选择明文模式、兼容模式、安全模式,推荐使用安全模式,此时消息内容会用公众号后台设置的加解密密钥进行AES加密,安全性更高。

    关注公众号时产生的事件(消息结构示例1)

          123456789    

    用户文本消息留言产生的事件(消息结构示例2)

          1348831860      1234567890123456

    上报地理位置产生的事件(消息结构示例3)

          123456789      23.137466  113.352425  119.385040

    通过上面的几类事件不难看出,XML结构固定不变的部分包含:接收人(公众号)、发送人(用户)、时间、消息类型、事件类型。剩下的就是事件内容,由于消息/事件类型不同,事件内容也各不相同,处理的时候区别一下即可。处理完毕,回复的消息仍旧是以XML格式发送。

    比如,新用户关注的时候,会收到一条MsgType=Event,Event=subscribe的消息(格式可参考消息结构示例1),这时HTTPResponse里返回一条Content为“欢迎关注”的文本消息XML,新关注的用户即可收到“欢迎关注”的问候语(消息结构示例4):

          12345678    

    业务应用

    类似上面这种对任意事件通知、留言进行处理的过程,即是公众后台开发所需实现的业务过程。简单一点,可以将公众号打造成一个BOT;复杂一点,则可以将公众号打造成功能完备的可提供各类服务的全能型应用中心。整个业务流程全部围绕着收消息、执行动作、响应三个环节。尤其是执行动作环节,几乎可以处理任何需求,无论是操作服务器本地资源(硬件、软件、文件、数据库),还是通过接口(HTTP、SOCKET、COM)收发消息或进行设备控制,都可以和公众号联系起来。

    297c1ec63353b0713d69cb4d5a28ba51.png

    9afeee14225738db70d063ff9a1d97e5.png

    消息/事件类型

    正如前面所介绍,公众号发往后端服务的消息分为两类:普通消息,包含文本、图片、语音、视频、短视频、地理位置、链接消息,MsgType对应为text、image、voice、video、shortvideo、location、link;事件推送,包含关注/取消关注、扫描带参数的二维码、上报地理位置、自定义菜单相关操作的消息,MsgType统一为event,不同事件通过Event值进行区分。

    在对用户进行回复时,消息类型也是多种多样,支持的MsgType有文本(text)、图片(image)、语音(voice)、视频(video)、音乐(music)、图文(news),可在回复时按需选择。

    语音转文字

    如果在接口权限中,开启了接收语音识别结果,voice类型的消息将会额外多出一个Recognaition字段,其值为语音识别结果。

    5a30fbe81faf5cf0d21e7c760bfd7412.png

    a4e2ef5119f184d5e7a7bc7313334748.png

    ec4c1fed31774ccf1a542c5913c479c5.png

    1273d780a1886c106c57d8d5a92f6211.png

    Access token

    除去以上涉及到用户交互的业务,公众号开发还支持管理类的业务操作(比如自定义菜单、素材管理、用户管理、获取统计数据等操作)。实现该类操作的时候,向指定API地址发送POST/GET请求即可。全局范围的access_token是API请求中最重要的一个参数,获取方式是以GET方式请求 https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET,有效期7200秒。

    公众平台只接受来自白名单IP的access_token请求。

    使用场景举例,新增图片类型的临时素材

    接口地址:https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE

    TYPE按素材类型取不同的值:图片(image)、语音(voice)、视频(video)、缩略图(thumb)。

    新增素材需要以表单形式进行POST提交到该接口,表单字段media即为需要上传的素材文件,调用成功,服务器即会返回包含type、media_id、created_at的JSON格式消息。

    加解密

    在公众号后台设置消息加解密方式为安全模式时,公众平台会向后端服务发送加密过的内容,同时也要求后端返回消息时也进行加密。加解密过程可以直接照搬官方提供的DEMO(c++, php, java, python, c#),下载地址:https://res.wx.qq.com/op_res/-serEQ6xSDVIjfoOHcX78T1JAYX-pM_fghzfiNYoD8uHVd3fOeC0PC_pvlg4-kmP

    收到的消息格式如下,Encrypt为原始消息加密结果,服务器收到消息后,对Encrypt字段的内容进行解密即可还原出原始内容(解密用到的参数从QueryString中获取,QueryString形如

    ?signature=…… &timestamp=…… &nonce=…… &openid=…… &encrypt_type=aes &msg_signature=……):
            

    返回消息时,也要进行加密:

                    xml>
    展开全文
  • C#微信公众号开发

    热门讨论 2014-09-21 11:06:43
    本人用c#语言vs2010开发的一个微信公众号。里面有自定义菜单,关注回复和发送被动响应消息。等基本功能。还有C#接入微信的注意事项。完全是本人在工作中发现的一些经验。希望对同道中人有所帮助。
  • 原文:C#微信公众号开发系列教程二(新手接入指南) 此系列前面已经更新了两篇博文了,都是微信开发的前期准备工作,现在切入正题,本篇讲解新手接入的步骤与方法,大神可直接跳过,也欢迎大神吐槽。 目录 C#...
    原文: C#微信公众号开发系列教程二(新手接入指南)

    此系列前面已经更新了两篇博文了,都是微信开发的前期准备工作,现在切入正题,本篇讲解新手接入的步骤与方法,大神可直接跳过,也欢迎大神吐槽。

    目录

    C#微信公众号开发系列教程一(调试环境部署)

    C#微信公众号开发系列教程一(调试环境部署续:vs远程调试)

    C#微信公众号开发系列教程二(新手接入指南)

     

    微信公众平台消息接口的工作原理大概可以这样理解:从用户端到公众号端一个流程是这样的,用户发送消息到微信服务器,微信服务器将接收到的消息post到用户接入时填写的url中,在url处理程序中,首先判断消息的合法性,判断成功后根据消息体的内容做相应的相应。原理很容易理解,接触过socket的可能理解起来更容易。

    然而,微信的文档有的时候确实有点让人摸不着头脑,关于微信接入的文档写的确实不敢恭维啊。官方文档写的第一步是“申请消息接口”,这里是需要填写一个url的,此url用来处理微信发送的消息的,但微信把url中相关的配置写在了第二步,一不小心就把新手给坑了。下面我按照我的理解来进行解释。

    首先,开发者在接入时,微信服务器将发送get请求到你填写的url上,此请求携带四个参数,分别signature(微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。),timestamp(时间戳),nonce(随机数),echostr(随机字符串).用 HttpContext.Current.Request.RawUrl可以获取当前请求的原始url,如下图所示:

    image

    开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。

    加密/校验流程如下:
    1. 将token、timestamp、nonce三个参数进行字典序排序
    2. 将三个参数字符串拼接成一个字符串进行sha1加密
    3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。
    下面是代码实现。
    首先,在你的处理程序中(我是新建了一个一般处理程序wx.ashx),判断当前请求的类型,因为接入时,是发送的GET请求,消息处理是发送的POST请求。如下图:
    这里我对验证url的方法进行封装。
    /// <summary>
            /// 验证url权限, 接入服务器
            /// </summary>
            /// <param name="token"></param>
            /// <returns></returns>
            public static bool ValidUrl(string token)
            {
                string echoStr = VqiRequest.GetQueryString("echoStr");
                if (CheckSignature(token))
                {
                    if (!string.IsNullOrEmpty(echoStr))
                    {
                        Utils.ResponseWrite(echoStr);
                        return true;
                    }
    
                }
                return false;
            }
    
    /// <summary>
            /// 验证微信签名
            /// </summary>
            /// * 将token、timestamp、nonce三个参数进行字典序排序
            /// * 将三个参数字符串拼接成一个字符串进行sha1加密
            /// * 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。
            /// <returns></returns>
            public static bool CheckSignature(string token)
            {
                string signature = VqiRequest.GetQueryString("signature");
                string timestamp = VqiRequest.GetQueryString("timestamp");
                string nonce = VqiRequest.GetQueryString("nonce");
                string[] ArrTmp = { token, timestamp, nonce };
                Array.Sort(ArrTmp);     //字典排序
                string tmpStr = string.Join("", ArrTmp);
                tmpStr = Utils.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
                tmpStr = tmpStr.ToLower();
                if (tmpStr == signature)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

     

    注:代码VqiRequest.GetQueryString是封装的QueryString请求的方法,使用的时候可以改成QueryString[“”]

    处理过程如图:

    image

    image

    将signature,timestamp,nonce三个参数放在数组中,

    image

    image

    排序后的ArrTmp:

    image

    将三个将三个参数字符串拼接成一个字符串:

    image

    将tmpStr进行sha1加密,加密后的字符串转换成小写:

    image

    然后和签名进行对比,相同则表示验证成功。

    image

    验证成功将echoStr返回给微信。

    image

    /// <summary>
            /// 根据指定的密码和哈希算法生成一个适合于存储在配置文件中的哈希密码
            /// </summary>
            /// <param name="str">要进行哈希运算的密码</param>
            /// <param name="type"> 要使用的哈希算法</param>
            /// <returns>经过哈希运算的密码</returns>
            public static string HashPasswordForStoringInConfigFile(string str, string type)
            {
                return FormsAuthentication.HashPasswordForStoringInConfigFile(str, type);
            }
    
            public static void ResponseWrite(string str)
            {
                HttpContext.Current.Response.Write(str);
                HttpContext.Current.Response.End();
            }

     

    处理程序编写完毕后,部署到iis(方法请参照教程一),登录微信管理后台https://mp.weixin.qq.com/在开发者中心页,点击“修改配置按钮”填写URL、Token和EncodingAESKey,其中URL是开发者用来接收微信服务器数据的接口URL。Token可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)。EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥。同时,开发者可选择消息加解密方式:明文模式、兼容模式和安全模式。模式的选择与服务器配置在提交后都会立即生效。加解密方式的默认状态为明文模式。加解密模式将在后期的系列中与大家共享,敬请期待。

    如图所示:

    image

    image

     

    点击提交后,微信服务器将get请求到上文中编写的url中。验证成功,则绑定成功。

    image

     

     

    END

     

    如有疑问加群一起交流,我需要广大屌丝小伙伴的反馈与建议,   点击这里给我发消息

    如果觉得本文对你有帮助,请点击文章下面的推荐哦,去帮助更多的小伙伴了解微信开发的流程。

    如果你是土豪,想支持笔者继续更新本系列教程,可以扫描下面的二维码悬赏一下,你的支持是笔者继续更新下去的动力。

    展开全文
  • C#开发微信号最基础服务器配置,直接上传即可用
  • //微信接入的测试 } } /// /// 处理信息并应答 /// private void Handle(string postStr) { MessageHelper help = new MessageHelper(); string responseContent = help.ReturnMessage(postStr); ...

     一、服务器处理程序

       在上篇文章中的测试号服务器配置中就需要,写处理程序的url,下面贴出的就是处理程序的代码了。当然了这个地址必须是外网才行,如果是自己搭建的一个服务器,可以使用外网穿透。它里面有免费服务器申请,再下载一个客户端,把隧道id输进去,直接enter,这样本机服务器就是一个外网的了,就是网速慢...但就测试是够用了。

    1.外网穿透

    下面就是关于它简单操作的一些截图,具体操作就不说了,它本身就有一个详细的文档,可以自己去看看

     

     二、处理程序源代码

    <%@ WebHandler Language="C#" Class="wxapi" %>
    
    using System;
    using System.Web;
    using System.Xml;
    using System.Text;
    
    public class wxapi : IHttpHandler
    {
        
        public void ProcessRequest (HttpContext context) {
            string postString = string.Empty;
            if (HttpContext.Current.Request.HttpMethod.ToUpper() == "POST")
            {
                using (System.IO.Stream stream = HttpContext.Current.Request.InputStream)
                {
                    Byte[] postBytes = new Byte[stream.Length];
                    stream.Read(postBytes, 0, (Int32)stream.Length);
                    postString = System.Text.Encoding.UTF8.GetString(postBytes);
                }
    
                if (!string.IsNullOrEmpty(postString))
                {
                    Handle(postString);//事件处理
                }
            }
            else
            {
                ConnectTest(); //微信接入的测试
            }
        }
        /// <summary>
        /// 处理信息并应答
        /// </summary>
        private void Handle(string postStr)
        {
            MessageHelper help = new MessageHelper();
            string responseContent = help.ReturnMessage(postStr);
    
            HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
            HttpContext.Current.Response.Write(responseContent);
        }
        /// <summary>
        /// 服务链接测试
        /// </summary>
        private void ConnectTest()
        {
          string token = System.Configuration.ConfigurationManager.AppSettings["WeixinToken"];//从配置文件获取Token
            if (string.IsNullOrEmpty(token))
            {
              MessageHelper.WriteLog(string.Format("WeixinToken 配置项没有配置!"));
            }
    
            string echoString = HttpContext.Current.Request.QueryString["echoStr"];
            string signature = HttpContext.Current.Request.QueryString["signature"];
            string timestamp = HttpContext.Current.Request.QueryString["timestamp"];
            string nonce = HttpContext.Current.Request.QueryString["nonce"];
    
            if (new BasicApi().CheckSignature(token, signature, timestamp, nonce))
            {
                if (!string.IsNullOrEmpty(echoString))
                {
                    HttpContext.Current.Response.Write(echoString);
                    HttpContext.Current.Response.End();
                }
            }
        }
        
        public bool IsReusable {
            get {
                return false;
            }
        }
    
    }

    三、签名代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    
    /// <summary>
    /// BasicApi 的摘要说明
    /// </summary>
    public class BasicApi
    {
    	public BasicApi()
    	{
    		//
    		// TODO: 在此处添加构造函数逻辑
    		//
    	}
        /// <summary>
        /// 验证微信签名
        /// </summary>
        public bool CheckSignature(string token, string signature, string timestamp, string nonce)
        {
            string[] ArrTmp = { token, timestamp, nonce };
    
            Array.Sort(ArrTmp);
            string tmpStr = string.Join("", ArrTmp);
    
            tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
            tmpStr = tmpStr.ToLower();
    
            if (tmpStr == signature)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

     

     

    展开全文
  • C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C#微信公众号开发系列教程四(接收普通消息) C#微信公众号开发系列教程五(接收事件推送与消息排重) C#微信...
  • C#微信公众号开发系列教程五(接收事件推送与消息排重) ...C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C#微信公众号开发系列教...
  • C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C#微信公众号开发系列教程四(接收普通消息) C#微信公众号开发系列教程五(接收事件推送与消息排重) ...
  • C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C#微信公众号开发系列教程四(接收普通消息) C#微信公众号开发系列教程五(接收事件推送与消息排重) C#微信...
  •  所以我准备每天写一点关于C#微信开发方面的东西,希望能帮到后面做C#微信开发的朋友们,希望能让你们少走点弯路,当然写在博客里面也是怕时间长了自己也会忘记了。  本人文笔有限,写的不好的地方希望大家理解,...
  • 微信公众号开发C#系列-2、微信公众平台接入指南 概述 微信公众平台消息接口的工作原理大概可以这样理解:从用户端到公众号端一个流程是这样的,用户发送消息到微信服务器,微信服务器将接收到的消息...
  • 1.C#/ASP.NET MVC微信公众号接口开发之从零开发(一) 接入微信公众平台 2.C#/ASP.NET MVC微信公众号接口开发之从零开发(二) 接收微信消息并且解析XML(附源码) 3.C#/ASP.NET MVC微信公众号接口开发之从零开发...
  • ConfigHelper configHelper = new ConfigHelper(); string appid = configHelper.GetValueByKey("AppID");... 模板ID是再公众号中查找的,或者自己进行申请的 然后根据别人的格式,进行发送信息,即可
  • c#实现微信公众号开发--接入

    千次阅读 2018-05-12 21:48:27
    2012年从微信公众号一推出就开始跟进研究,中间很多年因为工作岗位变动不再涉及编程,但作为业余爱好,兴趣一直没变,现总结几篇关于微信公众号开发的实现,帮助新手,同时也便于自己回顾。自己做微信公众好管理平台...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,545
精华内容 618
关键字:

c#微信公众号接口接入

c# 订阅