用户
 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,登录网站

小程序社区 首页 教程 实战教程 查看内容

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

Rolan 2017-5-22 13:22

微信小程序支付功能的开发的时候坑比较多,不过对于钱的事谨慎也是好事。网上关于小程序支付的实例很多,但是大多多少有些问题,C#开发的更少。此篇文档的目的是讲开发过程中遇到的问题做一个备注,也方便其他开发的 ...

微信小程序支付功能的开发的时候坑比较多,不过对于钱的事谨慎也是好事。网上关于小程序支付的实例很多,但是大多多少有些问题,C#开发的更少。此篇文档的目的是讲开发过程中遇到的问题做一个备注,也方便其他开发的同学作为参考!

  1. 1、首先建议把官方文档支付部分看上三遍,每个细节都不要放过,因为任何一个点和微信要求不符都会导致支付不成功。https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=3_1
  2. 2、经过验证的微信支付功能,会需要一些商户号、支付秘钥等,不要搞混。
  3. 3、经常遇到的是“签名错误”,请仔细看需要传送的xml参数及取值规则是否符合微信规则。微信有个验证工具可以验证发送的xml字段是否合法。

下面上代码:

web.config

  1. <add key="ConnectionString" value="server=127.0.0.1;database=;uid=sa;pwd="/>
  2. <add key="ConnectionString2" value="server=127.0.0.1;database=codematic2;uid=sa;pwd=1"/>
  3. <add key="appid" value=""/>//appid
  4. <add key="secret" value=""/>//小程序秘钥
  5. <add key="mch_id" value=""/>//商户号
  6. <add key="key" value=""/>//支付秘钥
  7. <add key="ip" value=""/>//服务器IP
  8. <add key="PayResulturl" value=""/>//微信返回接收信息的url地址
  9. </appSettings>

支付后台xiadan.ashx

  1. <%@ WebHandler Language="C#" Class="xiadan" %>
  2. using System;
  3. using System.Web;
  4. using System.Net;
  5. using System.IO;
  6. using System.Configuration;
  7. using Maticsoft.Model;
  8. using Maticsoft.BLL;
  9. using System.Security.Cryptography;
  10. using System.Text;
  11. using System.Xml.Serialization;
  12. using System.Xml;
  13. using System.Collections.Generic;
  14. using System.Data;
  15. using System.Net.Security;
  16. using System.Security.Cryptography.X509Certificates;
  17. using System.Linq;
  18. using Newtonsoft.Json;
  19. public class xiadan : IHttpHandler
  20. {
  21. public void ProcessRequest(HttpContext context)
  22. {
  23. context.Response.ContentType = "text/plain";
  24. string openid = context.Request.Params["openid"];
  25. string ordertime = context.Request.Params["ordertime"];
  26. string appid = ConfigurationManager.AppSettings["appid"];
  27. string secret = ConfigurationManager.AppSettings["secret"];
  28. string key = ConfigurationManager.AppSettings["key"];
  29. string mch_id = ConfigurationManager.AppSettings["mch_id"];
  30. string ip = ConfigurationManager.AppSettings["ip"];
  31. string PayResulturl = ConfigurationManager.AppSettings["PayResulturl"];
  32. string roomid = context.Request.Params["roomid"];
  33. string aa = "-押金";////商品描述交易字段格式根据不同的应用场景按照以下格式:APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。
  34. string strcode = aa;
  35. byte[] buffer = Encoding.UTF8.GetBytes(strcode);
  36. string body = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
  37. string totalfee = context.Request.Params["totalfee"];
  38. string output = "";
  39. if ((context.Request.Params["openid"] != null) && (context.Request.Params["openid"] != ""))
  40. {
  41. //OrderInfo order = new OrderInfo();
  42. //order.appid = appid;
  43. System.Random Random = new System.Random();
  44. var dic = new Dictionary<string, string>
  45. {
  46. {"appid", appid},
  47. {"mch_id", mch_id},
  48. {"nonce_str", GetRandomString(20)/*Random.Next().ToString()*/},
  49. {"body",body},
  50. {"out_trade_no",roomid + DateTime.Now.ToString("yyyyMMddHHmmssfff") + Random.Next(999).ToString()},//商户自己的订单号码
  51. {"total_fee",totalfee},
  52. {"spbill_create_ip",ip},//服务器的IP地址
  53. {"notify_url",PayResulturl},//异步通知的地址,不能带参数
  54. {"trade_type","JSAPI" },
  55. {"openid",openid}
  56. };
  57. //加入签名
  58. dic.Add("sign", GetSignString(dic));
  59. var sb = new StringBuilder();
  60. sb.Append("<xml>");
  61. foreach (var d in dic)
  62. {
  63. sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">");
  64. }
  65. sb.Append("</xml>");
  66. var xml = new XmlDocument();
  67. // xml.LoadXml(GetPostString("https://api.mch.weixin.qq.com/pay/unifiedorder", sb.ToString()));
  68. CookieCollection coo = new CookieCollection();
  69. Encoding en = Encoding.GetEncoding("UTF-8");
  70. HttpWebResponse response = CreatePostHttpResponse("https://api.mch.weixin.qq.com/pay/unifiedorder", sb.ToString(), en);
  71. //打印返回值
  72. Stream stream = response.GetResponseStream(); //获取响应的字符串流
  73. StreamReader sr = new StreamReader(stream); //创建一个stream读取流
  74. string html = sr.ReadToEnd(); //从头读到尾,放到字符串html
  75. //Console.WriteLine(html);
  76. xml.LoadXml(html);
  77. //对请求返回值 进行处理
  78. var root = xml.DocumentElement;
  79. DataSet ds = new DataSet();
  80. StringReader stram = new StringReader(html);
  81. XmlTextReader reader = new XmlTextReader(stram);
  82. ds.ReadXml(reader);
  83. string return_code = ds.Tables[0].Rows[0]["return_code"].ToString();
  84. if (return_code.ToUpper() == "SUCCESS")
  85. {
  86. //通信成功
  87. string result_code = ds.Tables[0].Rows[0]["result_code"].ToString();//业务结果
  88. if (result_code.ToUpper() == "SUCCESS")
  89. {
  90. var res = new Dictionary<string, string>
  91. {
  92. {"appId", appid},
  93. {"timeStamp", GetTimeStamp()},
  94. {"nonceStr", dic["nonce_str"]},
  95. {"package", "prepay_id="+ds.Tables[0].Rows[0]["prepay_id"].ToString()},
  96. {"signType", "MD5"}
  97. };
  98. //在服务器上签名
  99. res.Add("paySign", GetSignString(res));
  100. // string signapp = res.ToString();
  101. string signapp = JsonConvert.SerializeObject(res);
  102. if ((context.Request.Params["openid"] != null) && (context.Request.Params["openid"] != ""))
  103. {
  104. //存储订单信息
  105. Maticsoft.Model.order_history oh = new Maticsoft.Model.order_history();
  106. //oh.shop_id =
  107. oh.room_id = Convert.ToInt32(roomid);
  108. oh.pay_price = Convert.ToDecimal(totalfee);
  109. oh.out_trade_no = dic["out_trade_no"];
  110. oh.order_timestart = Convert.ToDateTime(ordertime);
  111. oh.openid = openid;
  112. oh.creating_date = DateTime.Now;
  113. Maticsoft.BLL.order_history bll = new Maticsoft.BLL.order_history();
  114. bll.Add(oh);
  115. }
  116. context.Response.Write(signapp);
  117. }
  118. }
  119. }
  120. context.Response.Write(output);
  121. }
  122. public bool IsReusable
  123. {
  124. get
  125. {
  126. return false;
  127. }
  128. }
  129. public string GetMd5Hash(String input)
  130. {
  131. if (input == null)
  132. {
  133. return null;
  134. }
  135. MD5 md5Hash = MD5.Create();
  136. // 将输入字符串转换为字节数组并计算哈希数据
  137. byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
  138. // 创建一个 Stringbuilder 来收集字节并创建字符串
  139. StringBuilder sBuilder = new StringBuilder();
  140. // 循环遍历哈希数据的每一个字节并格式化为十六进制字符串
  141. for (int i = 0; i < data.Length; i++)
  142. {
  143. sBuilder.Append(data[i].ToString());
  144. }
  145. // 返回十六进制字符串
  146. return sBuilder.ToString();
  147. }
  148. /// <summary>
  149. /// 对象序列化成 XML String
  150. /// </summary>
  151. public static string XmlSerialize<T>(T obj)
  152. {
  153. string xmlString = string.Empty;
  154. XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
  155. using (MemoryStream ms = new MemoryStream())
  156. {
  157. xmlSerializer.Serialize(ms, obj);
  158. xmlString = Encoding.UTF8.GetString(ms.ToArray());
  159. }
  160. return xmlString;
  161. }
  162. /// <summary>
  163. /// 从字符串里随机得到,规定个数的字符串.
  164. /// </summary>
  165. /// <param name="allChar"></param>
  166. /// <param name="CodeCount"></param>
  167. /// <returns></returns>
  168. public static string GetRandomString(int CodeCount)
  169. {
  170. string allChar = "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";
  171. string[] allCharArray = allChar.Split(',');
  172. string RandomCode = "";
  173. int temp = -1;
  174. Random rand = new Random();
  175. for (int i = 0; i < CodeCount; i++)
  176. {
  177. if (temp != -1)
  178. {
  179. rand = new Random(temp * i * ((int)DateTime.Now.Ticks));
  180. }
  181. int t = rand.Next(allCharArray.Length - 1);
  182. while (temp == t)
  183. {
  184. t = rand.Next(allCharArray.Length - 1);
  185. }
  186. temp = t;
  187. RandomCode += allCharArray[t];
  188. }
  189. return RandomCode;
  190. }
  191. public static string GetWebClientIp()
  192. {
  193. string userIP = "IP";
  194. try
  195. {
  196. if (System.Web.HttpContext.Current == null
  197. || System.Web.HttpContext.Current.Request == null
  198. || System.Web.HttpContext.Current.Request.ServerVariables == null)
  199. return "";
  200. string CustomerIP = "";
  201. //CDN加速后取到的IP
  202. CustomerIP = System.Web.HttpContext.Current.Request.Headers["Cdn-Src-Ip"];
  203. if (!string.IsNullOrEmpty(CustomerIP))
  204. {
  205. return CustomerIP;
  206. }
  207. CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
  208. if (!String.IsNullOrEmpty(CustomerIP))
  209. return CustomerIP;
  210. if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)
  211. {
  212. CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
  213. if (CustomerIP == null)
  214. CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
  215. }
  216. else
  217. {
  218. CustomerIP = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
  219. }
  220. if (string.Compare(CustomerIP, "unknown", true) == 0)
  221. return System.Web.HttpContext.Current.Request.UserHostAddress;
  222. return CustomerIP;
  223. }
  224. catch { }
  225. return userIP;
  226. }
  227. private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
  228. {
  229. return true; //总是接受
  230. }
  231. public static HttpWebResponse CreatePostHttpResponse(string url, string datas, Encoding charset)
  232. {
  233. HttpWebRequest request = null;
  234. //HTTPSQ请求
  235. ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
  236. request = WebRequest.Create(url) as HttpWebRequest;
  237. request.ProtocolVersion = HttpVersion.Version10;
  238. request.Method = "POST";
  239. request.ContentType = "application/x-www-form-urlencoded";
  240. //如果需要POST数据
  241. //if (!(parameters == null || parameters.Count == 0))
  242. //{
  243. StringBuilder buffer = new StringBuilder();
  244. //int i = 0;
  245. //foreach (string key in parameters.Keys)
  246. //{
  247. // if (i > 0)
  248. // {
  249. // buffer.AppendFormat("&{0}={1}", key, parameters[key]);
  250. // }
  251. // else
  252. // {
  253. // buffer.AppendFormat("{0}={1}", key, parameters[key]);
  254. // }
  255. // i++;
  256. //}
  257. buffer.AppendFormat(datas);
  258. byte[] data = charset.GetBytes(buffer.ToString());
  259. using (Stream stream = request.GetRequestStream())
  260. {
  261. stream.Write(data, 0, data.Length);
  262. }
  263. //}
  264. return request.GetResponse() as HttpWebResponse;
  265. }
  266. public string GetSignString(Dictionary<string, string> dic)
  267. {
  268. string key = System.Web.Configuration.WebConfigurationManager.AppSettings["key"].ToString();//商户平台 API安全里面设置的KEY 32位长度
  269. //排序
  270. dic = dic.OrderBy(d => d.Key).ToDictionary(d => d.Key, d => d.Value);
  271. //连接字段
  272. var sign = dic.Aggregate("", (current, d) => current + (d.Key + "=" + d.Value + "&"));
  273. sign += "key=" + key;
  274. //MD5
  275. // sign = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sign, "MD5").ToUpper();
  276. System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
  277. sign = BitConverter.ToString(md5.ComputeHash(Encoding.UTF8.GetBytes(sign))).Replace("-", null);
  278. return sign;
  279. }
  280. /// <summary>
  281. /// 获取时间戳
  282. /// </summary>
  283. /// <returns></returns>
  284. public static string GetTimeStamp()
  285. {
  286. TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
  287. return Convert.ToInt64(ts.TotalSeconds).ToString();
  288. }
  289. }

微信返回信息接收后台页面notify_url.ashx

  1. <%@ WebHandler Language="C#" Class="notify_url" %>
  2. using System;
  3. using System.Web;
  4. using System.Collections.Generic;
  5. using System.Data;
  6. using System.IO;
  7. using System.Text;
  8. using System.Xml;
  9. using System.Net;
  10. public class notify_url : IHttpHandler
  11. {
  12. public string return_result = "";
  13. public void ProcessRequest(HttpContext context)
  14. {
  15. context.Response.ContentType = "text/plain";
  16. context.Response.Write("Hello World");
  17. String xmlData = getPostStr();//获取请求数据
  18. if (xmlData == "")
  19. {
  20. }
  21. else
  22. {
  23. var dic = new Dictionary<string, string>
  24. {
  25. {"return_code", "SUCCESS"},
  26. {"return_msg","OK"}
  27. };
  28. var sb = new StringBuilder();
  29. sb.Append("<xml>");
  30. foreach (var d in dic)
  31. {
  32. sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">");
  33. }
  34. sb.Append("</xml>");
  35. //把数据重新返回给客户端
  36. DataSet ds = new DataSet();
  37. StringReader stram = new StringReader(xmlData);
  38. XmlTextReader datareader = new XmlTextReader(stram);
  39. ds.ReadXml(datareader);
  40. if (ds.Tables[0].Rows[0]["return_code"].ToString() == "SUCCESS")
  41. {
  42. string wx_appid = "";//微信开放平台审核通过的应用APPID
  43. string wx_mch_id = "";//微信支付分配的商户号
  44. string wx_nonce_str = "";// 随机字符串,不长于32位
  45. string wx_sign = "";//签名,详见签名算法
  46. string wx_result_code = "";//SUCCESS/FAIL
  47. string wx_return_code = "";
  48. string wx_openid = "";//用户在商户appid下的唯一标识
  49. string wx_is_subscribe = "";//用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效
  50. string wx_trade_type = "";// APP
  51. string wx_bank_type = "";// 银行类型,采用字符串类型的银行标识,银行类型见银行列表
  52. string wx_fee_type = "";// 货币类型,符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
  53. string wx_transaction_id = "";//微信支付订单号
  54. string wx_out_trade_no = "";//商户系统的订单号,与请求一致。
  55. string wx_time_end = "";// 支付完成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
  56. int wx_total_fee = -1;// 订单总金额,单位为分
  57. int wx_cash_fee = -1;//现金支付金额订单现金支付金额,详见支付金额
  58. #region 数据解析
  59. //列 是否存在
  60. string signstr = "";//需要前面的字符串
  61. //wx_appid
  62. if (ds.Tables[0].Columns.Contains("appid"))
  63. {
  64. wx_appid = ds.Tables[0].Rows[0]["appid"].ToString();
  65. if (!string.IsNullOrEmpty(wx_appid))
  66. {
  67. signstr += "appid=" + wx_appid;
  68. }
  69. }
  70. //wx_bank_type
  71. if (ds.Tables[0].Columns.Contains("bank_type"))
  72. {
  73. wx_bank_type = ds.Tables[0].Rows[0]["bank_type"].ToString();
  74. if (!string.IsNullOrEmpty(wx_bank_type))
  75. {
  76. signstr += "&bank_type=" + wx_bank_type;
  77. }
  78. }
  79. //wx_cash_fee
  80. if (ds.Tables[0].Columns.Contains("cash_fee"))
  81. {
  82. wx_cash_fee = Convert.ToInt32(ds.Tables[0].Rows[0]["cash_fee"].ToString());
  83. signstr += "&cash_fee=" + wx_cash_fee;
  84. }
  85. //wx_fee_type
  86. if (ds.Tables[0].Columns.Contains("fee_type"))
  87. {
  88. wx_fee_type = ds.Tables[0].Rows[0]["fee_type"].ToString();
  89. if (!string.IsNullOrEmpty(wx_fee_type))
  90. {
  91. signstr += "&fee_type=" + wx_fee_type;
  92. }
  93. }
  94. //wx_is_subscribe
  95. if (ds.Tables[0].Columns.Contains("is_subscribe"))
  96. {
  97. wx_is_subscribe = ds.Tables[0].Rows[0]["is_subscribe"].ToString();
  98. if (!string.IsNullOrEmpty(wx_is_subscribe))
  99. {
  100. signstr += "&is_subscribe=" + wx_is_subscribe;
  101. }
  102. }
  103. //wx_mch_id
  104. if (ds.Tables[0].Columns.Contains("mch_id"))
  105. {
  106. wx_mch_id = ds.Tables[0].Rows[0]["mch_id"].ToString();
  107. if (!string.IsNullOrEmpty(wx_mch_id))
  108. {
  109. signstr += "&mch_id=" + wx_mch_id;
  110. }
  111. }
  112. //wx_nonce_str
  113. if (ds.Tables[0].Columns.Contains("nonce_str"))
  114. {
  115. wx_nonce_str = ds.Tables[0].Rows[0]["nonce_str"].ToString();
  116. if (!string.IsNullOrEmpty(wx_nonce_str))
  117. {
  118. signstr += "&nonce_str=" + wx_nonce_str;
  119. }
  120. }
  121. //wx_openid
  122. if (ds.Tables[0].Columns.Contains("openid"))
  123. {
  124. wx_openid = ds.Tables[0].Rows[0]["openid"].ToString();
  125. if (!string.IsNullOrEmpty(wx_openid))
  126. {
  127. signstr += "&openid=" + wx_openid;
  128. }
  129. }
  130. //wx_out_trade_no
  131. if (ds.Tables[0].Columns.Contains("out_trade_no"))
  132. {
  133. wx_out_trade_no = ds.Tables[0].Rows[0]["out_trade_no"].ToString();
  134. if (!string.IsNullOrEmpty(wx_out_trade_no))
  135. {
  136. signstr += "&out_trade_no=" + wx_out_trade_no;
  137. }
  138. }
  139. //wx_result_code
  140. if (ds.Tables[0].Columns.Contains("result_code"))
  141. {
  142. wx_result_code = ds.Tables[0].Rows[0]["result_code"].ToString();
  143. if (!string.IsNullOrEmpty(wx_result_code))
  144. {
  145. signstr += "&result_code=" + wx_result_code;
  146. }
  147. }
  148. //wx_result_code
  149. if (ds.Tables[0].Columns.Contains("return_code"))
  150. {
  151. wx_return_code = ds.Tables[0].Rows[0]["return_code"].ToString();
  152. if (!string.IsNullOrEmpty(wx_return_code))
  153. {
  154. signstr += "&return_code=" + wx_return_code;
  155. }
  156. }
  157. //wx_sign
  158. if (ds.Tables[0].Columns.Contains("sign"))
  159. {
  160. wx_sign = ds.Tables[0].Rows[0]["sign"].ToString();
  161. //if (!string.IsNullOrEmpty(wx_sign))
  162. //{
  163. // signstr += "&sign=" + wx_sign;
  164. //}
  165. }
  166. //wx_time_end
  167. if (ds.Tables[0].Columns.Contains("time_end"))
  168. {
  169. wx_time_end = ds.Tables[0].Rows[0]["time_end"].ToString();
  170. if (!string.IsNullOrEmpty(wx_time_end))
  171. {
  172. signstr += "&time_end=" + wx_time_end;
  173. }
  174. }
  175. //wx_total_fee
  176. if (ds.Tables[0].Columns.Contains("total_fee"))
  177. {
  178. wx_total_fee = Convert.ToInt32(ds.Tables[0].Rows[0]["total_fee"].ToString());
  179. signstr += "&total_fee=" + wx_total_fee;
  180. }
  181. //wx_trade_type
  182. if (ds.Tables[0].Columns.Contains("trade_type"))
  183. {
  184. wx_trade_type = ds.Tables[0].Rows[0]["trade_type"].ToString();
  185. if (!string.IsNullOrEmpty(wx_trade_type))
  186. {
  187. signstr += "&trade_type=" + wx_trade_type;
  188. }
  189. }
  190. //wx_transaction_id
  191. if (ds.Tables[0].Columns.Contains("transaction_id"))
  192. {
  193. wx_transaction_id = ds.Tables[0].Rows[0]["transaction_id"].ToString();
  194. if (!string.IsNullOrEmpty(wx_transaction_id))
  195. {
  196. signstr += "&transaction_id=" + wx_transaction_id;
  197. }
  198. }
  199. #endregion
  200. //追加key 密钥
  201. signstr += "&key=" + System.Web.Configuration.WebConfigurationManager.AppSettings["key"].ToString();
  202. //签名正确
  203. string orderStrwhere = "ordernumber='" + wx_out_trade_no + "'";
  204. if (wx_sign == System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(signstr, "MD5").ToUpper())
  205. {
  206. //签名正确 处理订单操作逻辑
  207. }
  208. else
  209. {
  210. //追加备注信息
  211. }
  212. }
  213. else
  214. {
  215. // 返回信息,如非空,为错误原因 签名失败 参数格式校验错误
  216. string return_msg = ds.Tables[0].Rows[0]["return_msg"].ToString();
  217. }
  218. return_result = sb.ToString();
  219. }
  220. }
  221. public bool IsReusable
  222. {
  223. get
  224. {
  225. return false;
  226. }
  227. }
  228. //获得Post过来的数据
  229. public string getPostStr()
  230. {
  231. Int32 intLen = Convert.ToInt32(System.Web.HttpContext.Current.Request.InputStream.Length);
  232. byte[] b = new byte[intLen];
  233. System.Web.HttpContext.Current.Request.InputStream.Read(b, 0, intLen);
  234. return System.Text.Encoding.UTF8.GetString(b);
  235. }
  236. }
鲜花
鲜花 (2)
鸡蛋
鸡蛋

刚表态过的朋友 (2 人)

分享至 : QQ空间
收藏
原作者: 东边的小山 来自: 博客园

相关阅读

  • admin 2018-7-23 15:17
    2929228727: 为什么赞赏了也看不到文章实际内容,请尽快处理!
    你好 同学 由于微信支付接口出现问题,导致我们赞赏功能暂时不能使用,为了避免给大家带来不便所以暂时关闭了赞赏功能呢,后期修复后我们会再上线的。
  • 2929228727 2017-11-9 14:29
    还是没有回复,骗谈不上,但是尊重用户我觉得还是有必要的
  • 2929228727 2017-11-9 12:10
    原文在这里,为什么不回复,http://blog.csdn.net/yelin042/article/details/72625069
  • 2929228727 2017-11-9 11:43
    为什么赞赏了也看不到文章实际内容,请尽快处理!