首页 > 代码库 > .NET开发微信小程序-微信支付

.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 singValuehttp://www.mamicode.com/= ""
      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 =http://www.mamicode.com/ 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 =http://www.mamicode.com/ 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; }


    }

注:返回出来的实体对象一定要序列化返回出去。然后在前端有相应的处理。

核心代码已经写完了。其它跟业务相关的内容需要自己补充。

.NET开发微信小程序-微信支付