湘水渔歌 發表於 2019-8-8 14:38:00

微信小程序支付功能 C# .NET开发

<p><span style="font-size: 18px"><span style="font-size: 18px">微信小程序支付功能的开发的时候坑比较多,不过对于钱的事谨慎也是好事。网上关于小程序支付的实例很多,但是大多多少有些问题,C#开发的更少。此篇文档的目的是讲开发过程中遇到的问题做一个备注,也方便其他开发的同学作为参考!</span></span></p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px">&nbsp;</p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px"><span style="font-size: 18px">&nbsp; &nbsp; &nbsp; &nbsp;1、首先建议把官方文档支付部分看上三遍,每个细节都不要放过,因为任何一个点和微信要求不符都会导致支付不成功。https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=3_1</span></p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px"><span style="font-size: 18px">&nbsp; &nbsp; &nbsp; 2、经过验证的微信支付功能,会需要一些商户号、支付秘钥等,不要搞混。</span></p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px"><span style="font-size: 18px">&nbsp; &nbsp; &nbsp;3、经常遇到的是“签名错误”,请仔细看需要传送的xml参数及取值规则是否符合微信规则。微信有个验证工具可以验证发送的xml字段是否合法。</span></p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px">&nbsp;</p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px"><span style="font-size: 18px"><span style="color: rgba(255, 0, 0, 1)">下面上代码:</span></span></p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px">&nbsp;</p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px"><span style="font-size: 18px">web.config</span></p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px">&nbsp;</p>
<pre><code class="hljs cs">    &lt;<span class="hljs-keyword">add key=<span class="hljs-string">"ConnectionString" <span class="hljs-keyword">value=<span class="hljs-string">"server=127.0.0.1;database=;uid=sa;pwd="/&gt;
    &lt;<span class="hljs-keyword">add key=<span class="hljs-string">"ConnectionString2" <span class="hljs-keyword">value=<span class="hljs-string">"server=127.0.0.1;database=codematic2;uid=sa;pwd=1"/&gt;
    &lt;<span class="hljs-keyword">add key=<span class="hljs-string">"appid" <span class="hljs-keyword">value=<span class="hljs-string">""/&gt;<span class="hljs-comment">//appid
    &lt;<span class="hljs-keyword">add key=<span class="hljs-string">"secret" <span class="hljs-keyword">value=<span class="hljs-string">""/&gt;<span class="hljs-comment">//小程序秘钥
    &lt;<span class="hljs-keyword">add key=<span class="hljs-string">"mch_id" <span class="hljs-keyword">value=<span class="hljs-string">""/&gt;<span class="hljs-comment">//商户号
    &lt;<span class="hljs-keyword">add key=<span class="hljs-string">"key" <span class="hljs-keyword">value=<span class="hljs-string">""/&gt;<span class="hljs-comment">//支付秘钥
    &lt;<span class="hljs-keyword">add key=<span class="hljs-string">"ip" <span class="hljs-keyword">value=<span class="hljs-string">""/&gt;<span class="hljs-comment">//服务器IP
    &lt;<span class="hljs-keyword">add key=<span class="hljs-string">"PayResulturl" <span class="hljs-keyword">value=<span class="hljs-string">""/&gt;<span class="hljs-comment">//微信返回接收信息的url地址
&lt;/appSettings&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p><span style="font-size: 18px"><span style="font-size: 18px"><span style="color: rgba(86, 95, 105, 1); line-height: 25.2px; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px">支付后台xiadan.ashx</span></span></span></p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px">&nbsp;</p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px">&nbsp;</p>
<pre><code class="hljs cs">&lt;%@ WebHandler Language=<span class="hljs-string">"C#" Class=<span class="hljs-string">"xiadan" %&gt;

<span class="hljs-keyword">using System;
<span class="hljs-keyword">using System.Web;
<span class="hljs-keyword">using System.Net;
<span class="hljs-keyword">using System.IO;
<span class="hljs-keyword">using System.Configuration;
<span class="hljs-keyword">using Maticsoft.Model;
<span class="hljs-keyword">using Maticsoft.BLL;
<span class="hljs-keyword">using System.Security.Cryptography;
<span class="hljs-keyword">using System.Text;
<span class="hljs-keyword">using System.Xml.Serialization;
<span class="hljs-keyword">using System.Xml;
<span class="hljs-keyword">using System.Collections.Generic;
<span class="hljs-keyword">using System.Data;
<span class="hljs-keyword">using System.Net.Security;
<span class="hljs-keyword">using System.Security.Cryptography.X509Certificates;
<span class="hljs-keyword">using System.Linq;
<span class="hljs-keyword">using Newtonsoft.Json;

<span class="hljs-keyword">public <span class="hljs-keyword">class <span class="hljs-title">xiadan : <span class="hljs-title">IHttpHandler
{

    <span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">void <span class="hljs-title">ProcessRequest(<span class="hljs-params">HttpContext context)
    {
      context.Response.ContentType = <span class="hljs-string">"text/plain";
      <span class="hljs-keyword">string openid = context.Request.Params[<span class="hljs-string">"openid"];
      <span class="hljs-keyword">string ordertime = context.Request.Params[<span class="hljs-string">"ordertime"];

      <span class="hljs-keyword">string appid = ConfigurationManager.AppSettings[<span class="hljs-string">"appid"];
      <span class="hljs-keyword">string secret = ConfigurationManager.AppSettings[<span class="hljs-string">"secret"];
      <span class="hljs-keyword">string key = ConfigurationManager.AppSettings[<span class="hljs-string">"key"];
      <span class="hljs-keyword">string mch_id = ConfigurationManager.AppSettings[<span class="hljs-string">"mch_id"];
      <span class="hljs-keyword">string ip = ConfigurationManager.AppSettings[<span class="hljs-string">"ip"];
      <span class="hljs-keyword">string PayResulturl = ConfigurationManager.AppSettings[<span class="hljs-string">"PayResulturl"];
      <span class="hljs-keyword">string roomid = context.Request.Params[<span class="hljs-string">"roomid"];
      <span class="hljs-keyword">string aa = <span class="hljs-string">"-押金";<span class="hljs-comment"><span class="hljs-doctag">////商品描述交易字段格式根据不同的应用场景按照以下格式:APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。

      <span class="hljs-keyword">string strcode = aa;
      <span class="hljs-keyword">byte[] buffer = Encoding.UTF8.GetBytes(strcode);
      <span class="hljs-keyword">string body = Encoding.UTF8.GetString(buffer, <span class="hljs-number">0, buffer.Length);
      <span class="hljs-keyword">string totalfee = context.Request.Params[<span class="hljs-string">"totalfee"];
      <span class="hljs-keyword">string output = <span class="hljs-string">"";
      <span class="hljs-keyword">if ((context.Request.Params[<span class="hljs-string">"openid"] != <span class="hljs-literal">null) &amp;&amp; (context.Request.Params[<span class="hljs-string">"openid"] != <span class="hljs-string">""))
      {
            <span class="hljs-comment">//OrderInfo order = new OrderInfo();

            <span class="hljs-comment">//order.appid = appid;

            System.Random Random = <span class="hljs-keyword">new System.Random();



            <span class="hljs-keyword">var dic = <span class="hljs-keyword">new Dictionary&lt;<span class="hljs-keyword">string, <span class="hljs-keyword">string&gt;
{
    {<span class="hljs-string">"appid", appid},
    {<span class="hljs-string">"mch_id", mch_id},
    {<span class="hljs-string">"nonce_str", GetRandomString(<span class="hljs-number">20)<span class="hljs-comment">/*Random.Next().ToString()*/},
    {<span class="hljs-string">"body",body},
    {<span class="hljs-string">"out_trade_no",roomid + DateTime.Now.ToString(<span class="hljs-string">"yyyyMMddHHmmssfff") + Random.Next(<span class="hljs-number">999).ToString()},<span class="hljs-comment">//商户自己的订单号码
    {<span class="hljs-string">"total_fee",totalfee},
    {<span class="hljs-string">"spbill_create_ip",ip},<span class="hljs-comment">//服务器的IP地址
    {<span class="hljs-string">"notify_url",PayResulturl},<span class="hljs-comment">//异步通知的地址,不能带参数
    {<span class="hljs-string">"trade_type",<span class="hljs-string">"JSAPI" },
    {<span class="hljs-string">"openid",openid}
};
      <span class="hljs-comment">//加入签名
            dic.Add(<span class="hljs-string">"sign", GetSignString(dic));

            <span class="hljs-keyword">var sb = <span class="hljs-keyword">new StringBuilder();
            sb.Append(<span class="hljs-string">"&lt;xml&gt;");


            <span class="hljs-keyword">foreach (<span class="hljs-keyword">var d <span class="hljs-keyword">in dic)
            {
                sb.Append(<span class="hljs-string">"&lt;" + d.Key + <span class="hljs-string">"&gt;" + d.Value + <span class="hljs-string">"&lt;/" + d.Key + <span class="hljs-string">"&gt;");
            }
            sb.Append(<span class="hljs-string">"&lt;/xml&gt;");
            <span class="hljs-keyword">var xml = <span class="hljs-keyword">new XmlDocument();
            <span class="hljs-comment">//xml.LoadXml(GetPostString("https://api.mch.weixin.qq.com/pay/unifiedorder", sb.ToString()));
            CookieCollection coo = <span class="hljs-keyword">new CookieCollection();
            Encoding en = Encoding.GetEncoding(<span class="hljs-string">"UTF-8");

            HttpWebResponse response = CreatePostHttpResponse(<span class="hljs-string">"https://api.mch.weixin.qq.com/pay/unifiedorder", sb.ToString(), en);
            <span class="hljs-comment">//打印返回值
            Stream stream = response.GetResponseStream();   <span class="hljs-comment">//获取响应的字符串流
            StreamReader sr = <span class="hljs-keyword">new StreamReader(stream); <span class="hljs-comment">//创建一个stream读取流
            <span class="hljs-keyword">string html = sr.ReadToEnd();   <span class="hljs-comment">//从头读到尾,放到字符串html
                                          <span class="hljs-comment">//Console.WriteLine(html);
            xml.LoadXml(html);
            <span class="hljs-comment">//对请求返回值 进行处理

            <span class="hljs-keyword">var root = xml.DocumentElement;

            DataSet ds = <span class="hljs-keyword">new DataSet();
            StringReader stram = <span class="hljs-keyword">new StringReader(html);
            XmlTextReader reader = <span class="hljs-keyword">new XmlTextReader(stram);
            ds.ReadXml(reader);
            <span class="hljs-keyword">string return_code = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"return_code"].ToString();
            <span class="hljs-keyword">if (return_code.ToUpper() == <span class="hljs-string">"SUCCESS")
            {
                <span class="hljs-comment">//通信成功
                <span class="hljs-keyword">string result_code = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"result_code"].ToString();<span class="hljs-comment">//业务结果
                <span class="hljs-keyword">if (result_code.ToUpper() == <span class="hljs-string">"SUCCESS")
                {
                  <span class="hljs-keyword">var res = <span class="hljs-keyword">new Dictionary&lt;<span class="hljs-keyword">string, <span class="hljs-keyword">string&gt;
{
    {<span class="hljs-string">"appId", appid},
    {<span class="hljs-string">"timeStamp", GetTimeStamp()},
    {<span class="hljs-string">"nonceStr", dic[<span class="hljs-string">"nonce_str"]},
    {<span class="hljs-string">"package",<span class="hljs-string">"prepay_id="+ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"prepay_id"].ToString()},
    {<span class="hljs-string">"signType", <span class="hljs-string">"MD5"}
};

                  <span class="hljs-comment">//在服务器上签名
                  res.Add(<span class="hljs-string">"paySign", GetSignString(res));
                  <span class="hljs-comment">// string signapp = res.ToString();
                  <span class="hljs-keyword">string signapp = JsonConvert.SerializeObject(res);
                  <span class="hljs-keyword">if ((context.Request.Params[<span class="hljs-string">"openid"] != <span class="hljs-literal">null) &amp;&amp; (context.Request.Params[<span class="hljs-string">"openid"] != <span class="hljs-string">""))
                  {
                  <span class="hljs-comment">//存储订单信息
                  Maticsoft.Model.order_history oh = <span class="hljs-keyword">new Maticsoft.Model.order_history();
                  <span class="hljs-comment">//oh.shop_id =
                  oh.room_id = Convert.ToInt32(roomid);
                  oh.pay_price = Convert.ToDecimal(totalfee);
                  oh.out_trade_no = dic[<span class="hljs-string">"out_trade_no"];
                  oh.order_timestart = Convert.ToDateTime(ordertime);
                  oh.openid = openid;
                  oh.creating_date = DateTime.Now;

                  Maticsoft.BLL.order_history bll = <span class="hljs-keyword">new Maticsoft.BLL.order_history();
                  bll.Add(oh);

                }
                context.Response.Write(signapp);
            }
      }




    }
    context.Response.Write(output);
    }

<span class="hljs-keyword">public <span class="hljs-keyword">bool IsReusable
{
    <span class="hljs-keyword">get
    {
      <span class="hljs-keyword">return <span class="hljs-literal">false;
    }
}

<span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">string <span class="hljs-title">GetMd5Hash(<span class="hljs-params">String input)
{
    <span class="hljs-keyword">if (input == <span class="hljs-literal">null)
    {
      <span class="hljs-keyword">return <span class="hljs-literal">null;
    }

    MD5 md5Hash = MD5.Create();

    <span class="hljs-comment">// 将输入字符串转换为字节数组并计算哈希数据
    <span class="hljs-keyword">byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

    <span class="hljs-comment">// 创建一个 Stringbuilder 来收集字节并创建字符串
    StringBuilder sBuilder = <span class="hljs-keyword">new StringBuilder();

    <span class="hljs-comment">// 循环遍历哈希数据的每一个字节并格式化为十六进制字符串
    <span class="hljs-keyword">for (<span class="hljs-keyword">int i = <span class="hljs-number">0; i &lt; data.Length; i++)
    {
      sBuilder.Append(data.ToString());
    }

    <span class="hljs-comment">// 返回十六进制字符串
    <span class="hljs-keyword">return sBuilder.ToString();
}
<span class="hljs-comment"><span class="hljs-doctag">/// <span class="hljs-doctag">&lt;summary&gt;
<span class="hljs-comment"><span class="hljs-doctag">/// 对象序列化成 XML String
<span class="hljs-comment"><span class="hljs-doctag">/// <span class="hljs-doctag">&lt;/summary&gt;
<span class="hljs-keyword">public <span class="hljs-keyword">static <span class="hljs-keyword">string XmlSerialize&lt;T&gt;(T obj)
{
    <span class="hljs-keyword">string xmlString = <span class="hljs-keyword">string.Empty;
    XmlSerializer xmlSerializer = <span class="hljs-keyword">new XmlSerializer(<span class="hljs-keyword">typeof(T));
    <span class="hljs-keyword">using (MemoryStream ms = <span class="hljs-keyword">new MemoryStream())
    {
      xmlSerializer.Serialize(ms, obj);
      xmlString = Encoding.UTF8.GetString(ms.ToArray());
    }
    <span class="hljs-keyword">return xmlString;
}
<span class="hljs-comment"><span class="hljs-doctag">/// <span class="hljs-doctag">&lt;summary&gt;
<span class="hljs-comment"><span class="hljs-doctag">/// 从字符串里随机得到,规定个数的字符串.
<span class="hljs-comment"><span class="hljs-doctag">/// <span class="hljs-doctag">&lt;/summary&gt;
<span class="hljs-comment"><span class="hljs-doctag">/// <span class="hljs-doctag">&lt;param name="allChar"&gt;<span class="hljs-doctag">&lt;/param&gt;
<span class="hljs-comment"><span class="hljs-doctag">/// <span class="hljs-doctag">&lt;param name="CodeCount"&gt;<span class="hljs-doctag">&lt;/param&gt;
<span class="hljs-comment"><span class="hljs-doctag">/// <span class="hljs-doctag">&lt;returns&gt;<span class="hljs-doctag">&lt;/returns&gt;
<span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">static <span class="hljs-keyword">string <span class="hljs-title">GetRandomString(<span class="hljs-params"><span class="hljs-keyword">int CodeCount)
{
    <span class="hljs-keyword">string allChar = <span class="hljs-string">"1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,i,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
    <span class="hljs-keyword">string[] allCharArray = allChar.Split(<span class="hljs-string">',');
    <span class="hljs-keyword">string RandomCode = <span class="hljs-string">"";
    <span class="hljs-keyword">int temp = <span class="hljs-number">-1;
    Random rand = <span class="hljs-keyword">new Random();
    <span class="hljs-keyword">for (<span class="hljs-keyword">int i = <span class="hljs-number">0; i &lt; CodeCount; i++)
    {
      <span class="hljs-keyword">if (temp != <span class="hljs-number">-1)
      {
            rand = <span class="hljs-keyword">new Random(temp * i * ((<span class="hljs-keyword">int)DateTime.Now.Ticks));
      }
      <span class="hljs-keyword">int t = rand.Next(allCharArray.Length - <span class="hljs-number">1);
      <span class="hljs-keyword">while (temp == t)
      {
            t = rand.Next(allCharArray.Length - <span class="hljs-number">1);
      }
      temp = t;
      RandomCode += allCharArray;
    }

    <span class="hljs-keyword">return RandomCode;
}


<span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">static <span class="hljs-keyword">string <span class="hljs-title">GetWebClientIp(<span class="hljs-params">)
{
    <span class="hljs-keyword">string userIP = <span class="hljs-string">"IP";

    <span class="hljs-keyword">try
    {
      <span class="hljs-keyword">if (System.Web.HttpContext.Current == <span class="hljs-literal">null
    || System.Web.HttpContext.Current.Request == <span class="hljs-literal">null
    || System.Web.HttpContext.Current.Request.ServerVariables == <span class="hljs-literal">null)
            <span class="hljs-keyword">return <span class="hljs-string">"";

      <span class="hljs-keyword">string CustomerIP = <span class="hljs-string">"";

      <span class="hljs-comment">//CDN加速后取到的IP   
      CustomerIP = System.Web.HttpContext.Current.Request.Headers[<span class="hljs-string">"Cdn-Src-Ip"];
      <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(CustomerIP))
      {
            <span class="hljs-keyword">return CustomerIP;
      }

      CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables[<span class="hljs-string">"HTTP_X_FORWARDED_FOR"];


      <span class="hljs-keyword">if (!String.IsNullOrEmpty(CustomerIP))
            <span class="hljs-keyword">return CustomerIP;

      <span class="hljs-keyword">if (System.Web.HttpContext.Current.Request.ServerVariables[<span class="hljs-string">"HTTP_VIA"] != <span class="hljs-literal">null)
      {
            CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables[<span class="hljs-string">"HTTP_X_FORWARDED_FOR"];
            <span class="hljs-keyword">if (CustomerIP == <span class="hljs-literal">null)
                CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables[<span class="hljs-string">"REMOTE_ADDR"];
      }
      <span class="hljs-keyword">else
      {
            CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables[<span class="hljs-string">"REMOTE_ADDR"];

      }

      <span class="hljs-keyword">if (<span class="hljs-keyword">string.Compare(CustomerIP, <span class="hljs-string">"unknown", <span class="hljs-literal">true) == <span class="hljs-number">0)
            <span class="hljs-keyword">return System.Web.HttpContext.Current.Request.UserHostAddress;
      <span class="hljs-keyword">return CustomerIP;
    }
    <span class="hljs-keyword">catch { }

    <span class="hljs-keyword">return userIP;
}




<span class="hljs-function"><span class="hljs-keyword">private <span class="hljs-keyword">static <span class="hljs-keyword">bool <span class="hljs-title">CheckValidationResult(<span class="hljs-params"><span class="hljs-keyword">object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
    <span class="hljs-keyword">return <span class="hljs-literal">true; <span class="hljs-comment">//总是接受   
}

<span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">static HttpWebResponse <span class="hljs-title">CreatePostHttpResponse(<span class="hljs-params"><span class="hljs-keyword">string url, <span class="hljs-keyword">string datas, Encoding charset)
{
    HttpWebRequest request = <span class="hljs-literal">null;
    <span class="hljs-comment">//HTTPSQ请求
    ServicePointManager.ServerCertificateValidationCallback = <span class="hljs-keyword">new RemoteCertificateValidationCallback(CheckValidationResult);
    request = WebRequest.Create(url) <span class="hljs-keyword">as HttpWebRequest;
    request.ProtocolVersion = HttpVersion.Version10;
    request.Method = <span class="hljs-string">"POST";
    request.ContentType = <span class="hljs-string">"application/x-www-form-urlencoded";

    <span class="hljs-comment">//如果需要POST数据   
    <span class="hljs-comment">//if (!(parameters == null || parameters.Count == 0))
    <span class="hljs-comment">//{
    StringBuilder buffer = <span class="hljs-keyword">new StringBuilder();
    <span class="hljs-comment">//int i = 0;
    <span class="hljs-comment">//foreach (string key in parameters.Keys)
    <span class="hljs-comment">//{
    <span class="hljs-comment">//    if (i &gt; 0)
    <span class="hljs-comment">//    {
    <span class="hljs-comment">//      buffer.AppendFormat("&amp;{0}={1}", key, parameters);
    <span class="hljs-comment">//    }
    <span class="hljs-comment">//    else
    <span class="hljs-comment">//    {
    <span class="hljs-comment">//      buffer.AppendFormat("{0}={1}", key, parameters);
    <span class="hljs-comment">//    }
    <span class="hljs-comment">//    i++;
    <span class="hljs-comment">//}
    buffer.AppendFormat(datas);
    <span class="hljs-keyword">byte[] data = charset.GetBytes(buffer.ToString());
    <span class="hljs-keyword">using (Stream stream = request.GetRequestStream())
    {
      stream.Write(data, <span class="hljs-number">0, data.Length);
    }
    <span class="hljs-comment">//}
    <span class="hljs-keyword">return request.GetResponse() <span class="hljs-keyword">as HttpWebResponse;
}


<span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">string <span class="hljs-title">GetSignString(<span class="hljs-params">Dictionary&lt;<span class="hljs-keyword">string, <span class="hljs-keyword">string&gt; dic)
{
    <span class="hljs-keyword">string key = System.Web.Configuration.WebConfigurationManager.AppSettings[<span class="hljs-string">"key"].ToString();<span class="hljs-comment">//商户平台 API安全里面设置的KEY32位长度
                                                                                                <span class="hljs-comment">//排序
    dic = dic.OrderBy(d =&gt; d.Key).ToDictionary(d =&gt; d.Key, d =&gt; d.Value);
    <span class="hljs-comment">//连接字段
    <span class="hljs-keyword">var sign = dic.Aggregate(<span class="hljs-string">"", (current, d) =&gt; current + (d.Key + <span class="hljs-string">"=" + d.Value + <span class="hljs-string">"&amp;"));
    sign += <span class="hljs-string">"key=" + key;
    <span class="hljs-comment">//MD5
    <span class="hljs-comment">// sign = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sign, "MD5").ToUpper();
    System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
    sign = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(sign))).Replace(<span class="hljs-string">"-", <span class="hljs-literal">null);
    <span class="hljs-keyword">return sign;
}


<span class="hljs-comment"><span class="hljs-doctag">/// <span class="hljs-doctag">&lt;summary&gt;
<span class="hljs-comment"><span class="hljs-doctag">/// 获取时间戳
<span class="hljs-comment"><span class="hljs-doctag">/// <span class="hljs-doctag">&lt;/summary&gt;
<span class="hljs-comment"><span class="hljs-doctag">/// <span class="hljs-doctag">&lt;returns&gt;<span class="hljs-doctag">&lt;/returns&gt;
<span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">static <span class="hljs-keyword">string <span class="hljs-title">GetTimeStamp(<span class="hljs-params">)
{
    TimeSpan ts = DateTime.UtcNow - <span class="hljs-keyword">new DateTime(<span class="hljs-number">1970, <span class="hljs-number">1, <span class="hljs-number">1, <span class="hljs-number">0, <span class="hljs-number">0, <span class="hljs-number">0, <span class="hljs-number">0);
    <span class="hljs-keyword">return Convert.ToInt64(ts.TotalSeconds).ToString();
}

}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p><span style="font-size: 18px"><span style="font-size: 18px"><span style="color: rgba(86, 95, 105, 1); line-height: 25.2px; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px"><br style="color: rgba(86, 95, 105, 1); line-height: 25.2px; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px"><br style="color: rgba(86, 95, 105, 1); line-height: 25.2px; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px"><br style="color: rgba(86, 95, 105, 1); line-height: 25.2px; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px"></span></span></span></p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px">&nbsp;</p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px"><span style="font-size: 18px">&nbsp; &nbsp; &nbsp; 微信返回信息接收后台页面notify_url.ashx</span></p>
<p style="color: rgba(86, 95, 105, 1); line-height: 2; font-family: &quot;Microsoft Yahei&quot;; font-size: 14px">&nbsp;</p>
<pre><code class="hljs cs">&lt;%@ WebHandler Language=<span class="hljs-string">"C#" Class=<span class="hljs-string">"notify_url" %&gt;

<span class="hljs-keyword">using System;
<span class="hljs-keyword">using System.Web;
<span class="hljs-keyword">using System.Collections.Generic;
<span class="hljs-keyword">using System.Data;
<span class="hljs-keyword">using System.IO;
<span class="hljs-keyword">using System.Text;
<span class="hljs-keyword">using System.Xml;
<span class="hljs-keyword">using System.Net;
<span class="hljs-keyword">public <span class="hljs-keyword">class <span class="hljs-title">notify_url : <span class="hljs-title">IHttpHandler
{
    <span class="hljs-keyword">public <span class="hljs-keyword">string return_result = <span class="hljs-string">"";
    <span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">void <span class="hljs-title">ProcessRequest(<span class="hljs-params">HttpContext context)
    {
      context.Response.ContentType = <span class="hljs-string">"text/plain";
      context.Response.Write(<span class="hljs-string">"Hello World");


      String xmlData = getPostStr();<span class="hljs-comment">//获取请求数据
      <span class="hljs-keyword">if (xmlData == <span class="hljs-string">"")
      {

      }
      <span class="hljs-keyword">else
      {
            <span class="hljs-keyword">var dic = <span class="hljs-keyword">new Dictionary&lt;<span class="hljs-keyword">string, <span class="hljs-keyword">string&gt;
{
    {<span class="hljs-string">"return_code", <span class="hljs-string">"SUCCESS"},
    {<span class="hljs-string">"return_msg",<span class="hljs-string">"OK"}

};
            <span class="hljs-keyword">var sb = <span class="hljs-keyword">new StringBuilder();
            sb.Append(<span class="hljs-string">"&lt;xml&gt;");


            <span class="hljs-keyword">foreach (<span class="hljs-keyword">var d <span class="hljs-keyword">in dic)
            {
                sb.Append(<span class="hljs-string">"&lt;" + d.Key + <span class="hljs-string">"&gt;" + d.Value + <span class="hljs-string">"&lt;/" + d.Key + <span class="hljs-string">"&gt;");
            }
            sb.Append(<span class="hljs-string">"&lt;/xml&gt;");





            <span class="hljs-comment">//把数据重新返回给客户端
            DataSet ds = <span class="hljs-keyword">new DataSet();
            StringReader stram = <span class="hljs-keyword">new StringReader(xmlData);
            XmlTextReader datareader = <span class="hljs-keyword">new XmlTextReader(stram);
            ds.ReadXml(datareader);
            <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"return_code"].ToString() == <span class="hljs-string">"SUCCESS")
            {


                <span class="hljs-keyword">string wx_appid = <span class="hljs-string">"";<span class="hljs-comment">//微信开放平台审核通过的应用APPID
                <span class="hljs-keyword">string wx_mch_id = <span class="hljs-string">"";<span class="hljs-comment">//微信支付分配的商户号

                <span class="hljs-keyword">string wx_nonce_str = <span class="hljs-string">"";<span class="hljs-comment">//         随机字符串,不长于32位
                <span class="hljs-keyword">string wx_sign = <span class="hljs-string">"";<span class="hljs-comment">//签名,详见签名算法
                <span class="hljs-keyword">string wx_result_code = <span class="hljs-string">"";<span class="hljs-comment">//SUCCESS/FAIL

                <span class="hljs-keyword">string wx_return_code = <span class="hljs-string">"";
                <span class="hljs-keyword">string wx_openid = <span class="hljs-string">"";<span class="hljs-comment">//用户在商户appid下的唯一标识
                <span class="hljs-keyword">string wx_is_subscribe = <span class="hljs-string">"";<span class="hljs-comment">//用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效
                <span class="hljs-keyword">string wx_trade_type = <span class="hljs-string">"";<span class="hljs-comment">//         APP
                <span class="hljs-keyword">string wx_bank_type = <span class="hljs-string">"";<span class="hljs-comment">//         银行类型,采用字符串类型的银行标识,银行类型见银行列表
                <span class="hljs-keyword">string wx_fee_type = <span class="hljs-string">"";<span class="hljs-comment">//         货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型


                <span class="hljs-keyword">string wx_transaction_id = <span class="hljs-string">"";<span class="hljs-comment">//微信支付订单号
                <span class="hljs-keyword">string wx_out_trade_no = <span class="hljs-string">"";<span class="hljs-comment">//商户系统的订单号,与请求一致。
                <span class="hljs-keyword">string wx_time_end = <span class="hljs-string">"";<span class="hljs-comment">//         支付完成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
                <span class="hljs-keyword">int wx_total_fee = <span class="hljs-number">-1;<span class="hljs-comment">//         订单总金额,单位为分
                <span class="hljs-keyword">int wx_cash_fee = <span class="hljs-number">-1;<span class="hljs-comment">//现金支付金额订单现金支付金额,详见支付金额


                <span class="hljs-meta">#<span class="hljs-meta-keyword">region数据解析
                <span class="hljs-comment">//列 是否存在
                <span class="hljs-keyword">string signstr = <span class="hljs-string">"";<span class="hljs-comment">//需要前面的字符串
                                    <span class="hljs-comment">//wx_appid
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"appid"))
                {
                  wx_appid = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"appid"].ToString();
                  <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(wx_appid))
                  {
                        signstr += <span class="hljs-string">"appid=" + wx_appid;
                  }
                }

                <span class="hljs-comment">//wx_bank_type
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"bank_type"))
                {
                  wx_bank_type = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"bank_type"].ToString();
                  <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(wx_bank_type))
                  {
                        signstr += <span class="hljs-string">"&amp;bank_type=" + wx_bank_type;
                  }
                }
                <span class="hljs-comment">//wx_cash_fee
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"cash_fee"))
                {
                  wx_cash_fee = Convert.ToInt32(ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"cash_fee"].ToString());

                  signstr += <span class="hljs-string">"&amp;cash_fee=" + wx_cash_fee;
                }

                <span class="hljs-comment">//wx_fee_type
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"fee_type"))
                {
                  wx_fee_type = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"fee_type"].ToString();
                  <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(wx_fee_type))
                  {
                        signstr += <span class="hljs-string">"&amp;fee_type=" + wx_fee_type;
                  }
                }

                <span class="hljs-comment">//wx_is_subscribe
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"is_subscribe"))
                {
                  wx_is_subscribe = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"is_subscribe"].ToString();
                  <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(wx_is_subscribe))
                  {
                        signstr += <span class="hljs-string">"&amp;is_subscribe=" + wx_is_subscribe;
                  }
                }

                <span class="hljs-comment">//wx_mch_id
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"mch_id"))
                {
                  wx_mch_id = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"mch_id"].ToString();
                  <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(wx_mch_id))
                  {
                        signstr += <span class="hljs-string">"&amp;mch_id=" + wx_mch_id;
                  }
                }

                <span class="hljs-comment">//wx_nonce_str
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"nonce_str"))
                {
                  wx_nonce_str = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"nonce_str"].ToString();
                  <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(wx_nonce_str))
                  {
                        signstr += <span class="hljs-string">"&amp;nonce_str=" + wx_nonce_str;
                  }
                }

                <span class="hljs-comment">//wx_openid
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"openid"))
                {
                  wx_openid = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"openid"].ToString();
                  <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(wx_openid))
                  {
                        signstr += <span class="hljs-string">"&amp;openid=" + wx_openid;
                  }
                }

                <span class="hljs-comment">//wx_out_trade_no
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"out_trade_no"))
                {
                  wx_out_trade_no = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"out_trade_no"].ToString();
                  <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(wx_out_trade_no))
                  {
                        signstr += <span class="hljs-string">"&amp;out_trade_no=" + wx_out_trade_no;
                  }
                }

                <span class="hljs-comment">//wx_result_code
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"result_code"))
                {
                  wx_result_code = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"result_code"].ToString();
                  <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(wx_result_code))
                  {
                        signstr += <span class="hljs-string">"&amp;result_code=" + wx_result_code;
                  }
                }

                <span class="hljs-comment">//wx_result_code
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"return_code"))
                {
                  wx_return_code = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"return_code"].ToString();
                  <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(wx_return_code))
                  {
                        signstr += <span class="hljs-string">"&amp;return_code=" + wx_return_code;
                  }
                }

                <span class="hljs-comment">//wx_sign
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"sign"))
                {
                  wx_sign = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"sign"].ToString();
                  <span class="hljs-comment">//if (!string.IsNullOrEmpty(wx_sign))
                  <span class="hljs-comment">//{
                  <span class="hljs-comment">//    signstr += "&amp;sign=" + wx_sign;
                  <span class="hljs-comment">//}
                }

                <span class="hljs-comment">//wx_time_end
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"time_end"))
                {
                  wx_time_end = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"time_end"].ToString();
                  <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(wx_time_end))
                  {
                        signstr += <span class="hljs-string">"&amp;time_end=" + wx_time_end;
                  }
                }

                <span class="hljs-comment">//wx_total_fee
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"total_fee"))
                {
                  wx_total_fee = Convert.ToInt32(ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"total_fee"].ToString());

                  signstr += <span class="hljs-string">"&amp;total_fee=" + wx_total_fee;
                }

                <span class="hljs-comment">//wx_trade_type
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"trade_type"))
                {
                  wx_trade_type = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"trade_type"].ToString();
                  <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(wx_trade_type))
                  {
                        signstr += <span class="hljs-string">"&amp;trade_type=" + wx_trade_type;
                  }
                }

                <span class="hljs-comment">//wx_transaction_id
                <span class="hljs-keyword">if (ds.Tables[<span class="hljs-number">0].Columns.Contains(<span class="hljs-string">"transaction_id"))
                {
                  wx_transaction_id = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"transaction_id"].ToString();
                  <span class="hljs-keyword">if (!<span class="hljs-keyword">string.IsNullOrEmpty(wx_transaction_id))
                  {
                        signstr += <span class="hljs-string">"&amp;transaction_id=" + wx_transaction_id;
                  }
                }

                <span class="hljs-meta">#<span class="hljs-meta-keyword">endregion

                <span class="hljs-comment">//追加key 密钥
                signstr += <span class="hljs-string">"&amp;key=" + System.Web.Configuration.WebConfigurationManager.AppSettings[<span class="hljs-string">"key"].ToString();
                <span class="hljs-comment">//签名正确
                <span class="hljs-keyword">string orderStrwhere = <span class="hljs-string">"ordernumber='" + wx_out_trade_no + <span class="hljs-string">"'";



                <span class="hljs-keyword">if (wx_sign == System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(signstr, <span class="hljs-string">"MD5").ToUpper())
                {
                  <span class="hljs-comment">//签名正确   处理订单操作逻辑


                }
                <span class="hljs-keyword">else
                {
                  <span class="hljs-comment">//追加备注信息

                }

            }
            <span class="hljs-keyword">else
            {
                <span class="hljs-comment">// 返回信息,如非空,为错误原因签名失败 参数格式校验错误
                <span class="hljs-keyword">string return_msg = ds.Tables[<span class="hljs-number">0].Rows[<span class="hljs-number">0][<span class="hljs-string">"return_msg"].ToString();

            }


            return_result = sb.ToString();
      }
    }


    <span class="hljs-keyword">public <span class="hljs-keyword">bool IsReusable
    {
      <span class="hljs-keyword">get
      {
            <span class="hljs-keyword">return <span class="hljs-literal">false;
      }
    }

    <span class="hljs-comment">//获得Post过来的数据
    <span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">string <span class="hljs-title">getPostStr(<span class="hljs-params">)
    {
      Int32 intLen = Convert.ToInt32(System.Web.HttpContext.Current.Request.InputStream.Length);
      <span class="hljs-keyword">byte[] b = <span class="hljs-keyword">new <span class="hljs-keyword">byte;
      System.Web.HttpContext.Current.Request.InputStream.Read(b, <span class="hljs-number">0, intLen);
      <span class="hljs-keyword">return System.Text.Encoding.UTF8.GetString(b);
    }
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre><br><br>
来源:https://www.cnblogs.com/ws-yizhiduxiu/p/11320994.html
頁: [1]
查看完整版本: 微信小程序支付功能 C# .NET开发