.NET开发微信小程序-微信支付
前台MD5加密代码
/* * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algorithm, as defined in RFC 1321. * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for more info. */ /* * Configurable variables. You may need to tweak these to be compatible with * the server-side, but the defaults work in most cases. */ var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ /* * These are the functions you'll usually want to call * They take string arguments and return either hex or base-64 encoded strings */ function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));} function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));} function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));} function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); } function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); } function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); } /* * Perform a simple self-test to see if the VM is working */ function md5_vm_test() { return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; } /* * Calculate the MD5 of an array of little-endian words, and a bit length */ function core_md5(x, len) { /* append padding */ x[len >> 5] |= 0x80 << ((len) % 32); x[(((len + 64) >>> 9) << 4) + 14] = len; var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; for(var i = 0; i < x.length; i += 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); c = md5_ff(c, d, a, b, x[i+10], 17, -42063); b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); a = safe_add(a, olda); b = safe_add(b, oldb); c = safe_add(c, oldc); d = safe_add(d, oldd); } return Array(a, b, c, d); } /* * These functions implement the four basic operations the algorithm uses. */ function md5_cmn(q, a, b, x, s, t) { return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); } function md5_ff(a, b, c, d, x, s, t) { return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); } function md5_gg(a, b, c, d, x, s, t) { return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); } function md5_hh(a, b, c, d, x, s, t) { return md5_cmn(b ^ c ^ d, a, b, x, s, t); } function md5_ii(a, b, c, d, x, s, t) { return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); } /* * Calculate the HMAC-MD5, of a key and some data */ function core_hmac_md5(key, data) { var bkey = str2binl(key); if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz); var ipad = Array(16), opad = Array(16); for(var i = 0; i < 16; i++) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5C5C5C5C; } var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); return core_md5(opad.concat(hash), 512 + 128); } /* * Add integers, wrapping at 2^32. This uses 16-bit operations internally * to work around bugs in some JS interpreters. */ function safe_add(x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } /* * Bitwise rotate a 32-bit number to the left. */ function bit_rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); } /* * Convert a string to an array of little-endian words * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. */ function str2binl(str) { var bin = Array(); var mask = (1 << chrsz) - 1; for(var i = 0; i < str.length * chrsz; i += chrsz) bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32); return bin; } /* * Convert an array of little-endian words to a string */ function binl2str(bin) { var str = ""; var mask = (1 << chrsz) - 1; for(var i = 0; i < bin.length * 32; i += chrsz) str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask); return str; } /* * Convert an array of little-endian words to a hex string. */ function binl2hex(binarray) { var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; var str = ""; for(var i = 0; i < binarray.length * 4; i++) { str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) + hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF); } return str; } /* * Convert an array of little-endian words to a base-64 string */ function binl2b64(binarray) { var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var str = ""; for(var i = 0; i < binarray.length * 4; i += 3) { var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16) | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 ) | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF); for(var j = 0; j < 4; j++) { if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); } } return str; } module.exports = { hex_md5: hex_md5 }
前端发起支付接口
/* 发起微信支付 */ var md5 = require('md5.js') function wxPay(data, CallBack) { var appInstance = getApp() var url = appInstance.globalData.apiurl url += "Weixin/SendwxPay" wx.request({ url: url, data: data, header: { 'content-type': 'application/json' }, success: function (res) { console.log('md5:' + md5.hex_md5("123456")) console.log('appId:' + res.data.data.appId) console.log('key:' + res.data.data.Key) console.log('timeStamp:' + res.data.data.timeStamp) console.log('nonceStr:' + res.data.data.nonceStr) console.log('package:' + res.data.data.package) console.log('paySign:' + res.data.data.paySign) var singValue = "" singValue += "appId=" + res.data.data.appId singValue += "&nonceStr=" + res.data.data.nonceStr singValue += "&package=prepay_id=" + res.data.data.package singValue += "&signType=MD5" singValue += "&timeStamp=" + res.data.data.timeStamp singValue += "&key=" + res.data.data.Key console.log(singValue) var paySign = md5.hex_md5(singValue) paySign = paySign.toUpperCase() console.log(paySign) wx.hideLoading() wx.requestPayment({ 'timeStamp': res.data.data.timeStamp, 'nonceStr': res.data.data.nonceStr, 'package': 'prepay_id=' + res.data.data.package, 'signType': 'MD5', 'paySign': paySign, 'success': function (res) { CallBack(res) }, 'fail': function (res) { CallBack(res) } }) } }) }
1.预支付需要的付款实体类
public class PayModel { /// <summary> /// 小程序appID /// </summary> public String appid { get; set; } /// <summary> /// 商户号 /// </summary> public String mch_id { get; set; } /// <summary> /// 设备号 /// 终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB /// 示例值:013467007045764 /// </summary> public String device_info { get; set; } /// <summary> /// 随机字符串,不长于32位 /// 随机字符串算法地址:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3 /// </summary> public String nonce_str { get; set; } /// <summary> /// 签名 /// 生成签名算法地址:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3 /// </summary> public String sign { get; set; } /// <summary> /// 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5 /// </summary> public String sign_type { get; set; } /// <summary> /// 商品描述 /// 例:腾讯-游戏 /// </summary> public String body { get; set; } /// <summary> /// 商品详情(不必填) /// </summary> public String detail { get; set; } /// <summary> /// 附加数据 /// 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 /// </summary> public String attach { get; set; } /// <summary> /// 商户订单号 /// 商户支付的订单号由商户自定义生成,微信支付要求商户订单号保持唯一性(建议根据当前系统时间加随机序列来生成订单号)。 /// 重新发起一笔支付要使用原订单号,避免重复支付;已支付过或已调用关单、撤销(请见后文的API列表)的订单号不能重新发起支付。 /// </summary> public String out_trade_no { get; set; } /// <summary> /// 货币类型 /// 默认值:CNY /// </summary> public String fee_type { get; set; } /// <summary> /// 付款金额 /// 默认值:(分) /// </summary> public Int32 total_fee { get; set; } /// <summary> /// 终端IP /// </summary> public String spbill_create_ip { get; set; } /// <summary> /// 交易起始时间 /// 订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010 /// </summary> public String time_start { get; set; } /// <summary> /// 交易结束时间 /// 订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010 /// 注意:最短失效时间间隔必须大于5分钟 /// </summary> public String time_expire { get; set; } /// <summary> /// 商品标记 /// 商品标记,代金券或立减优惠功能的参数 /// </summary> public String goods_tag { get; set; } /// <summary> /// 通知地址 /// </summary> public String notify_url { get; set; } /// <summary> /// 交易类型 /// 小程序默认值:JSAPI /// </summary> public String trade_type { get; set; } /// <summary> /// 指定支付方式 /// no_credit--指定不能使用信用卡支付 /// </summary> public String limit_pay { get; set; } /// <summary> /// 支付人的openID /// </summary> public String openid { get; set; } /// <summary> /// key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 /// </summary> public String key { get; set; } }
2.给该实体进行赋值
var wxconfig = dbContext.GXL_WxConfig.FirstOrDefault(x => x.ManuID == PayNotifyModel.ManuId); //生成预支付的订单编号 string orderNum = Utils.GetOrderNumber(); PayModel paymodel = new PayModel(); paymodel.appid = wxconfig.AppId; paymodel.body = "消费-付款"; paymodel.fee_type = "CNY"; paymodel.key = wxconfig.PayKey; paymodel.limit_pay = "no_credit";//不能使用信用卡支付,目前禁止,到时候和客户确定,开通权限 paymodel.mch_id = wxconfig.MchId; paymodel.nonce_str = Utils.GetRandomString(32, true, true, true, false, ""); paymodel.notify_url = "https://www.fujinapp.cn/api/gxl/Weixin/Notify_url";//支付成功回调页面 paymodel.openid = openId; paymodel.out_trade_no = orderNum;//给微信支付的订单号,避免重复 paymodel.sign_type = "MD5"; paymodel.spbill_create_ip = "112.94.224.190";//考虑还要做一个获取IP地址的功能 paymodel.time_start = DateTime.Now.ToString("yyyyMMddHHmmss");//支付时间 paymodel.time_expire = DateTime.Now.AddDays(1).ToString("yyyyMMddHHmmss");//支付结束时间 目前暂定是一天 paymodel.total_fee = PayNotifyModel.total_fee;//支付金额 通过订单id获取支付金额 然后进行转化 paymodel.trade_type = "JSAPI"; paymodel.attach = Newtonsoft.Json.JsonConvert.SerializeObject(PayNotifyModel);//支付成功带回来的
3.将绑定好数据的实体对象丢到付款方法里面去
/// <summary> /// 付款信息 /// </summary> /// <param name="openID">付款人</param> /// <param name="paymodel">配置付款model信息</param> /// <returns></returns> public static PayReturnData SendPay(PayModel paymodel) { #region 1.填充数据 Dictionary<string, string> dics = new Dictionary<string, string>(); dics.Add("appid", paymodel.appid); dics.Add("mch_id", paymodel.mch_id); dics.Add("nonce_str", paymodel.nonce_str); dics.Add("body", paymodel.body); dics.Add("attach", paymodel.attach); dics.Add("out_trade_no", paymodel.out_trade_no); dics.Add("total_fee", paymodel.total_fee.ToString()); dics.Add("notify_url", paymodel.notify_url); dics.Add("trade_type", paymodel.trade_type); dics.Add("openid", paymodel.openid); dics.Add("spbill_create_ip", paymodel.spbill_create_ip); //string sign = GetSignString(dics, paymodel.key); string sign = Utils.getParamSrc(dics); sign = sign + "&key=" + paymodel.key; sign = Utils.MD5Encrypt(sign, Encoding.UTF8); dics.Add("sign", sign); paymodel.sign = sign; #endregion #region 2.生成xml数据var sb = new StringBuilder(); sb.Append("<xml>"); foreach (var d in dics) { sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">"); } sb.Append("</xml>"); #endregion #region 3.发起预支付 CookieCollection coo = new CookieCollection(); Encoding en = Encoding.GetEncoding("UTF-8"); HttpWebResponse response = Request.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 var xml = new XmlDocument(); xml.LoadXml(html); //处理返回的值 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(); PayReturnData payDataModel = new PayReturnData(); if (return_code.ToUpper() == "SUCCESS") { //通信成功 string result_code = ds.Tables[0].Rows[0]["result_code"].ToString();//业务结果 if (result_code.ToUpper() == "SUCCESS") { Log4Helper.ErrorInfo("GXL", "支付请求完成"); string pid = ds.Tables[0].Rows[0]["prepay_id"].ToString(); payDataModel.paySign = paymodel.sign; payDataModel.signType = paymodel.sign_type; payDataModel.timeStamp = Utils.GetTimeStamp(); payDataModel.package = pid; //payDataModel.nonceStr = GetRandomString(32, true, true, true, false, ""); payDataModel.nonceStr = paymodel.nonce_str; payDataModel.appId = paymodel.appid; payDataModel.Key = paymodel.key; } } return payDataModel; #endregion }
4.相应的方法类
#region 小程序 /// <summary> /// 获取时间戳 /// </summary> /// <returns></returns> public static string GetTimeStamp() { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds).ToString(); } /// <summary> /// 拼接:Dictionary &拼接 /// </summary> /// <param name="paramsMap"></param> /// <returns></returns> public static String getParamSrc(Dictionary<string, string> paramsMap) { var vDic = (from objDic in paramsMap orderby objDic.Key ascending select objDic); StringBuilder str = new StringBuilder(); foreach (KeyValuePair<string, string> kv in vDic) { string pkey = kv.Key; string pvalue = kv.Value; str.Append(pkey + "=" + pvalue + "&"); } String result = str.ToString().Substring(0, str.ToString().Length - 1); return result; } /// <summary> /// MD5 加密 /// </summary> /// <param name="input"> 待加密的字符串 </param> /// <param name="encoding"> 字符编码 </param> /// <returns></returns> public static string MD5Encrypt(string input, Encoding encoding) { return HashEncrypt(MD5.Create(), input, encoding); } /// <summary> /// 哈希加密算法 /// </summary> /// <param name="hashAlgorithm"> 所有加密哈希算法实现均必须从中派生的基类 </param> /// <param name="input"> 待加密的字符串 </param> /// <param name="encoding"> 字符编码 </param> /// <returns></returns> private static string HashEncrypt(HashAlgorithm hashAlgorithm, string input, Encoding encoding) { var data = hashAlgorithm.ComputeHash(encoding.GetBytes(input)); return BitConverter.ToString(data).Replace("-", ""); } /// <summary> /// 获取时间差 返回秒 /// </summary> /// <param name="DateTime1"></param> /// <param name="DateTime2"></param> /// <returns></returns> public static double DateDiffIsSecond(DateTime DateTime1, DateTime DateTime2) { string dateDiff = null; TimeSpan ts = DateTime1.Subtract(DateTime2).Duration(); return ts.TotalSeconds; } ///<summary> ///生成随机字符串 ///</summary> ///<param name="length">目标字符串的长度</param> ///<param name="useNum">是否包含数字,1=包含,默认为包含</param> ///<param name="useLow">是否包含小写字母,1=包含,默认为包含</param> ///<param name="useUpp">是否包含大写字母,1=包含,默认为包含</param> ///<param name="useSpe">是否包含特殊字符,1=包含,默认为不包含</param> ///<param name="custom">要包含的自定义字符,直接输入要包含的字符列表</param> ///<returns>指定长度的随机字符串</returns> public static string GetRandomString(int length, bool useNum, bool useLow, bool useUpp, bool useSpe, string custom) { byte[] b = new byte[4]; new System.Security.Cryptography.RNGCryptoServiceProvider().GetBytes(b); Random r = new Random(BitConverter.ToInt32(b, 0)); string s = null, str = custom; if (useNum == true) { str += "0123456789"; } if (useLow == true) { str += "abcdefghijklmnopqrstuvwxyz"; } if (useUpp == true) { str += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; } if (useSpe == true) { str += "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; } for (int i = 0; i < length; i++) { s += str.Substring(r.Next(0, str.Length - 1), 1); } return s; } public static byte[] StreamToBytes(Stream stream) { List<byte> bytes = new List<byte>(); int temp = stream.ReadByte(); while (temp != -1) { bytes.Add((byte)temp); temp = stream.ReadByte(); } return bytes.ToArray(); } public static void PreservationCodeImage(string path, byte[] imgByte) { System.IO.File.WriteAllBytes(@"" + path + "", imgByte); } /// <summary> /// MD5加密 /// </summary> /// <param name="encypStr">加密字符串</param> /// <param name="charset">编码方式</param> /// <returns></returns> public static string GetMD5(string encypStr, string charset) { string retStr; MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider(); //创建md5对象 byte[] inputBye; byte[] outputBye; //使用GB2312编码方式把字符串转化为字节数组. try { inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr); } catch (Exception ex) { inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr); } outputBye = m5.ComputeHash(inputBye); retStr = System.BitConverter.ToString(outputBye); retStr = retStr.Replace("-", "").ToUpper(); return retStr; } #endregion
5.返回出去的实体对象
/// <summary> /// 预支付返回的数据 /// </summary> public class PayReturnData { /// <summary> /// 小程序Key /// </summary> public String Key { get; set; } /// <summary> /// 小程序编号 /// </summary> public String appId { get; set; } /// <summary> /// 时间戳从1970年1月1日00:00:00至今的秒数,即当前的时间 /// </summary> public String timeStamp { get; set; } /// <summary> /// 随机字符串,不长于32位 /// </summary> public String nonceStr { get; set; } /// <summary> /// 统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=wx2017033010242291fcfe0db70013231072 /// </summary> public String package { get; set; } /// <summary> /// 签名算法,暂支持 MD5 /// </summary> public String signType { get; set; } /// <summary> /// 签名 /// </summary> public String paySign { get; set; } }
注:返回出来的实体对象一定要序列化返回出去。然后在前端有相应的处理。
核心代码已经写完了。其它跟业务相关的内容需要自己补充。