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

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

 

       1、首先建议把官方文档支付部分看上三遍,每个细节都不要放过,因为任何一个点和微信要求不符都会导致支付不成功。https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=3_1

      2、经过验证的微信支付功能,会需要一些商户号、支付秘钥等,不要搞混。

     3、经常遇到的是“签名错误”,请仔细看需要传送的xml参数及取值规则是否符合微信规则。微信有个验证工具可以验证发送的xml字段是否合法。

 

下面上代码:

 

web.config

 

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

支付后台xiadan.ashx

 

 

<%@ WebHandler Language="C#" Class="xiadan" %>

using System;
using System.Web;
using System.Net; using System.IO; using System.Configuration; using Maticsoft.Model; using Maticsoft.BLL; using System.Security.Cryptography; using System.Text; using System.Xml.Serialization; using System.Xml; using System.Collections.Generic; using System.Data; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Linq; using Newtonsoft.Json; public class xiadan : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; string openid = context.Request.Params["openid"]; string ordertime = context.Request.Params["ordertime"]; string appid = ConfigurationManager.AppSettings["appid"]; string secret = ConfigurationManager.AppSettings["secret"]; string key = ConfigurationManager.AppSettings["key"]; string mch_id = ConfigurationManager.AppSettings["mch_id"]; string ip = ConfigurationManager.AppSettings["ip"]; string PayResulturl = ConfigurationManager.AppSettings["PayResulturl"]; string roomid = context.Request.Params["roomid"]; string aa = "-押金";商品描述交易字段格式根据不同的应用场景按照以下格式:APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。 string strcode = aa; byte[] buffer = Encoding.UTF8.GetBytes(strcode); string body = Encoding.UTF8.GetString(buffer, 0, buffer.Length); string totalfee = context.Request.Params["totalfee"]; string output = ""; if ((context.Request.Params["openid"] != null) && (context.Request.Params["openid"] != "")) { //OrderInfo order = new OrderInfo(); //order.appid = appid; System.Random Random = new System.Random(); var dic = new Dictionary<string, string> { {"appid", appid}, {"mch_id", mch_id}, {"nonce_str", GetRandomString(20)/*Random.Next().ToString()*/}, {"body",body}, {"out_trade_no",roomid + DateTime.Now.ToString("yyyyMMddHHmmssfff") + Random.Next(999).ToString()},//商户自己的订单号码 {"total_fee",totalfee}, {"spbill_create_ip",ip},//服务器的IP地址 {"notify_url",PayResulturl},//异步通知的地址,不能带参数 {"trade_type","JSAPI" }, {"openid",openid} }; //加入签名 dic.Add("sign", GetSignString(dic)); var sb = new StringBuilder(); sb.Append("<xml>"); foreach (var d in dic) { sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">"); } sb.Append("</xml>"); var xml = new XmlDocument(); // xml.LoadXml(GetPostString("https://api.mch.weixin.qq.com/pay/unifiedorder", sb.ToString())); CookieCollection coo = new CookieCollection(); Encoding en = Encoding.GetEncoding("UTF-8"); HttpWebResponse response = CreatePostHttpResponse("https://api.mch.weixin.qq.com/pay/unifiedorder", sb.ToString(), en); //打印返回值 Stream stream = response.GetResponseStream(); //获取响应的字符串流 StreamReader sr = new StreamReader(stream); //创建一个stream读取流 string html = sr.ReadToEnd(); //从头读到尾,放到字符串html //Console.WriteLine(html); xml.LoadXml(html); //对请求返回值 进行处理 var root = xml.DocumentElement; DataSet ds = new DataSet(); StringReader stram = new StringReader(html); XmlTextReader reader = new XmlTextReader(stram); ds.ReadXml(reader); string return_code = ds.Tables[0].Rows[0]["return_code"].ToString(); if (return_code.ToUpper() == "SUCCESS") { //通信成功 string result_code = ds.Tables[0].Rows[0]["result_code"].ToString();//业务结果 if (result_code.ToUpper() == "SUCCESS") { var res = new Dictionary<string, string> { {"appId", appid}, {"timeStamp", GetTimeStamp()}, {"nonceStr", dic["nonce_str"]}, {"package", "prepay_id="+ds.Tables[0].Rows[0]["prepay_id"].ToString()}, {"signType", "MD5"} }; //在服务器上签名 res.Add("paySign", GetSignString(res)); // string signapp = res.ToString(); string signapp = JsonConvert.SerializeObject(res); if ((context.Request.Params["openid"] != null) && (context.Request.Params["openid"] != "")) { //存储订单信息 Maticsoft.Model.order_history oh = new Maticsoft.Model.order_history(); //oh.shop_id = oh.room_id = Convert.ToInt32(roomid); oh.pay_price = Convert.ToDecimal(totalfee); oh.out_trade_no = dic["out_trade_no"]; oh.order_timestart = Convert.ToDateTime(ordertime); oh.openid = openid; oh.creating_date = DateTime.Now; Maticsoft.BLL.order_history bll = new Maticsoft.BLL.order_history(); bll.Add(oh); } context.Response.Write(signapp); } } } context.Response.Write(output); } public bool IsReusable { get { return false; } } public string GetMd5Hash(String input) { if (input == null) { return null; } MD5 md5Hash = MD5.Create(); // 将输入字符串转换为字节数组并计算哈希数据 byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input)); // 创建一个 Stringbuilder 来收集字节并创建字符串 StringBuilder sBuilder = new StringBuilder(); // 循环遍历哈希数据的每一个字节并格式化为十六进制字符串 for (int i = 0; i < data.Length; i++) { sBuilder.Append(data[i].ToString()); } // 返回十六进制字符串 return sBuilder.ToString(); } /// <summary> /// 对象序列化成 XML String /// </summary> public static string XmlSerialize<T>(T obj) { string xmlString = string.Empty; XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); using (MemoryStream ms = new MemoryStream()) { xmlSerializer.Serialize(ms, obj); xmlString = Encoding.UTF8.GetString(ms.ToArray()); } return xmlString; } /// <summary> /// 从字符串里随机得到,规定个数的字符串. /// </summary> /// <param name="allChar"></param> /// <param name="CodeCount"></param> /// <returns></returns> public static string GetRandomString(int CodeCount) { 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"; string[] allCharArray = allChar.Split(','); string RandomCode = ""; int temp = -1; Random rand = new Random(); for (int i = 0; i < CodeCount; i++) { if (temp != -1) { rand = new Random(temp * i * ((int)DateTime.Now.Ticks)); } int t = rand.Next(allCharArray.Length - 1); while (temp == t) { t = rand.Next(allCharArray.Length - 1); } temp = t; RandomCode += allCharArray[t]; } 
微信小程序支付功能的实现需要借助微信支付接口,而在 C# 中可以使用 HttpClient 类来发送 HTTP 请求进行调用。 以下是一个简单的实现过程: 1.获取微信支付接口的API密钥和商户号 在微信支付商户平台中,可以获取到微信支付接口的 API 密钥和商户号。 2.编写 C# 代码实现支付功能 首先,需要引用 System.Net.Http 命名空间,然后创建一个 HttpClient 对象。 接着,构造微信支付接口的请求参数,并将其转换为 XML 格式。可以使用 XmlSerializer 类来实现。 然后,使用 HttpClient 对象发送 HTTP 请求并接收响应,将响应转换为字符串后再解析出其中的支付信息。 最后,将支付信息返回给微信小程序。 下面是一个简单的示例代码: ```csharp using System.Net.Http; using System.Text; using System.Xml.Serialization; public class WechatPay { private static readonly string apiUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"; private static readonly string apiKey = "your_api_key"; private static readonly string mchId = "your_mch_id"; public async Task<string> Pay(string openId, string orderId, double amount) { var httpClient = new HttpClient(); var parameters = new Dictionary<string, string> { { "appid", "your_app_id" }, { "mch_id", mchId }, { "nonce_str", Guid.NewGuid().ToString("N") }, { "body", "test" }, { "out_trade_no", orderId }, { "total_fee", (amount * 100).ToString("0") }, { "spbill_create_ip", "127.0.0.1" }, { "notify_url", "your_notify_url" }, { "trade_type", "JSAPI" }, { "openid", openId } }; var xml = ToXmlString(parameters); var content = new StringContent(xml, Encoding.UTF8, "application/xml"); var response = await httpClient.PostAsync(apiUrl, content); var responseContent = await response.Content.ReadAsStringAsync(); var result = FromXmlString(responseContent); return result["prepay_id"]; } private static string ToXmlString(Dictionary<string, string> parameters) { var serializer = new XmlSerializer(typeof(Dictionary<string, string>), new XmlRootAttribute("xml")); using (var textWriter = new StringWriter()) { serializer.Serialize(textWriter, parameters); return textWriter.ToString(); } } private static Dictionary<string, string> FromXmlString(string xml) { var serializer = new XmlSerializer(typeof(Dictionary<string, string>), new XmlRootAttribute("xml")); using (var textReader = new StringReader(xml)) { return (Dictionary<string, string>)serializer.Deserialize(textReader); } } } ``` 在上面的代码中,Pay 方法接收三个参数:openId、orderId 和 amount。其中,openId 是用户在微信小程序中的唯一标识符,orderId 是订单号,amount 是支付金额。 在方法中,首先构造了微信支付接口的请求参数,然后将其转换为 XML 格式。接着,使用 HttpClient 对象发送 HTTP 请求并接收响应,将响应转换为字符串后再解析出其中的支付信息。最后,将支付信息返回给微信小程序。 需要注意的是,以上代码仅为示例代码,实际使用时需要根据实际情况进行适当的修改。同时,为了保证安全性,API 密钥等敏感信息应该存储在安全的地方,并使用安全的方式进行传输。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值