閱讀316 返回首頁    go iPhone_iPad_Mac_apple


微信小程序教程 第二十七篇 微信小程序支付

微信小程序支付

接入微信支付有三種方式: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)

其次,小程序整個支付流程是分為小程序端調用與服務端處理兩大塊的,其中服務端處理是要與微信服務端進行多次交互處理的。

即 小程序->服務端——>微信服務端->服務端->小程序

簽名參數sign主要有兩個用處,一個是向微信服務端請求預支付時需要用到這個參數,而另一個是返回小程序端調用確認支付裏需要用到,而簽名的生成都是通過MD5加密appid+openid/prepay_id等參數而成

最後分步講解下具體過程

1. 小程序發起

success:function(res){

if (res.code) {

//這裏得到jscode即可傳到後台進行處理

url:'https://www.voopAPI/getData?js_code='+res.code

data: {},

method: 'GET',

success: function(res){

//後台處理預支付成功,在這就能得到paySign等確認支付需要的參數

}

})

};

};

});

2. 服務端處理

public string GetSessionKeyOpenId(string appid, string secret, string js_code)

{

var url = string.Format("https://api.weixin.qq.com/sns/jscode2session?appid=&secret=&js_code=&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加密後向微信服務器統一下單

paramter.AppId = shopinfo.AppId;

paramter.Body = shopinfo.ShopName + "-" + orderpool.OrderPoolCode;

paramter.MchId = shopinfo.MchId;

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;

MD5加密得出簽名sign

public string GetOrderUnifiedParam(string openid, WXPayParameters param)

{

//參與統一下單簽名的參數,除最後的key外,已經按參數名ASCII碼從小到大排序

var unifiedorderSignParam = string.Format("appid=&body=&mch_id=&nonce_str=¬ify_url=&openid=&out_trade_no=&spbill_create_ip=&total_fee=&trade_type=&key="

, 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(@"

", 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¬ify_url=https://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

簽名規則注意事項(must)

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

如果參數的值為空不參與簽名;

參數名區分大小寫;

驗證調用返回或微信主動通知簽名時,傳送的sign參數不參與簽名,將生成的簽名與該sign值作校驗。

微信接口可能增加字段,驗證簽名時必須支持增加的擴展字段

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

發送的XML樣式

\r\n w3e843377f9a \r\n 中國館-O2017041200015\r\n 1445576552 \r\n 819F465763A252422644317\r\n https://voopaip.com/notifyurl\r\noujEK0Q3oAuwI_DDyE5660\r\n O2017200015\r\n 127.0.0.1\r\n 1\r\n JSAPI\r\n A5381D73DBA86D3DC645D8A3\r\n \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=&nonceStr=&package=&signType=&timeStamp=&key=",

appid, nonceStr, package, signType, timeStamp, key);

var paySign = GetMD5(paySignParam).ToUpper();

{

package = package,

nonceStr = nonceStr,

paySign = paySign,

signType = signType,

timeStamp = timeStamp

};

return payEntity;

}

}

返回XML樣式

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) {

//確認成功

}

});

收集的一些支付坑,方便遇到問題可供查閱

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

3.返回錯誤說total_fee參數為空,如果total_fee參數不為空,可能是package格式不對應該為”prepay_id=”+prepay_id,統一下單接口是xml(這個不隻是小程序,公眾號也是),返回值也是xml格式需要自己獲取prepay_id,

4.簽名算法要帶上key,最後要轉換成大些

5.微信支付的sign算法也要帶上appid(這個不科學,深坑)

6.簽名算法一定不要用json拚接key

7.簽名MD5加密,網上有些算法是錯誤的,自己寫完還需要在線MD5加密工具進行校驗(我采坑一下午,怎麼看我寫的怎麼對,就是出不來,原因就是MD5工具使用錯誤,坑爹- - )

8.統一下單簽名appid,wx.requestPayment簽名appId(大小寫必須區分,真是找瞎我鈦合金狗眼- - )

9.wx.requestPayment中package參數必須是package:”prepay_id=wx21**“,不然,會出現調用支付JSAPI缺少appid/total_fee

10.total_fee為分,並且是int

11.生成隨機數和時間戳一定要保證簽名與上傳參數一致

13.wx.requestPayment生成簽名有appId,請求的時候沒有appId

最後更新:2017-10-08 02:11:51

  上一篇:go 雲交易時代 微信雲交易
  下一篇:go 微信小程序教程