免费国产欧美国日产_少妇AV一区二区三区无码_蜜桃精品av无码喷奶水小说_jk18禁网站视频_精产国品一二三级产品区别_被夫の上司に犯波多野结衣_78m成人手机免费看_最爽最刺激18禁视频_偷偷色噜狠狠狠狠的777米奇

易優(yōu)GEO 重磅上線 ~ 一站式GEO優(yōu)化工具,讓豆包、文心一言、DeepSeek 在回答中主動(dòng)推薦你的品牌,搶占AI流量入口!  點(diǎn)擊查看

小程序模板網(wǎng)

微信小程序接入微信支付實(shí)操記錄

發(fā)布時(shí)間:2018-02-09 14:58 所屬欄目:小程序開(kāi)發(fā)教程

接入微信支付有三種方式:JSAPI,JSSDK,小程序,而小程序的微信支付,官方這次了一次升級(jí)優(yōu)化,對(duì)接開(kāi)發(fā)起來(lái)相比更加簡(jiǎn)易,詳情可見(jiàn)官方文檔(https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1)

官方給出的小程序支付交互流程圖如下,其實(shí)也比較清晰描述了整個(gè)過(guò)程

 

宏記(微信號(hào):hongji8410)為了驗(yàn)證這一過(guò)程,特地去實(shí)操了一下,現(xiàn)整理了下整個(gè)過(guò)程如下:

首先要準(zhǔn)備幾個(gè)東西

  • 小程序APPID(appid)

  • 商戶(hù)號(hào)(mchid)

  • 商家設(shè)置的密鑰(key)

  • 在配置小程序時(shí)的密鑰(secret)

其次,小程序整個(gè)支付流程是分為小程序端調(diào)用與服務(wù)端處理兩大塊的,其中服務(wù)端處理是要與微信服務(wù)端進(jìn)行多次交互處理的。

即 小程序->服務(wù)端——>微信服務(wù)端->服務(wù)端->小程序

小程序端發(fā)起三次請(qǐng)求,兩次向微信服務(wù)器(wx.login和wx.requestPayment),中間一次向服務(wù)端(wx.request)

服務(wù)端發(fā)起兩次請(qǐng)求與加密處理成簽名,兩次都是向微信服務(wù)器請(qǐng)求,一次請(qǐng)求獲取openid,一次統(tǒng)一下單獲取prepay_id,加密處理主要是通過(guò)MD5然后生成簽名參數(shù)sign

簽名參數(shù)sign主要有兩個(gè)用處,一個(gè)是向微信服務(wù)端請(qǐng)求預(yù)支付時(shí)需要用到這個(gè)參數(shù),而另一個(gè)是返回小程序端調(diào)用確認(rèn)支付里需要用到,而簽名的生成都是通過(guò)MD5加密appid+openid/prepay_id等參數(shù)而成

最后分步講解下具體過(guò)程
1. 小程序發(fā)起

調(diào)用wx.login得到j(luò)scode,通過(guò)wx.request把jscode傳送給后臺(tái)

wx.login({
    success:function(res){
      if (res.code) {
        //這里得到j(luò)scode即可傳到后臺(tái)進(jìn)行處理
        wx.request({
        url:'https://www.voopAPI/getData?js_code='+res.code
        data: {},
        method: 'GET', 
        success: function(res){
          //后臺(tái)處理預(yù)支付成功,在這就能得到paySign等確認(rèn)支付需要的參數(shù)
        }
        })
    };
    };
});
2. 服務(wù)端處理

首先根據(jù)傳過(guò)來(lái)的jsCode向微信服務(wù)器請(qǐng)求session_key和openid

public 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;
}

返回?cái)?shù)據(jù)

{\”session_key\”:\”a6Td9fWKZx8LkPFCsGA==\”,\”expires_in\”:7200,\”openid\”:\”oujEK0QoA0wI_DDyE5660\”}

其次根據(jù)openid,appid,mch_id等參數(shù)封裝成一個(gè)字符串后用MD5加密后向微信服務(wù)器統(tǒng)一下單

    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(); 暫時(shí)1分,用于測(cè)試
    paramter.Trade_Type = shopinfo.Trade_type;
    paramter.Key = shopinfo.Key;
    var param = WXHandleBll.GetOrderUnifiedParam(reslogion.openid, paramter);

MD5加密得出簽名sign

public string GetOrderUnifiedParam(string openid, WXPayParameters param)
    {
        //參與統(tǒng)一下單簽名的參數(shù),除最后的key外,已經(jīng)按參數(shù)名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();

        //構(gòu)造統(tǒng)一下單的請(qǐng)求參數(shù)
        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=中國(guó)特館-O2017041200015&mch_id=14107872&nonce_str=819F462C255C424244317&notify_url=http://yourdomain.com/notifyurl&openid=oujEK0QoAI_DDyE5660&out_trade_no=O20170015&spbill_create_ip=127.0.0.1&total_fee=1&trade_type=JSAPI&key=4537751044EE2113393A

MD5后的簽名

DFWGFGF81D73DBA86C645D8A3

簽名規(guī)則注意事項(xiàng)(must)

  • 參數(shù)名ASCII碼從小到大排序(字典序);

  • 如果參數(shù)的值為空不參與簽名;

  • 參數(shù)名區(qū)分大小寫(xiě);

  • 驗(yàn)證調(diào)用返回或微信主動(dòng)通知簽名時(shí),傳送的sign參數(shù)不參與簽名,將生成的簽名與該sign值作校驗(yàn)。

  • 微信接口可能增加字段,驗(yàn)證簽名時(shí)必須支持增加的擴(kuò)展字段

再著,向微信服務(wù)再次進(jìn)行請(qǐng)求(統(tǒng)一下單),獲取預(yù)支付信息

var RespayXML = WXHandleBll.DoPost(param, "https://api.mch.weixin.qq.com/pay/unifiedorder");

發(fā)送的XML樣式

<xml>\r\n <appid>w3e843377f9a</appid> \r\n <body>中國(guó)館-O2017041200015</body>\r\n <mch_id>1445576552</mch_id> \r\n <nonce_str>819F465763A252422644317</nonce_str>\r\n <notify_url>http://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

最后,根據(jù)統(tǒng)一下單請(qǐng)求返回的參數(shù)prepay_id再加上appid等參數(shù)封裝成一個(gè)字符串后用MD5再得出一個(gè)簽名參數(shù),并且處理其它參數(shù)后全部返回小程序端所需要的參數(shù)

    //3.統(tǒng)一下單后拿到的xml結(jié)果
    var payRes = XDocument.Parse(RespayXML);
    var ResXML = payRes.Element("xml");
    //序列化相應(yīng)參數(shù)返回給小程序
    var res = WXHandleBll.GetPayRequestParam(ResXML, paramter.AppId, paramter.Key);    

    public WXPayRequesEntity GetPayRequestParam(XElement root, string appid, string key)
    {
        //當(dāng)return_code 和result_code都為SUCCESS時(shí)才有我們要的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. 小程序端調(diào)用wx.requestPayment彈出密碼輸入框,再輸入密碼進(jìn)行確認(rèn)支付
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) {
          //確認(rèn)成功
      }
});

收集的一些支付坑,方便遇到問(wèn)題可供查閱

  • 微信支付接口要嚴(yán)格區(qū)分大小寫(xiě)。在獲取預(yù)付單數(shù)據(jù)的時(shí)候,timestamp沒(méi)有區(qū)分大小寫(xiě),導(dǎo)致支付的收銀臺(tái)一直調(diào)用不起來(lái)。

  • 簽名操作,一定是要配合appId,appid商戶(hù)號(hào)KEY是否正確,參與簽名的字符串是否按照要求排序,是否是UTF8格式(實(shí)在不行可重置一下),在具體簽名方法說(shuō)明中,可以看出key是在簽名參數(shù)按照ASCII大小排序完再拼接上去的,

  • 返回錯(cuò)誤說(shuō)total_fee參數(shù)為空,如果total_fee參數(shù)不為空,可能是package格式不對(duì)應(yīng)該為”prepay_id=”+prepay_id

  • 統(tǒng)一下單接口是xml(這個(gè)不只是小程序,公眾號(hào)也是),返回值也是xml格式需要自己獲取prepay_id,

  • 簽名算法要帶上key,最后要轉(zhuǎn)換成大些

  • 微信支付的sign算法也要帶上appid(這個(gè)不科學(xué),深坑)

  • 簽名算法一定不要用json拼接key

  • 簽名MD5加密,網(wǎng)上有些算法是錯(cuò)誤的,自己寫(xiě)完還需要在線MD5加密工具進(jìn)行校驗(yàn)(我采坑一下午,怎么看我寫(xiě)的怎么對(duì),就是出不來(lái),原因就是MD5工具使用錯(cuò)誤,坑爹- - )

  • 統(tǒng)一下單簽名appid,wx.requestPayment簽名appId(大小寫(xiě)必須區(qū)分,真是找瞎我鈦合金狗眼- - )

  • wx.requestPayment中package參數(shù)必須是package:”prepay_id=wx21**“,不然,會(huì)出現(xiàn)調(diào)用支付JSAPI缺少appid/total_fee

  • total_fee為分,并且是int

  • 生成隨機(jī)數(shù)和時(shí)間戳一定要保證簽名與上傳參數(shù)一致

  • 微信小程序trade_type=JSAPI,openid參數(shù)必傳

  • wx.requestPayment生成簽名有appId,請(qǐng)求的時(shí)候沒(méi)有appId


本文地址:http://www.szcjxy.com/wxmini/doc/course/21887.html 復(fù)制鏈接 如需定制請(qǐng)聯(lián)系易優(yōu)客服咨詢(xún): 點(diǎn)擊咨詢(xún)
在線客服