无码人妻精一区二区三区,eeuss影院www在线观看,无码精品久久久久久人妻中字,日韩av高清在线看片

推薦新聞
微信小程序支付簡(jiǎn)單小結(jié)與梳理
發(fā)布者:深藍(lán)互聯(lián)
發(fā)布時(shí)間:2019-12-10
點(diǎn)擊:次

公司最近在做微信小程序,被分配到做支付這一塊,現(xiàn)在對(duì)這一塊做一個(gè)簡(jiǎn)單的總結(jié)和梳理。

支付,對(duì)于購(gòu)物來(lái)說(shuō),可以說(shuō)是占據(jù)了十分重要的一塊,畢竟能收到錢(qián)才是重點(diǎn)。

當(dāng)然在開(kāi)發(fā)之前,我們需要有下面這些東西:

  • appId
  • 密鑰(小程序配置界面)
  • 商戶(hù)號(hào)
  • api密鑰(商家后臺(tái)自己設(shè)置)

當(dāng)然這些是不用我們自己申請(qǐng)的,公司會(huì)有人申請(qǐng)好,然后要什么跟這個(gè)人說(shuō),讓他提供就可以了。

首先來(lái)看一下官方給出的業(yè)務(wù)流程時(shí)序圖

wxapy

這個(gè)圖很清晰的表達(dá)了在小程序支付中的整個(gè)流程,每一步要做些什么。

一個(gè)完整的支付,一般情況下都是包含了下面三個(gè)主要的點(diǎn);

  • 支付(正常是支付平臺(tái)提供的h5頁(yè)面讓用戶(hù)操作,主要是輸密碼)
  • 通知(用戶(hù)完成一筆支付了,支付平臺(tái)要通知商家支付結(jié)果,商家收到結(jié)果后進(jìn)行一些相應(yīng)的處理)
  • 查詢(xún)(與第二點(diǎn)有點(diǎn)反過(guò)來(lái)的意思,商家自己主動(dòng)去支付平臺(tái)查詢(xún)支付的結(jié)果,然后根據(jù)結(jié)果做相應(yīng)的處理)

下面就重點(diǎn)來(lái)簡(jiǎn)單實(shí)現(xiàn)一下上面說(shuō)的第一點(diǎn),支付,也是可以進(jìn)行下面兩步的在大前提。

支付的簡(jiǎn)單實(shí)現(xiàn)

小程序的實(shí)現(xiàn)

簡(jiǎn)單起見(jiàn),在index.wxml中添加一個(gè)輸入框和一個(gè)button,綁定一下相應(yīng)的事件,輸入框主要是用于輸入訂單號(hào),按鈕用于模擬提交一個(gè)訂單并發(fā)起支付。

<!--index.wxml-->
<view class="container">
    <input type="text" bindinput="getOrderCode" style="border:1px solid #ccc;"  />
    <button bindtap="pay">立即支付</button>
</view>

然后在index.js中寫(xiě)上一小段代碼,主要是處理上面按鈕的點(diǎn)擊事件。

Page({
    data: {
        txtOrderCode: ''
    },
    pay: function () {
        var ordercode = this.data.txtOrderCode;
        wx.login({
          success: function (res) {
            if (res.code) {
              wx.request({
                url: 'https://www.yourdomain.com/pay',
                data: {
                  code: res.code,//要去換取openid的登錄憑證
                  ordercode: ordercode
                },
                method: 'GET',
                success: function (res) {
                  console.log(res.data)
                  wx.requestPayment({
                    timeStamp: res.data.timeStamp,
                    nonceStr: res.data.nonceStr,
                    package: res.data.package,
                    signType: 'MD5',
                    paySign: res.data.paySign,
                    success: function (res) {
                      // success
                      console.log(res);
                    },
                    fail: function (res) {
                      // fail
                      console.log(res);
                    },
                    complete: function (res) {
                      // complete
                      console.log(res);
                    }
                  })
                }
              })
            } else {
              console.log('獲取用戶(hù)登錄態(tài)失敗!' + res.errMsg)
            }
          }
        });
    },
    getOrderCode: function (event) {
        this.setData({
          txtOrderCode: event.detail.value
        });
    }
})

可以看到,在這里Catcher先通過(guò)wx.login這個(gè)API先取到了登錄的憑證code,并把這個(gè)憑證code做為請(qǐng)求參數(shù)用wx.request這個(gè)API發(fā)起一個(gè)網(wǎng)絡(luò)請(qǐng)求。

在這個(gè)網(wǎng)絡(luò)請(qǐng)求處理后會(huì)返回小程序支付所需要的相關(guān)參數(shù)。拿到這些參數(shù)后,再調(diào)用wx.requestPayment這個(gè)支付API,此時(shí)才算是真正的發(fā)起支付。

至此,小程序這邊的事已經(jīng)做完了,接下來(lái)就是要去處理接口那邊的事了,其實(shí)接口要做的就是返回小程序需要的幾個(gè)參數(shù)。但是要拿到這幾個(gè)參數(shù)還是需要做不少事情的。

接口的實(shí)現(xiàn)

據(jù)悉最新版的Senparc.Weixin.MP已經(jīng)支付了小程序相關(guān)的內(nèi)容,但是公司用的版本還是比較低

并且近期也沒(méi)有打算對(duì)這個(gè)組件進(jìn)行升級(jí)。所以就從白紙一張開(kāi)始了。

用的是mvc,所以這個(gè)小程序發(fā)起的網(wǎng)絡(luò)請(qǐng)求會(huì)由下面的action的執(zhí)行,里面的實(shí)現(xiàn),每一步做了什么應(yīng)該也已經(jīng)很清晰了。

public ActionResult Pay(string code, string ordercode)
{
    var paramter = new Parameters();
    paramter.out_trade_no = ordercode;

    //使用登錄憑證 code 獲取 session_key 和 openid
    var unifiedorderRes = GetOpenIdAndSessionKey(paramter.appid, paramter.secret, code);

    //反序列化session_key 和 openid成ChangeResponseEntity實(shí)體
    var tmp = JsonConvert.DeserializeObject<ChangeResponseEntity>(unifiedorderRes);

    //統(tǒng)一下單的url和參數(shù)
    var payUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    var param = GetUnifiedOrderParam(tmp.openid, paramter);
               
    //統(tǒng)一下單后拿到的xml結(jié)果
    var payResXML = Helper.DoPost(param, payUrl);
    var payRes = XDocument.Parse(payResXML);
    var root = payRes.Element("xml");
    
    //序列化相應(yīng)參數(shù)返回給小程序
    var res = GetPayRequestParam(root, paramter.appid, paramter.key);
    return Json(res, JsonRequestBehavior.AllowGet);            
}

由于只是一個(gè)演示的過(guò)程,不想這些數(shù)據(jù)經(jīng)常以字符串的形式頻繁出現(xiàn)在代碼中,所以把相關(guān)的參數(shù)全部都放到了一個(gè)名為Parameters的類(lèi)中(放到配置文件中也是可以的),除了訂單號(hào)是從小程序傳過(guò)來(lái)的,當(dāng)然在實(shí)際中這是不合理的,畢竟像金額這些東西,不可能每次都是同一個(gè)!這點(diǎn)是要注意的。

下面先來(lái)看看這個(gè)Parameters類(lèi)的定義:

public class Parameters
{      
    public string appid { get { return "申請(qǐng)的appid"; } }
    public string mchid { get { return "申請(qǐng)的商戶(hù)號(hào)"; } }
    public string nonce { get { return Helper.GetNoncestr(); } }
    public string notify_url { get { return "http://yourdomain.com/notifyurl"; } }
    public string body { get { return "testpay"; } }
    public string out_trade_no { get; set; }
    public string spbill_create_ip { get { return "IP地址"; } }
    public string total_fee { get { return "1"; } }
    public string trade_type { get { return "JSAPI"; } }
    public string key { get { return "在商家后臺(tái)設(shè)置的密鑰"; } }
    public string secret { get { return "在配置小程序時(shí)的密鑰"; } }
}

首先是獲取到登錄憑證后發(fā)起的這個(gè)網(wǎng)絡(luò)請(qǐng)求。這個(gè)網(wǎng)絡(luò)請(qǐng)求是決定了這次支付能否成功的第一步!

下面要做的是用登錄憑證去換我們要的openid。

/// <summary>
/// 取openid和session_key
/// </summary>
/// <param name="appid"></param>
/// <param name="secret"></param>
/// <param name="js_code"></param>
/// <returns></returns>
private string GetOpenIdAndSessionKey(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;
}

要換取openid,就要向微信提供的地址發(fā)起一個(gè)網(wǎng)絡(luò)請(qǐng)求,并在URL帶上appid,secret和憑證code這三個(gè)參數(shù)。

然后就可以拿到一個(gè)下面形式的json字符串

{
  "openid": "OPENID",
  "session_key": "SESSIONKEY"
}

拿到之后自然就是要對(duì)這個(gè)字符串進(jìn)行json的反序列化,這里用到了json.net這個(gè)包。

根據(jù)時(shí)序圖,下面要調(diào)用統(tǒng)一下單這個(gè)接口了。

上面的代碼,在統(tǒng)一下單這一塊,又分為下面幾個(gè)步驟

  1. 處理統(tǒng)一下單的參數(shù)(簽名和組裝xml)
  2. 發(fā)起POST請(qǐng)求
  3. 解析請(qǐng)求得到的結(jié)果

參數(shù)的處理:

具體規(guī)則參見(jiàn):https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3

/// <summary>
/// 取統(tǒng)一下單的請(qǐng)求參數(shù)
/// </summary>
/// <param name="openid"></param>
/// <param name="param"></param>
/// <returns></returns>
private string GetUnifiedOrderParam(string openid, Parameters 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 = Helper.GetMD5(unifiedorderSignParam).ToUpper();
    //構(gòu)造統(tǒng)一下單的請(qǐng)求參數(shù)
   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>
                    ", 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);
    
}

這里要注意一點(diǎn),由于我們的傳的trade_type是JSAPI,所以這里必須是要加上openid進(jìn)行處理的。

然后就是解析統(tǒng)一下單返回的XML了,說(shuō)是解析,其實(shí)也就是要拿到我們需要的數(shù)據(jù)罷了。這里最后會(huì)得到一個(gè)小程序支付API需要的參數(shù)實(shí)體。

/// <sum               

 

  • 聯(lián)系地址
    中國(guó) 深圳 龍華區(qū)龍觀西路99號(hào)順泰中晟大廈一棟14樓13A01
  • 聯(lián)系電話(huà)
    電話(huà):13530005652 / 0755-23110995
  • 電子郵箱
    wisepu@szdbi.com
關(guān)注深藍(lán)互聯(lián)公眾號(hào)
Copyright ? 2013-2025 深藍(lán)互聯(lián) 版權(quán)所有
友情鏈接: