小程序

c# 微信小程序微信统一下单支付 和小程序支付

2020-08-21

小程序微信支付


一、前置工作(微信公众平台申请  https://mp.weixin.qq.com/)要申请商户号关联APPID

关联账号


1、APPID(小程序ID)

2、AppSecret(小程序密钥)

3、mch_id 商户号 

4、mch_key 商户密匙  (需要设置,设置一次一定要记录,如果没记住需要重新设置。pay.weixin.qq.com中账户中心---安全中心---API秘钥---重设秘钥)

以上4个参数是必须要有的。

这一步的目的就是获取这几个必须用到的参数。



二、有了以上的参数,服务端就可以调用统一下单接口了(统一下单,说白了就是生成预支付订单,就用这个就行!)

官方文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1

小程序的微信支付需要 OpenId 支付用户唯一标识  可以通过小程序 auth.code2Session 获取

登录凭证校验:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html

这个会返回 OpenId 


接着说统一下单  一图顶千字

统一下单


以上参数重点说一下签名  sign

看我代码的意思就是把上面的参数都拼接到一起最后加了个key(商户秘钥)再MD5加密。这是第一次签名(下面会说二次签名)。

扩展方法  粘贴直接用即可


        /// <summary>

        /// 把字典内的数据拼接成  url参数  例:  ?par1=1&par2=2

        /// </summary>

        /// <param name="paraMap"></param>

        /// <returns></returns>

        public string FormatBizQueryParaMapForUnifiedPay(Dictionary<string, string> paraMap)

        {

            string buff = "";

            try

            {

                var result = from pair in paraMap orderby pair.Key select pair;

                foreach (KeyValuePair<string, string> pair in result)

                {

                    if (pair.Key != "")

                    {


                        string key = pair.Key;

                        string val = pair.Value;

                        buff += key + "=" + val + "&";

                    }

                }


                if (buff.Length == 0 == false)

                {

                    buff = buff.Substring(0, (buff.Length - 1) - (0));

                }

            }

            catch (Exception e)

            {

                throw e;

            }

            return buff;

        }


        /// <summary>

        /// MD5加密

        /// </summary>

        /// <param name="encypStr"></param>

        /// <returns></returns>

        public string GetMD5(string encypStr)

        {

            char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',

                    'A', 'B', 'C', 'D', 'E', 'F' };

            try

            {


                byte[] btInput = System.Text.Encoding.UTF8.GetBytes(encypStr);

                // 获得MD5摘要算法的 MessageDigest 对象

                MD5 mdInst = System.Security.Cryptography.MD5.Create();

                // 使用指定的字节更新摘要

                mdInst.ComputeHash(btInput);

                // 获得密文

                byte[] md = mdInst.Hash;

                // 把密文转换成十六进制的字符串形式

                int j = md.Length;

                char[] str = new char[j * 2];

                int k = 0;

                for (int i = 0; i < j; i++)

                {

                    byte byte0 = md[i];

                    str[k++] = hexDigits[(int)(((byte)byte0) >> 4) & 0xf];

                    str[k++] = hexDigits[byte0 & 0xf];

                }

                return new string(str);

            }

            catch (Exception e)

            {

                Console.Error.WriteLine(e.StackTrace);

                return null;

            }

        }


以上两个方法粘贴可用。用在sign签名签名拼接和加密。

还有那个商户订单号(out_trade_no)就是商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*且在同一个商户号下唯一。自己定义个规则就可以了。

还有随机字符串可以直接用我的这个方法:(说白了就是一个随机字符串)


        /// <summary>

        /// 获取微信的随机数

        /// </summary>

        /// <returns></returns>

        public String CreateNoncestr()

        {

            String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

            String res = "";

            Random rd = new Random();

            for (int i = 0; i < 16; i++)

            {

                res += chars[rd.Next(chars.Length - 1)];

            }

            return res;

        }

重点就是这几个不好理解,其他的都应该好理解,再不理解,可以查查。


然后统一下单进行下一步

返回那个xml之后

统一下单接口2.png


这样统一下单就ok了  生成了一个微信预支付订单。很简单的逻辑

重新屡一下思路:通过参数请求统一下单的链接,返回的xml解析后,判断成功后,进行二次签名,最终返回给小程序前端。


 

三、小程序前端操作

首先你得有微信开发者工具,这里下载 https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html

接下来就是小程序调用接口  一张图简单明了

小程序支付页面1.png


很简单的逻辑:在这个支付的点击事件内,先调用服务端的统一下单支付接口,成功后返回的参数传给  wx.requestPayment

小程序的前端就ok了。


四、最后是关于回调的说明(notify_url)

这个需要你自己创建个回调的文件(我用的是一般处理程序ashx页面处理的,你也可以用这个),写自己的业务逻辑,这个是支付成功后要执行的地址。

比如你支付完  修改后台的订单状态,或者记录第三方信息,或者其他的业务逻辑操作都可以在这里操作。

举例代码,参考就可以了,也可以用:

public void ProcessRequest(HttpContext context)

{

    context.Response.ContentType = "text/xml";  //xml格式

    var inputStream = context.Request.InputStream;//获取http实体主体的内容

    if (inputStream != null)

    {

           var strLen = Convert.ToInt32(inputStream.Length);

            var strArr = new byte[strLen];

            inputStream.Read(strArr, 0, strLen);

            var requestMes = Encoding.UTF8.GetString(strArr);

            inputStream.Flush();

            inputStream.Close();

            inputStream.Dispose();


            //以上这小段代码对返回参数操作,最后可以转成xml格式,这样好操作。


            if (requestMes.Length > 0)

            {

                 context.Response.Write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");


                XmlDocument doc = new XmlDocument();

                doc.XmlResolver = null;

                doc.LoadXml(requestMes);


                if (doc != null)

                {

                XmlNode xmlNode = doc["xml"];

                    if (xmlNode != null)

                    {

                        if (xmlNode["return_code"].InnerText.Equals("SUCCESS") &&                 xmlNode["result_code"].InnerText.Equals("SUCCESS"))

                        {

                        //此处就可以对宁的订单状态做修改或者  其他  的 业务逻辑了!!!!!    

                        }

                    }

                }

            }

    }


} //public结尾

这样就最后一步对业务的操作ok了    就支付了。