小程序微信支付[JSAPI]

作者:admin来源:自编 日期:2021/2/24 16:59:21浏览次数:

这里说的小程序微信支付是其程序方说明的JSAPI方式,即按支付按钮后,会出现输入支付密码的样式。

微信小程序页面分4个部分:jsjsonwxmlwxss,各负责一部分内容。

js(逻辑部分)支付按钮函数(bindtap)可以是://页面中需要定义支付按钮

pay: function (options) {

    var orderCode = this.getorderid();//可以定义一个获取订单号的函数;

    var that=this;

    var selfsession = wx.getStorageSync("selfsession");//根据selfsession获取id,selfsession为自定义变量;selfsession的使用方法可参考文章-小程序获取session方法

   wx.login({

      success: function (res) {

         if (res.code) {

          wx.request({

            url: "https://www.xxxx.cn/xxx.ashx",

            data: {

              code: res.code,             

              order_code: orderCode,//相应参数在此规划好

              total_fee: "",

              body:"",

              ……

            },           

            method: 'POST',          

            header: {'content-type': 'application/x-www-form-urlencoded'},           

                 success: function(res) {                           

                    console.log(res.data); 

                    wx.requestPayment({

                      timeStamp:res.data.timeStamp,   

                      nonceStr:res.data.nonceStr,               

                      package:res.data.package,               

                      signType:res.data.signType,               

                      paySign:res.data.paySign,               

                      success: function(res) {                

                       console.log(res);  |#|#|                                    

                       wx.request({    //更新付款状态及录入订单号、订单金额等

                          url: "https://www.xxxx.cn/xxx.ashx",

                          method: "POST",

                          header: { "Content-Type": "application/x-www-form-urlencoded" },

                          data: {                         

                          },

                          success: function (res) {                     

                          },

                          fail: function (res) {

                           }, 

                        })             

                       },               

                      fail: function(res) {                 

                       console.log("支付失败:",res);

                       },             

                    })           

                  }          

              })       

            }    

          }  

     }) 

  },

后方函数,需要一系列函数支撑,这里用.NET需要定义一个微信支付类WXPay

后方在接到命令后,处理函数如下,s是需要返回给前方的字符串。

                    try{

                        string code = context.Request.Form["code"];

                        string order_code = context.Request.Form["order_code"];

                        string body = context.Request.Form["body"];

                        string total_fee = context.Request.Form["total_fee"];

                        WXPay.PayRequesEntity msg = (WXPay.PayRequesEntity)WXPay.Pay(code, order_code,total_fee,body);

                        if (msg != null){|#|#|

                            s = "{\"state\":\"OK\",\"Error_code\":\"0\",\"Success\":\"" + true + "\",\"Message\":\"支付结果!\",\"Total_count\":\""+total_fee+"\",\"timeStamp\":\"" + msg.timeStamp + "\",\"nonceStr\":\"" + msg.nonceStr + "\",\"package\":\"" + msg.package + "\",\"signType\":\"" + msg.signType + "\",\"paySign\":\"" + msg.paySign + "\"}";

                        }

                        else

                   {s = "{\"state\":\"none\"}";}

                    }

                    catch (Exception e){

                        s = "{\"state\":\"none\",\"Error_code\":\"1\",\"Success\":\"" + false + "\",\"Message\":\"发起支付失败!\",\"Error_desc\":\"" + e.Message + "\"}";

                    }

微信支付类WXPay 如下:

public class WXPay{

    private static string APP_ID = "";/*以下是小程序及商户号相关信息。*/

    private static string APP_SECRET = "";

    private static string MCH_ID = "";

    private static string KEY = "";

    private static string NOTIFY_URL = "https://www.xxxx.cn/xxx.aspx";

    private static string PAY_URL = https://api.mch.weixin.qq.com/pay/unifiedorder; 

    public class Parameters {

        public string appid;//申请的appid           

        public string mchid;//申请的商户号           

        public string nonce_str;  //随机字符串           

        public string notify_url;//支付结果回调接口       

        public string body;//商品描述(商品简单描述,该字段请按照规范传递,具体参见参数规定)           

        public string out_trade_no;//商户订单号           

        public string total_fee;//标价金额           

        public string spbill_create_ip;//终端IP          

        public string trade_type;//交易类型                 

        public string key;//在商家后台设置的密钥            

        public string app_secret;//在配置小程序时的密钥       

    }|#|#|

    public class PayRequesEntity {

        public string timeStamp { get; set; }

        public string nonceStr { get; set; }

        public string package { get; set; }

        public string signType { get; set; }

        public string paySign { get; set; }

    } 

    public static PayRequesEntity Pay(string code, string order_code,string total_fee,string body) {  /*获取微信最后支付返回值object*/

        Parameters para = new Parameters();

        para.appid = APP_ID;         

        para.mchid = MCH_ID;          

        para.nonce_str = GetNoncestr();             

        para.notify_url = NOTIFY_URL;           

        para.body = body;

        para.out_trade_no = order_code;           

        para.total_fee = total_fee;         

        para.spbill_create_ip = "";          

        para.trade_type = "JSAPI";           

        para.key = KEY;           

        para.app_secret = APP_SECRET;                              

        JObject jObject = GetOpendidAndSessionkey(code);//用code换取opendid获取用户唯一标识           

        string openid = string.Empty;          

        string session_key = string.Empty;

        if (jObject.Property("openid") != null && jObject.Property("session_key") != null) {

            openid = jObject["openid"].ToString();

            session_key = jObject["session_key"].ToString();

        }

        string param = "";

        if (!string.IsNullOrEmpty(openid)){   //获取统一的下单的请求参数                

            param = GetUnifiedOrderParam(openid, para);    //获取统一下单,传给微信服务器的参数,xml格式                                       

            String msg = PostUnifiedOrder(PAY_URL, param);   //统一下单后,返回的值 预支付的prepay_id  |#|#|

            var payRes = XDocument.Parse(msg);

            var root = payRes.Element("xml");

            if (root.Element("return_code").Value == "SUCCESS"){

                //拿到请求的结果 //序列化相应参数返回给小程序                   

                var res = GetPayRequestParam(root, para.appid, para.key);//返回给小程序,最后要支付的值,5个值

                return res;

            }

        }

        return null;

    }

    public static JObject GetOpendidAndSessionkey(string code){

        string backMsg = "";

        String url = "https://api.weixin.qq.com/sns/jscode2session";

        String sendData = "appid=" + APP_ID + "&secret=" + APP_SECRET + "&js_code=" + code + "&grant_type=authorization_code";

        try{

            System.Net.WebRequest httpRquest = System.Net.HttpWebRequest.Create(url);

            httpRquest.Method = "POST";

            httpRquest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";

            byte[] dataArray = System.Text.Encoding.UTF8.GetBytes(sendData);

            //httpRquest.ContentLength = dataArray.Length;

            System.IO.Stream requestStream = null;

            if (string.IsNullOrWhiteSpace(sendData) == false)

            { requestStream = httpRquest.GetRequestStream();

                requestStream.Write(dataArray,0,dataArray.Length);

                requestStream.Close();

            }

            System.Net.WebResponse response = httpRquest.GetResponse();

            System.IO.Stream responseStream = response.GetResponseStream();

            System.IO.StreamReader reader = new System.IO.StreamReader(responseStream, System.Text.Encoding.UTF8);

            backMsg = reader.ReadToEnd();

            reader.Close();|#|#|

            reader.Dispose();

            requestStream.Dispose();

            responseStream.Close();

            responseStream.Dispose();

        }

        catch (Exception){

            throw;

        }

        JObject jo = JObject.Parse(backMsg);

        return jo;

    }

    private static string GetUnifiedOrderParam(string openid, Parameters para){

        //参与统一下单签名的参数,除最后的key外,已经按参数名ASCII码从小到大排序           

        string unifiedorderSignParam = string.Format("appid={0}&body={1}&mch_id={2}&nonce_str={3}&notify_url={4}&openid={5}&out_trade_no={6}&spbill_create_ip={7}&total_fee={8}&trade_type={9}&key={10}", para.appid, para.body, para.mchid, para.nonce_str, para.notify_url, openid, para.out_trade_no, para.spbill_create_ip, para.total_fee, para.trade_type, para.key);

        //MD5加密并将结果转换成大写           

        string unifiedorderSign = GetMD5(unifiedorderSignParam).ToUpper();

        //构造统一下单的请求参数      

        return string.Format(@"<xml>

                                 <appid>{0}</appid>                                                                             

                                 <body>{1}</body>                               

                                 <mch_id>{2}</mch_id>

                                 <nonce_str>{3}</nonce_str>

                                 <notify_url>{4}</notify_url>                                

                                 <openid>{5}</openid>                               

                                 <out_trade_no>{6}</out_trade_no>                                                                  

                                 <spbill_create_ip>{7}</spbill_create_ip>                               

                                 <total_fee>{8}</total_fee>                               

                                 <trade_type>{9}</trade_type>

                                 <sign>{10}</sign>                                                                                            

                                 </xml>", para.appid, para.body, para.mchid, para.nonce_str, para.notify_url, openid, para.out_trade_no, para.spbill_create_ip, para.total_fee, para.trade_type,unifiedorderSign);

    }|#|#|

    //统一请求下单       

    private static String PostUnifiedOrder(string payUrl, string para){

        string result = string.Empty;

        try {

            System.Net.WebRequest httpRquest = System.Net.HttpWebRequest.Create(payUrl);

            httpRquest.Method = "POST";

            httpRquest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";

            byte[] dataArray = System.Text.Encoding.UTF8.GetBytes(para);

            //httpRquest.ContentLength = dataArray.Length;

            System.IO.Stream requestStream = null;

            if (string.IsNullOrWhiteSpace(para) == false)

            {

                requestStream = httpRquest.GetRequestStream();

                requestStream.Write(dataArray,0,dataArray.Length);

                requestStream.Close();

            }

            System.Net.WebResponse response = httpRquest.GetResponse();

            System.IO.Stream responseStream = response.GetResponseStream();

            System.IO.StreamReader reader = new System.IO.StreamReader(responseStream, System.Text.Encoding.UTF8);

            result = reader.ReadToEnd();

            reader.Close();

            reader.Dispose();

            requestStream.Dispose();

            responseStream.Close();

            responseStream.Dispose();

            return result;

        }

        catch (Exception e) {

            result = e.Message;

        }

        return result;

    }|#|#|

    //获取返回给小程序的支付参数       

    private static PayRequesEntity GetPayRequestParam(XElement root, string appid, string key) {

        //return_code result_code都为SUCCESS时才有我们要的prepay_id           

        if (root.Element("return_code").Value == "SUCCESS" && root.Element("result_code").Value == "SUCCESS"){

            var package = "prepay_id=" + root.Element("prepay_id").Value;//统一下单接口返回的 prepay_id 参数值               

            var nonceStr = GetNoncestr();//获取随机字符串               

            var signType = "MD5";//加密方式               

            var timeStamp = Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds).ToString();//时间戳                

            var paySignParam = string.Format("appId={0}&nonceStr={1}&package={2}&signType={3}&timeStamp={4}&key={5}",appid, nonceStr, package, signType, timeStamp, key); //二次加签               

            var paySign = GetMD5(paySignParam).ToUpper();

            PayRequesEntity payEntity = new PayRequesEntity{

                package = package,

                nonceStr = nonceStr,

                paySign = paySign,

                signType = signType,

                timeStamp = timeStamp

            };

            return payEntity;

        }

        return null;

    }

    private static string GetNoncestr() {//获取随机字符串函数

        int CodeCount = 10;

        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];

        }

        return RandomCode;

    }

    /* MD5算法,不同的算法结果不一样,下面这个是可行的*/

    public static string GetMD5(string sDataIn){

        System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();

        byte[]byt, bytHash;

        byt = System.Text.Encoding.UTF8.GetBytes(sDataIn);

        bytHash = md5.ComputeHash(byt);

        md5.Clear();

        string sTemp = "";

        for (int i = 0; i < bytHash.Length; i ++ ){

            sTemp += bytHash[i].ToString("x").PadLeft(2, '0');

        }

        return sTemp;

    }

}

按照上面的说明,配置好参数,小程序微信支付基本就可以运行了。版权所有,实践经验,转载及使用请注明出处,文章来自-三里河之光-风、物、情

using命名空间中,相应的命名空间要引入

要引用外部Newtonsoft.Json程序集   用于json字符串及对象之间转化,外部下载

using Newtonsoft.Json.Linq;

 

 

中华人民共和国