zoukankan      html  css  js  c++  java
  • 微信JSAPI 公众号支付 H5支付以及APP支付 WEBAPI接口开发测试

    统一下单入口 调用该方法入口:

    public void WxPayAPI()
        {   //string PayPrice ="99.9";
            ////订单号
            //string Payorder =GenerateOutTradeNo();
    
            //支付金额
            string PayPrice = Request.GetString("payprice").ToString("filtersql");
            //支付单号
            string Payorder = Request.GetString("payorder").ToString("filtersql");
            //公众号jsapi支付 H5支付传参数
            string Openid =Request.GetString("openid").ToString("filtersql");
    string data = "";
    try { WechatPayHelper wxpay = new WechatPayHelper(); int total_fee = (Convert.ToInt32(decimal.Parse(PayPrice) * 100)); ; //////////////////////////////////////////////////////////////////////////////////////////// //发起统一下单请求APP支付 // string return_response = wxpay.GetUnifiedOrderResult(Payorder, total_fee, "财政专费"); //////////////////////////////////////////////////////////////////////////////////////////// //发起统一下单请求JASPI H5支付 传递参数 订单号 金额 body说明 公众号ID string return_response = wxpay.GetUnifiedOrderResultJSAPI(Payorder, total_fee, "财政专费", "rsR8y885552oooo8DH0"); //写日志 Utils.WriteLog("统一下单:" + return_response, "微信下单日志"); //读取返回xml文件信息 XmlDocument doc = new XmlDocument(); doc.LoadXml(return_response);//读取xml字符串 XmlElement root = doc.DocumentElement; //转化类 WeUnifiedorder weun = GetExmlMsg(root); if (null!=weun) { if (weun.return_code.Trim().ToLower() == "fail") { //签名失败 接口问题 Utils.WriteLogFile("[WechatPay]签名失败:", "异常日志"); ReturnData(API.ReturnStatus.失败, "SYSTEMERROR", "系统超时", ""); } else if (weun.result_code.Trim().ToLower() == "fail") { string error = ErrorCode(weun.err_code); Utils.WriteLog("[WechatPay]" + weun.err_code + "" + error + "", "异常日志"); ReturnData(API.ReturnStatus.失败, weun.err_code, error, ""); } else { //统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP或者公众号客户端。
    //参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。
    //注意:package的值格式为Sign=WXPay
    string noncestr = WechatPayHelper.StrRodamNo(16); string timestamp = Common.TimeSpanValue.getTimestamp(); //把请求参数打包成数组 Dictionary<string, string> sParaTempToken = new Dictionary<string, string>(); sParaTempToken.Add("appid", weun.appid); sParaTempToken.Add("partnerid", weun.mch_id); sParaTempToken.Add("noncestr", noncestr); sParaTempToken.Add("prepayid", weun.prepay_id); sParaTempToken.Add("package", "Sign=WXPay"); sParaTempToken.Add("timestamp", timestamp); //请求参数体 string strRequestData = ""; //加密 string strSign = wxpay.MakeSignData(sParaTempToken, ref strRequestData); data = "{"appid":"" + weun.appid + "","partnerid":"" + weun.mch_id + "","noncestr":"" + noncestr + "","sign":"" + strSign + "","Package":"Sign=WXPay","prepayid":"" + weun.prepay_id + "","timestamp":"" + timestamp + ""}"; ReturnData(API.ReturnStatus.成功, "success", "下单支付成功", data); } } else { ReturnData(API.ReturnStatus.失败, "error", "下单支付失败", ""); } } catch (System.Threading.ThreadAbortException) { } catch (Exception e) { Utils.WriteLog("统一下单:" + e.Message, "异常日志"); ReturnData(API.ReturnStatus.失败, "error", "下单支付失败", data); } } /// <summary> /// 统一下单返回类 /// </summary> /// <param name="root"></param> /// <returns></returns> public WeUnifiedorder GetExmlMsg(XmlElement root) { WeUnifiedorder xmlMsg = new WeUnifiedorder() { return_code = root.SelectSingleNode("return_code").InnerText }; //返回状态码为SUCCESS if (xmlMsg.return_code.Trim().ToLower() == "fail") { xmlMsg.return_msg = root.SelectSingleNode("return_msg").InnerText; } else { xmlMsg.appid = root.SelectSingleNode("appid").InnerText; xmlMsg.mch_id = root.SelectSingleNode("mch_id").InnerText; xmlMsg.nonce_str = root.SelectSingleNode("nonce_str").InnerText; xmlMsg.sign = root.SelectSingleNode("sign").InnerText; xmlMsg.result_code = root.SelectSingleNode("result_code").InnerText; //业务结果 if (xmlMsg.result_code.Trim().ToLower() == "fail") { xmlMsg.err_code = root.SelectSingleNode("err_code").InnerText; xmlMsg.err_code_des = root.SelectSingleNode("err_code_des").InnerText; } else { xmlMsg.trade_type = root.SelectSingleNode("trade_type").InnerText; xmlMsg.prepay_id = root.SelectSingleNode("prepay_id").InnerText; } } return xmlMsg; } /// <summary> /// 统一下单返回错误码 /// </summary> /// <param name="code"></param> /// <returns></returns> public string ErrorCode(string code) { string message = "错误信息:"; switch (code) { case "NOAUTH": message += "商户未开通此接口权限"; break; case "NOTENOUGH": message += "用户帐号余额不足"; break; case "ORDERPAID": message += "商户订单已支付"; break; case "ORDERCLOSED": message += "当前订单已关闭,无法支付"; break; case "SYSTEMERROR": message += "系统超时"; break; case "APPID_NOT_EXIST": message += "请检查APPID是否正确"; break; case "MCHID_NOT_EXIST": message += "请检查MCHID是否正确"; break; case "APPID_MCHID_NOT_MATCH": message += "appid和mch_id不匹配"; break; case "LACK_PARAMS": message += "缺少必要的请求参数"; break; case "OUT_TRADE_NO_USED": message += "商户订单号重复"; break; case "SIGNERROR": message += "签名错误"; break; case "XML_FORMAT_ERROR": message += "XML格式错误"; break; case "REQUIRE_POST_METHOD": message += "未使用post传递参数 "; break; case "POST_DATA_EMPTY": message += "post数据不能为空"; break; case "NOT_UTF8": message += "编码格式错误"; break; } return message; }

     WechatPayHelper 代码:

    public class WechatPayHelper
    {
        private string RequestUrl = "";//接口调用地址
        //交易安全检验码,由数字和字母组成的32位字符串
        private string key = "";
        private string appid = "";//应用ID
        private string mch_id = "";//商户号
        private string nonce_str = "";//随机字符串
        private string sign = "";//签名
         private string spbill_create_ip = "";//终端IP
        private string notify_url = "";//通知地址
        private string trade_type = "";//交易类型
        private string pay_url = "";
        //字符编码格式 目前支持 utf-8
        private string input_charset = "utf-8";
        //签名方式RSA MD5
        private string sign_type = "MD5";
        public WechatPayHelper()
        {
            HttpContext Context = System.Web.HttpContext.Current;
            DataTable dt = null;
            //////////////////////////////////////////////////////
            //APP支付配置   读取配置文件XML
            /////////////////////////////////////////////////////
            // string strXML = "Wechat_Pay_APP.xml";
            /////////////////////////////////////////////////
            //jsapi h5支付配置  读取配置XML文件
           
              string strXML = "Wechat_Pay_JSAPI.xml";
                  object objValue =GetCache(strXML);
            if (objValue == null)
            {
                dt = GetConfigXml("//Config//PayConfig/" + strXML);
                SetCache(strXML, dt);
            }
            else
            {
                dt = (DataTable)objValue;
            }
            if (dt != null)
            {
                appid = dt.Rows[0]["appid"].ToString();
                mch_id = dt.Rows[0]["mch_id"].ToString();
                notify_url = dt.Rows[0]["notify_url"].ToString();
                pay_url = dt.Rows[0]["pay_url"].ToString();
                spbill_create_ip = GetUserIp();
                nonce_str=StrRodamNo(16);
                trade_type = dt.Rows[0]["trade_type"].ToString();
                key = dt.Rows[0]["key"].ToString();
            }
        }
    /// <summary> /// 调用统一下单,获得下单结果 APP /// </summary> /// <param name="out_trade_no"></param> /// <param name="total_fee"></param> /// <param name="body"></param> /// <returns></returns> public string GetUnifiedOrderResult(string out_trade_no, int total_fee, string body) { //请求业务参数详细 StringBuilder sb = new StringBuilder(); sb.AppendFormat("<xml><appid>{0}</appid><mch_id>{1}</mch_id> <body>{2}</body><nonce_str>{3}</nonce_str>", appid, mch_id, body, nonce_str); sb.AppendFormat("<out_trade_no>{0}</out_trade_no><total_fee>{1}</total_fee> <spbill_create_ip>{2}</spbill_create_ip><trade_type>{3}</trade_type>", out_trade_no, total_fee.ToString(), spbill_create_ip, trade_type); sb.AppendFormat("<notify_url>{0}</notify_url>", notify_url); //把请求参数打包成数组 Dictionary<string, string> softdic = new Dictionary<string, string>(); softdic.Add("appid", appid); softdic.Add("mch_id", mch_id); softdic.Add("nonce_str", nonce_str); softdic.Add("body", body); softdic.Add("out_trade_no", out_trade_no); softdic.Add("total_fee", total_fee.ToString()); softdic.Add("spbill_create_ip", spbill_create_ip); softdic.Add("trade_type", trade_type); softdic.Add("notify_url", notify_url); //请求参数体 string strRequest = ""; //加密签名 string strSign = MakeSignData(softdic, ref strRequest); strRequest += "&sign=" + strSign; //打包xml sb.AppendFormat("<sign>{0}</sign></xml>", strSign); //发送请求 string strResponse = RequestWechatpay(sb.ToString()); //URLDECODE返回的信息 Encoding code = Encoding.GetEncoding(input_charset); strResponse = HttpUtility.UrlDecode(strResponse, code); return strResponse; } /// <summary> /// 调用统一下单,获得下单结果 JSAPI /// </summary> /// <param name="out_trade_no"></param> /// <param name="total_fee"></param> /// <param name="body"></param> /// <returns></returns> public string GetUnifiedOrderResultJSAPI(string out_trade_no, int total_fee, string body, string openid) { //请求业务参数详细 StringBuilder sb = new StringBuilder(); sb.AppendFormat("<xml><appid>{0}</appid><mch_id>{1}</mch_id> <body>{2}</body><nonce_str>{3}</nonce_str>", appid, mch_id, body, nonce_str); sb.AppendFormat("<out_trade_no>{0}</out_trade_no><total_fee>{1}</total_fee> <spbill_create_ip>{2}</spbill_create_ip><trade_type>{3}</trade_type>", out_trade_no, total_fee.ToString(), spbill_create_ip, trade_type); sb.AppendFormat("<notify_url>{0}</notify_url>", notify_url); sb.AppendFormat("<openid>{0}</openid>", openid); //把请求参数打包成数组 Dictionary<string, string> softdic = new Dictionary<string, string>(); softdic.Add("appid", appid); softdic.Add("mch_id", mch_id); softdic.Add("nonce_str", nonce_str); softdic.Add("body", body); softdic.Add("out_trade_no", out_trade_no); softdic.Add("total_fee", total_fee.ToString()); softdic.Add("spbill_create_ip", spbill_create_ip); softdic.Add("trade_type", trade_type); softdic.Add("notify_url", notify_url); softdic.Add("openid", openid); //请求参数体 string strRequest = ""; //加密签名 string strSign = MakeSignData(softdic, ref strRequest); strRequest += "&sign=" + strSign; //打包xml sb.AppendFormat("<sign>{0}</sign></xml>", strSign); //发送请求 string strResponse = RequestWechatpay(sb.ToString()); //URLDECODE返回的信息 Encoding code = Encoding.GetEncoding(input_charset); strResponse = HttpUtility.UrlDecode(strResponse, code); return strResponse; } /// <summary>
      /// 设置当前应用程序指定CacheKey的Cache值
      /// </summary>
      /// <param name="CacheKey"></param>
      /// <param name="objObject"></param>
      public static void SetCache(string CacheKey, object objObject)
      {
       System.Web.Caching.Cache objCache = HttpRuntime.Cache;
                if (objObject!=null)
                    objCache.Insert(CacheKey, objObject, null, DateTime.UtcNow.AddDays(7), TimeSpan.Zero);
      }
    /// <summary>
      /// 获取当前应用程序指定CacheKey的Cache值
      /// </summary>
      /// <param name="CacheKey"></param>
      /// <returns></returns>
      public static object GetCache(string CacheKey)
      {
       System.Web.Caching.Cache objCache = HttpRuntime.Cache;
       return objCache[CacheKey];
      }
    /// <summary> /// 签名原始串 /// </summary> /// <param name="dicParm">所有非空参数</param> /// <param name="strQueryString">请求串</param> /// <returns>签名串</returns> public string MakeSignData(Dictionary<string, string> dicParm, ref string strQueryString) { //先排序 Dictionary<string, string> dicSort = dicParm.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value); StringBuilder sb = new StringBuilder(); //再转换成URL字符串 foreach (KeyValuePair<string, string> kvParm in dicSort) { if (null != kvParm.Value && "".CompareTo(kvParm.Value) != 0 && "sign".CompareTo(kvParm.Key) != 0 && "key".CompareTo(kvParm.Key) != 0 && "sign_type".CompareTo(kvParm.Key) != 0) { if (sb.Length > 0) { sb.Append("&"); strQueryString += "&"; } sb.Append(kvParm.Key + "=" + HttpUtility.UrlDecode(kvParm.Value)); strQueryString += kvParm.Key + "=" + HttpUtility.UrlEncode(kvParm.Value); } } //再和key拼装成字符串 sb.Append("&key=" + key); //再进行MD5加密转成大写 return MD5Create(sb.ToString(), input_charset).ToUpper(); } public static string MD5Create(string str, string charset) { string retStr; MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider(); //创建md5对象 byte[] inputBye; byte[] outputBye; //使用GB2312编码方式把字符串转化为字节数组. try { inputBye = Encoding.GetEncoding(charset).GetBytes(str); } catch (Exception ex) { inputBye = Encoding.GetEncoding("GB2312").GetBytes(str); } outputBye = m5.ComputeHash(inputBye); retStr = System.BitConverter.ToString(outputBye); retStr = retStr.Replace("-", ""); return retStr; } /// <summary> ///把请求参数信息打包发送请求微信支付地址 /// </summary> /// <param name="strRequestData">请求参数字符串(QueryString)</param> /// <returns></returns> private string RequestWechatpay(string strRequestData) { Encoding code = Encoding.GetEncoding(input_charset); //把数组转换成流中所需字节数组类型 byte[] bytesRequestData = code.GetBytes(strRequestData); //请求远程HTTP string strResult = ""; try { //设置HttpWebRequest基本信息 HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(pay_url); myReq.Method = "post"; myReq.ContentType = "text/xml"; //填充POST数据 myReq.ContentLength = bytesRequestData.Length; Stream requestStream = myReq.GetRequestStream(); requestStream.Write(bytesRequestData, 0, bytesRequestData.Length); requestStream.Close(); //发送POST数据请求服务器 HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse(); Stream myStream = HttpWResp.GetResponseStream(); //获取服务器返回信息 StreamReader reader = new StreamReader(myStream, code); StringBuilder responseData = new StringBuilder(); String line; while ((line = reader.ReadLine()) != null) { responseData.Append(line); } //释放 myStream.Close(); strResult = responseData.ToString(); } catch (Exception exp) { strResult = "报错:" + exp.Message; } return strResult; } /// <summary> /// 获得客户端的IP /// </summary> /// <returns>当前页面客户端的IP</returns> public static string GetUserIp() { string userHostAddress = HttpContext.Current.Request.UserHostAddress; if (string.IsNullOrEmpty(userHostAddress)) { userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; } //最后判断获取是否成功,并检查IP地址的格式(检查其格式非常重要) if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress)) { return userHostAddress; } return "127.0.0.1"; } /// <summary> /// 检查IP地址格式 /// </summary> /// <param name="ip"></param> /// <returns></returns> public static bool IsIP(string ip) { return System.Text.RegularExpressions.Regex.IsMatch(ip, @"^((2[0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?)$"); } /// <summary> /// 生成随机字母与数字 /// </summary> /// <param name="IntStr">生成长度</param> /// <returns></returns> public static string StrRodamNo(int Length) { return StrRodam(Length, false); } /// <summary> /// 生成随机字母与数字 /// </summary> /// <param name="Length">生成长度</param> /// <param name="Sleep">是否要在生成前将当前线程阻止以避免重复</param> /// <returns></returns> public static string StrRodam(int Length, bool Sleep) { if (Sleep) System.Threading.Thread.Sleep(3); char[] Pattern = new char[] { '0', '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 result = ""; int n = Pattern.Length; System.Random random = new Random(~unchecked((int)DateTime.Now.Ticks)); for (int i = 0; i < Length; i++) { int rnd = random.Next(0, n); result += Pattern[rnd]; } return result; } #region 读取xml中的指定节点的值 /// <summary> /// 读取xml中的指定节点的值 /// </summary> private string ReadXmlNode(string filename) { string result = "调用微信服务异常"; XmlDocument xmlDoc = new XmlDocument(); try { xmlDoc.LoadXml(filename); XmlNode root = xmlDoc.SelectSingleNode("xml"); if (root != null) result = (root.SelectSingleNode("code_url")).InnerText; } catch (Exception e) { SZRPP.Common.Utils.WriteLogFile("ReadXmlNode:" + e.Message,""); } return result; } #endregion }

     微信返回结果异步通知地址

    wechatpay_notify.aspx

     protected void Page_Load(object sender, EventArgs e)
        {
            
          
            StreamReader reader = new StreamReader(Request.InputStream);
            String xmlData = reader.ReadToEnd();
            Utils.WriteLog("微信异步回调:" + xmlData, "微信异步回调");
            //序列化xml
            Dictionary<string, string> dicParam = GetInfoFromXml(xmlData);
            string data = "";
    
            try
            {
                //当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
                
                if (dicParam.ContainsKey("return_code") && dicParam["return_code"] == "SUCCESS")
                {
                    //通讯成功
                    WechatPayHelper wcHelper = new WechatPayHelper();
                    string strRequestData = "";
                    //计算加密
                    string strSign = wcHelper.MakeSignData(dicParam, ref strRequestData);
                    //判断签名
                    if (strSign == dicParam["sign"])
                    {
                        //判断业务结果
                        if ("SUCCESS" == dicParam["result_code"])
                        {
                            //判断业务是否处理过  
                            string out_trade_no = dicParam["out_trade_no"];//订单编号
                            
                            if (out_trade_no != null)
                            {
                                     OrderPayment payment = payBll.Query(out_trade_no,"");
    
                                if (payment != null)
                                {//商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,防止数据泄漏导致出现“假通知”,造成资金损失。
                                    if (payment.PayPrice.Equals(decimal.Parse(dicParam["total_fee"])/100))
                                    {
                               data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[金额不一致]]></return_msg></xml>";
                                        Response.Write(data);
                                    }
                                    if (payment.PayStatus == 1)
                                    {
                                        //已经支付 视为处理过 直接返回
                                        data = "<xml><return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg></xml>";
                                        Response.Write(data);
                                    }
                                    else
                                    {
                                        //修改支付状态
                                        if (payBll.UpdatePayStatus(out_trade_no, "1",1) > 0)
                                        {
                                            
                                            data = "<xml><return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg></xml>";
                                            Response.Write(data);
                                        }
                                    }
                                }
    
                                else
                                {
                                    data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[系统调用超时]]></return_msg></xml>";
                                    Response.Write(data);
                                }
                            }
                        }
                        else
                        {
                            //错误信息
                            string error = dicParam["err_code"] + ":" + dicParam["err_code_des"];
                            data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[系统调用超时]]></return_msg></xml>";
                            Response.Write(data);
                        }
                    }
                    else
                    {
                        data="<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[系统调用超时]]></return_msg></xml>";
                        Response.Write(data);
                    }
                }
    
            }
            catch (Exception ex)
            {
                Utils.WriteLog("微信异步回调异常:" + ex.Message, "异常日志");
                data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[系统调用超时]]></return_msg></xml>";
                Response.Write(data);
            }
    
        }
    
        /// <summary>
        /// 把XML数据转换为Sorted<string, string>集合
        /// </summary>
        /// <param name="strxml"></param>
        /// <returns></returns>
        public Dictionary<string, string> GetInfoFromXml(string xmlstring)
        {
            Dictionary<string, string> sParams = new Dictionary<string, string>();
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xmlstring);
                XmlElement root = doc.DocumentElement;
                int len = root.ChildNodes.Count;
                for (int i = 0; i < len; i++)
                {
                    string name = root.ChildNodes[i].Name;
                    if (!sParams.ContainsKey(name))
                    {
                        sParams.Add(name.Trim(), root.ChildNodes[i].InnerText.Trim());
                    }
                }
            }
            catch (Exception ex)
            {
                
            }
            return sParams;
        }

     xml配置文件: Wechat_Pay_JSAPI.xml  

    <?xml version="1.0" encoding="utf-8" ?>
    <data>
      <!--接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数-->
      <notify_url>http://8.20.7.8:300/PayNotifyPage/PayNotify/wechatpay_notify.aspx</notify_url>
      <pay_url>https://api.mch.weixin.qq.com/pay/unifiedorder</pay_url>
      <!--微信开放平台审核通过的应用APPID-->
      <appid>wxf99999999999</appid>
      <!--微信支付分配的商户号-->
      <mch_id>148888888882</mch_id>
      <key>16ce9ghjjjjjj5555552ee19d</key>
      <subject>财政专费</subject>
      <trade_type>JSAPI</trade_type>
    </data>

    Wechat_Pay_APP.xml

    
    
    <?xml version="1.0" encoding="utf-8" ?>
    <data>
      <!--接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数-->
      <notify_url>http://8.20.7.8:300/PayNotifyPage/PayNotify/wechatpay_notify.aspx</notify_url>
      <pay_url>https://api.mch.weixin.qq.com/pay/unifiedorder</pay_url>
      <!--微信开放平台审核通过的应用APPID-->
      <appid>wxf99999999999</appid>
      <!--微信支付分配的商户号-->
      <mch_id>148888888882</mch_id>
      <key>16ce9ghjjjjjj5555552ee19d</key>
      <subject>财政专费</subject>
      <trade_type>APP</trade_type>
    </data>
    </data>

    稍加对接口的调整 加一个参数类型 直接使用一个接口即可完成对APP 公众号 jsapi H5 的统一调用即可   当哪一个渠道发起支付请求就唤起哪一个渠道的支付
    至此进行传递参数进行发起下单既可完成整个支付请求了。在这里分开写 主要起到一个牵针引线的作用

  • 相关阅读:
    连续点击来回切换执行回调函数
    css 属性
    html 手机web超出屏幕宽度的内容不换行,并产生横向滚动条
    生活若失去了物质,哪有资格祈求过的开心
    第一天创建自己的博客,有点小激动!?
    挣值分析法
    PMP--论文部分
    软件项目估算之代码行估算方法
    版本管理:配置项版本号规则
    最大最小准则(悲观准则)
  • 原文地址:https://www.cnblogs.com/Warmsunshine/p/8033329.html
Copyright © 2011-2022 走看看