微信小程序开发之接入微信支付实操记录
凌雪 2018-11-12 来源 :网络 阅读 1168 评论 0

摘要:本文将带你了解微信小程序开发之接入微信支付实操记录,希望本文对大家学微信有所帮助。

本文将带你了解微信小程序开发之接入微信支付实操记录,希望本文对大家学微信有所帮助。


接入微信支付有三种方式:JSAPI,JSSDK,小程序,而小程序的微信支付,官方这次了一次升级优化,对接开发起来相比更加简易,详情可见官方文档(https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1)官方给出的小程序支付交互流程图如下,其实也比较清晰描述了整个过程宏记(微信号:hongji8410)为了验证这一过程,特地去实操了一下,现整理了下整个过程如下:首先要准备几个东西小程序APPID(appid)商户号(mchid)商家设置的密钥(key)在配置小程序时的密钥(secret)其次,小程序整个支付流程是分为小程序端调用与服务端处理两大块的,其中服务端处理是要与微信服务端进行多次交互处理的。即 小程序->服务端——>微信服务端->服务端->小程序小程序端发起三次请求,两次向微信服务器(wx.login和wx.requestPayment),中间一次向服务端(wx.request)服务端发起两次请求与加密处理成签名,两次都是向微信服务器请求,一次请求获取openid,一次统一下单获取prepay_id,加密处理主要是通过MD5然后生成签名参数sign签名参数sign主要有两个用处,一个是向微信服务端请求预支付时需要用到这个参数,而另一个是返回小程序端调用确认支付里需要用到,而签名的生成都是通过MD5加密appid+openid/prepay_id等参数而成最后分步讲解下具体过程1. 小程序发起调用wx.login得到jscode,通过wx.request把jscode传送给后台wx.login({
      success:function(res){
      if (res.code)   {
        //这里得到jscode即可传到后台进行处理
          wx.request({
          url:'https://www.voopAPI/getData?js_code='+res.code
        data:   {},
        method:   'GET',
        success:   function(res){
          //后台处理预支付成功,在这就能得到paySign等确认支付需要的参数
          }
        })
    };
    };
    });2. 服务端处理首先根据传过来的jsCode向微信服务器请求session_key和openidpublic string   GetSessionKeyOpenId(string appid, string secret, string js_code)
    {
        var url =   string.Format("https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code",   appid, secret, js_code);            
    var request =   WebRequest.Create(url) as HttpWebRequest;
    var response =   request.GetResponse();
    var respStream =   response.GetResponseStream();
    var res =   string.Empty;
    using (var reader = new   StreamReader(respStream, Encoding.UTF8))
    {
        res =   reader.ReadToEnd();
    }
    return res;
    }返回数据{\”session_key\”:\”a6Td9fWKZx8LkPFCsGA==\”,\”expires_in\”:7200,\”openid\”:\”oujEK0QoA0wI_DDyE5660\”}其次根据openid,appid,mch_id等参数封装成一个字符串后用MD5加密后向微信服务器统一下单    var   paramter = new WXPayParameters();
    paramter.AppId =   shopinfo.AppId;
    paramter.Body =   shopinfo.ShopName + "-" + orderpool.OrderPoolCode;
    paramter.MchId =   shopinfo.MchId;
    paramter.Nonce =   WXHandleBll.GetNoncestr();
    paramter.Notify_Url =   shopinfo.Notify_Url;
    paramter.Out_Trade_No =   orderpool.OrderPoolCode;
      paramter.Spbill_Create_Ip = "127.0.0.1";
    paramter.Total_Fee =   "1";//(orderpool.NetAmt).ToString(); 暂时1分,用于测试
      paramter.Trade_Type = shopinfo.Trade_type;
    paramter.Key =   shopinfo.Key;
    var param = WXHandleBll.GetOrderUnifiedParam(reslogion.openid,   paramter);MD5加密得出签名signpublic   string GetOrderUnifiedParam(string openid, WXPayParameters param)
    {
        //参与统一下单签名的参数,除最后的key外,已经按参数名ASCII码从小到大排序
          var 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}"
              , param.AppId, param.Body, param.MchId, param.Nonce, param.Notify_Url,   openid, param.Out_Trade_No, param.Spbill_Create_Ip, param.Total_Fee,   param.Trade_Type, param.Key);
   
              //MD5
        var   unifiedorderSign = GetMD5(unifiedorderSignParam).ToUpper();
   
            //构造统一下单的请求参数
          var requestParam = 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>
    ", param.AppId, param.Body, param.MchId, param.Nonce,   param.Notify_Url, openid, param.Out_Trade_No, param.Spbill_Create_Ip,   param.Total_Fee, param.Trade_Type, unifiedorderSign);
        return   requestParam;
    }将要MD5的字符串appid=w362e8457f1ca&body=中国特馆-O2017041200015&mch_id=14107872&nonce_str=819F462C255C424244317&notify_url=//yourdomain.com/notifyurl&openid=oujEK0QoAI_DDyE5660&out_trade_no=O20170015&spbill_create_ip=127.0.0.1&total_fee=1&trade_type=JSAPI&key=4537751044EE2113393AMD5后的签名DFWGFGF81D73DBA86C645D8A3签名规则注意事项(must)参数名ASCII码从小到大排序(字典序);如果参数的值为空不参与签名;参数名区分大小写;验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。微信接口可能增加字段,验证签名时必须支持增加的扩展字段再着,向微信服务再次进行请求(统一下单),获取预支付信息var RespayXML = WXHandleBll.DoPost(param,   "https://api.mch.weixin.qq.com/pay/unifiedorder");发送的XML样式<xml>\r\n <appid>w3e843377f9a</appid> \r\n   <body>中国馆-O2017041200015</body>\r\n   <mch_id>1445576552</mch_id> \r\n   <nonce_str>819F465763A252422644317</nonce_str>\r\n   <notify_url>//voopaip.com/notifyurl</notify_url>\r\n<openid>oujEK0Q3oAuwI_DDyE5660</openid>\r\n   <out_trade_no>O2017200015</out_trade_no>\r\n   <spbill_create_ip>127.0.0.1</spbill_create_ip>\r\n   <total_fee>1</total_fee>\r\n   <trade_type>JSAPI</trade_type>\r\n   <sign>A5381D73DBA86D3DC645D8A3</sign>\r\n </xml>\r\n最后,根据统一下单请求返回的参数prepay_id再加上appid等参数封装成一个字符串后用MD5再得出一个签名参数,并且处理其它参数后全部返回小程序端所需要的参数    //3.统一下单后拿到的xml结果
      var payRes = XDocument.Parse(RespayXML);
    var ResXML =   payRes.Element("xml");
    //序列化相应参数返回给小程序
      var res = WXHandleBll.GetPayRequestParam(ResXML, paramter.AppId,   paramter.Key);    
   
        public   WXPayRequesEntity 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;
              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();
   
                  var payEntity = new WXPayRequesEntity
              {
                  package = package,
                  nonceStr = nonceStr,
                  paySign = paySign,
                  signType = signType,
                  timeStamp = timeStamp
              };
              return payEntity;
        }
   
            return   new WXPayRequesEntity();
    }返回XML样式<xml>   <return_code><![CDATA[SUCCESS]]></return_code>   <return_msg><![CDATA[OK]]></return_msg>   <appid><![CDATA[w2e84759cca]]></appid>   <mch_id><![CDATA[141008772]]></mch_id> <nonce_str><![CDATA[brDijFx44Xx4Nl]]></nonce_str>   <sign><![CDATA[690985862E39F75F03D447E3C9]]></sign>   <result_code><![CDATA[SUCCESS]]></result_code>   <prepay_id><![CDATA[w201702219c9a14b79b753854012]]></prepay_id>   <trade_type><![CDATA[JSAPI]]></trade_type> </xml>3. 小程序端调用wx.requestPayment弹出密码输入框,再输入密码进行确认支付wx.requestPayment({
      timeStamp:   res.data.Body.Data.timeStamp,
      nonceStr:   res.data.Body.Data.nonceStr,
      package:   res.data.Body.Data.package,
      signType:   'MD5',
      paySign: res.data.Body.Data.paySign,
      success:   function (res) {
          //确认成功
        }
    });收集的一些支付坑,方便遇到问题可供查阅微信支付接口要严格区分大小写。在获取预付单数据的时候,timestamp没有区分大小写,导致支付的收银台一直调用不起来。签名操作,一定是要配合appId,appid商户号KEY是否正确,参与签名的字符串是否按照要求排序,是否是UTF8格式(实在不行可重置一下),在具体签名方法说明中,可以看出key是在签名参数按照ASCII大小排序完再拼接上去的,返回错误说total_fee参数为空,如果total_fee参数不为空,可能是package格式不对应该为”prepay_id=”+prepay_id统一下单接口是xml(这个不只是小程序,公众号也是),返回值也是xml格式需要自己获取prepay_id,签名算法要带上key,最后要转换成大些微信支付的sign算法也要带上appid(这个不科学,深坑)签名算法一定不要用json拼接key签名MD5加密,网上有些算法是错误的,自己写完还需要在线MD5加密工具进行校验(我采坑一下午,怎么看我写的怎么对,就是出不来,原因就是MD5工具使用错误,坑爹- - )统一下单签名appid,wx.requestPayment签名appId(大小写必须区分,真是找瞎我钛合金狗眼- - )wx.requestPayment中package参数必须是package:”prepay_id=wx21**“,不然,会出现调用支付JSAPI缺少appid/total_feetotal_fee为分,并且是int生成随机数和时间戳一定要保证签名与上传参数一致微信小程序trade_type=JSAPI,openid参数必传wx.requestPayment生成签名有appId,请求的时候没有appId    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之微信频道!

本文由 @凌雪 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程