日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

微信公众号开发,微信支付功能开发(网页JSAPI调用)

發布時間:2024/3/13 javascript 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 微信公众号开发,微信支付功能开发(网页JSAPI调用) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、微信支付的流程

如下三張手機截圖,我們在微信網頁端看到的支付,表面上看到的是 “點擊支付按鈕 - 彈出支付框 - 支付成功后出現提示頁面”,實際上的核心處理過程是:
  • 點擊支付按鈕時,執行一個Ajax到后臺
  • 后臺通過前臺的部分信息(如商品名額,金額等),將其組裝成符合微信要求格式的xml,然后調用微信的“統一下單接口”
  • 調用成功后微信會返回一個組裝好的xml,我們提取之中的消息(預支付id也在其中)以JSON形式返回給前臺
  • 前臺將該JSON傳參給微信內置JS的方法中,調其微信支付
  • 支付成功后,微信會將本次支付相關信息返回給我們的服務器

這些在《 微信支付官方文檔 - 場景介紹》和《 微信支付官方文檔 - 業務流程》都進行了更詳細的說明。




2、微信支付功能開發詳解?

2.1 設置支付目錄和授權域名

登陸公眾號,進行支付相關的目錄和域名設置,詳情參考《 微信支付官方文檔 - 開發步驟》,我這里簡單貼幾張官方的圖就行了,這步比較簡單,就不過多說明了,只提其中一點:對于微信支付授權的目錄,發起微信支付的頁面必須精確地位于授權目錄下,假如支付頁面為 http://www.a.com/wx/pay/a.html,那么授權目錄必須為 http://www.a.com/wx/pay/,其他的如 http://www.a.com/wx/ , https://www.a.com/wx/pay/(http和https是不一樣的),http://a.com/wx/pay/(千萬別忘了www)都是不行的。填寫了這些非法目錄無法調起支付。





2.2 組裝xml,調用統一下單接口,獲取prepay_id

2.2.1 組裝xml

點擊支付按鈕后,寫一個Ajax將前臺部分信息發送給后臺,然后組裝xml,調用統一下單接口。該接口在《 微信支付官方文檔 - 統一下單》進行了很詳細的解釋,我在這里進行部分說明:
參數 說明? ?? 備注
appId? ?? 開發者應用ID,在 “開發 - 基本配置” 查看
mch_id 微信支付的商戶號,在 “微信支付 - 商戶信息” 查看
device_info? ?? 終端設備號(門店號或收銀設備ID) PC網頁或公眾號內支付,則傳 “WEB”
body 商品或支付的簡單描述
trade_type 可取值JSAPI,NATIVE,APP等,我們這里使用的是JSAPI JSAPI 公眾號支付;NATIVE 原生掃碼支付;APP app支付
nonce_str 隨機字符串 參考算法:《微信支付官方文檔 - 安全規范》
notify_url 通知地址,微信支付成功后,微信服務器會發送信息到該url
out_trade_no 商戶系統內部訂單號,由商戶自定義,訂單號要保持唯一性
total_fee 訂單總金額,單位:分
openid 用戶標識,用戶在該公眾號下的唯一身份標識
sign 簽名 參考算法:《微信支付官方文檔 - 安全規范
key API密鑰,在 “微信商戶平臺?- 賬戶中心 - API安全 - API密鑰”

其他的都比較簡單,重要的在于這兩個涉及算法的參數,nonce_str 和 sign,這里說明一下:
  • nonce_str 隨機字符串,用于保證簽名不可預測
    • 算法:
    • 官方建議調用隨機數函數生成,然后轉為字符串

  • sign 簽名
    • 算法:
    • 所有發送或接收的數據按參數名ASCII碼從小到大排序,使用鍵值對形式拼接為字符串(如 key1=value1&key2=value2…)
    • ASCII碼的字典排序,可以利用TreeMap幫我們自動實現
    • 將拼接好的字符串最后,再拼接上API密鑰,即key,得到新的字符串
    • 將新的字符串進行MD5加密,并將加密后字符串全部轉換為大寫

按照以上的這些說明,進行xml的拼裝,貼上我自己的測試代碼(注:為方便測試,部分數據我直接寫入方法了,如body、openId等):
  • String appId = WeChatAPI.getAppID();
  • String body = "JSAPI支付測試";
  • String merchantId = WeChatAPI.getMerchantID();
  • String tradeNo = String.valueOf(new Date().getTime());
  • String nonceStr1 = SignUtil.createNonceStr();
  • String notifyUrl = "http://k169710n05.51mypc.cn/pay/do/afterPaySuccess.q";
  • String openId = "okAkc0muYuSJUtvMf25UQHnqYvM4";
  • String totalFee = "1";
  • TreeMap<String, String> map = new TreeMap<String, String>();
  • map.put("appid", appId);
  • map.put("mch_id", merchantId);
  • map.put("device_info", "WEB");
  • map.put("body", body);
  • map.put("trade_type", "JSAPI");
  • map.put("nonce_str", nonceStr1);
  • map.put("notify_url", notifyUrl);
  • map.put("out_trade_no", tradeNo);
  • map.put("total_fee", totalFee);
  • map.put("openid", openId);
  • String sign = SignUtil.createSign(map);
  • String xml = "<xml>" +
  • "<appid>" + appId + "</appid>" +
  • "<body>" + body +"</body>" +
  • "<device_info>WEB</device_info>" +
  • "<mch_id>" + merchantId + "</mch_id>" +
  • "<nonce_str>" + nonceStr1 + "</nonce_str>" +
  • "<notify_url>" + notifyUrl +"</notify_url>" +
  • "<openid>" + openId + "</openid>" +
  • "<out_trade_no>" + tradeNo + "</out_trade_no>" +
  • "<total_fee>" + totalFee + "</total_fee>" +
  • "<trade_type>JSAPI</trade_type>" +
  • "<sign>" + sign + "</sign>" +
  • "</xml>";

  • 注意
    • body參數如果直接填寫中文,在調用接口時會出現“簽名錯誤”,要以ISO8859-1編碼
    • 所以?String body = new String("body內容字符串".getBytes("ISO8859-1"));
    • 但即便如此,在支付完成后微信推送的“微信支付憑證”中,商品詳情中的中文也依然顯示的亂碼

    • body參數內容如果包含中文,那么在調用接口時會出現“簽名錯誤”
    • 在網上找了很多方法,有了如上刪除線部分的方法,但是仍然是有問題的,因為支付成功后的憑證里中文是亂碼
    • 后來終于在網上各種倒騰,找到了原因,確實是編碼問題,但問題不在body是否使用ISO8859-1,而在MD5的加密算法中是否使用UTF-8
    • 所以?md.update(sourceStr.getBytes("UTF-8"));

    兩個算法的代碼如下:
  • /**
  • * 生成隨機數
  • * <p>算法參考:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3</p>
  • * @return 隨機數字符串
  • */
  • public static String createNonceStr() {
  • SecureRandom random = new SecureRandom();
  • int randomNum = random.nextInt();
  • return Integer.toString(randomNum);
  • }
  • /**
  • * 生成簽名,用于在微信支付前,獲取預支付時候需要使用的參數sign
  • * <p>算法參考:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3</p>
  • * @param params 需要發送的所有數據設置為的Map
  • * @return 簽名sign
  • */
  • public static String createSign(TreeMap<String, String> params) {
  • String signValue = "";
  • String stringSignTemp = "";
  • String stringA = "";
  • //獲得stringA
  • Set<String> keys = params.keySet();
  • for (String key : keys) {
  • stringA += (key + "=" + params.get(key) + "&");
  • }
  • stringA = stringA.substring(0, stringA.length() - 1);
  • //獲得stringSignTemp
  • stringSignTemp = stringA + "&key=" + WeChatAPI.getMerchantKey();
  • //獲得signValue
  • signValue = encryptByMD5(stringSignTemp).toUpperCase();
  • log.debug("預支付簽名:" + signValue);
  • return signValue;
  • }
  • /**
  • * MD5加密
  • *
  • * @param sourceStr
  • * @return
  • */
  • public static String encryptByMD5(String sourceStr) {
  • String result = "";
  • try {
  • MessageDigest md = MessageDigest.getInstance("MD5");
  • md.update(sourceStr.getBytes("UTF-8"));
  • byte b[] = md.digest();
  • int i;
  • StringBuffer buf = new StringBuffer("");
  • for (int offset = 0; offset < b.length; offset++) {
  • i = b[offset];
  • if (i < 0)
  • i += 256;
  • if (i < 16)
  • buf.append("0");
  • buf.append(Integer.toHexString(i));
  • }
  • result = buf.toString();
  • } catch (NoSuchAlgorithmException e) {
  • System.out.println(e);
  • }
  • return result;
  • }

  • 2.2.2 調用統一下單接口,獲取prepay_id

    有了組裝好的xml,現在我們直接使用POST方式的請求發送給微信提供的接口就可以了,如果一切順利,我們會收到微信返回的xml字符串,格式示例如下:
  • <xml>
  • <return_code><![CDATA[SUCCESS]]></return_code>
  • <return_msg><![CDATA[OK]]></return_msg>
  • <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
  • <mch_id><![CDATA[10000100]]></mch_id>
  • <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
  • <openid><![CDATA[oUpF8uMuAJO_M2pxb1Q9zNjWeS6o]]></openid>
  • <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
  • <result_code><![CDATA[SUCCESS]]></result_code>
  • <prepay_id><![CDATA[wx201411101639507cbf6ffd8b07629950874]]></prepay_id>
  • <trade_type><![CDATA[JSAPI]]></trade_type>
  • </xml>

  • 其中我們最需要的就是 prepay_id,這個值在后續需要用到。這段過程比較簡單,其中提取prepay_id我是用的正則,我直接貼代碼好了:
  • String url = WeChatAPI.getUrl_prePay();
  • String result = NetUtil.sendRequest(url, "POST", xml);
  • String reg = "<prepay_id><!\\[CDATA\\[(\\w+)\\]\\]></prepay_id>";
  • Pattern pattern = Pattern.compile(reg);
  • Matcher matcher = pattern.matcher(result);
  • String prepayId = "";
  • while (matcher.find()) {
  • prepayId = matcher.group(1);
  • log.debug("預支付ID:" + prepayId);
  • }


  • 2.3 回傳參數,調起微信支付JS

    2.3.1 回傳參數

    這時候,已經有了預支付ID,但是后臺的處理還沒有結束,我們還沒有把該有的信息返回給前臺。那么前臺需要哪些東西呢?《 微信支付官方文檔 - 微信內H5調起支付》有詳細的解釋,這里再貼一下:
    參數???? 說明? ?? 備注
    appId 開發者應用ID,在 “開發 - 基本配置” 查看
    timeStamp? ?? 時間戳,標準北京時間,秒級(10位數字)
    nonceStr? ?? 隨機字符串 參考算法:《微信支付官方文檔 - 安全規范
    package? ?? 訂單詳情擴展字符串,其實就是預支付ID 示例: prepay_id=***
    signType? ?? 簽名方式,暫支持MD5
    paySign? ?? 簽名 參考算法:《微信支付官方文檔 - 安全規范

    有了之前的經驗,想必到這里對這些的獲取已經沒有什么問題了,但是仍然有幾個 注意的地方:
    • package的值是 “prepay_id=***”,而不是 "***" 的方式(***表示之前獲取的prepay_id)
    • timeStamp注意使用標準北京時間,可以使用Calendar設置Locale為CHINA,因為是秒級所以記得除以1000
    • paySign簽名要重新生成,算法還是之前的,但是參數需要除自己以外的?appId、timeStamp、nonceStr、package、signType
    • 之前xml中參數appid是小寫,這里的appId是大寫的I

    好了,因為前臺接受到參數以后會以JSON的形式發送給微信服務器,所以我們這里后臺,直接就把這些參數封裝到一個JSONObject中就行了,然后轉成JSON的形式發給前臺。下面貼一下我的測試代碼,簽名算法和之前一樣,我這里就不重復貼出來了:
  • Date beijingDate = Calendar.getInstance(Locale.CHINA).getTime();
  • String nonceStr2 = SignUtil.createNonceStr();
  • JSONObject json = new JSONObject();
  • json.put("appId", appId);
  • json.put("timeStamp", beijingDate.getTime() / 1000);
  • json.put("nonceStr", nonceStr2);
  • json.put("package", "prepay_id=" + prepayId);
  • json.put("signType", "MD5");
  • TreeMap<String, String> map2 = new TreeMap<String, String>();
  • map2.put("appId", appId);
  • map2.put("timeStamp", String.valueOf(beijingDate.getTime() / 1000));
  • map2.put("nonceStr", nonceStr2);
  • map2.put("package", "prepay_id=" + prepayId);
  • map2.put("signType", "MD5");
  • String paySign = SignUtil.createSign(map2);
  • json.put("paySign", paySign);
  • String re = json.toJSONString();
  • AjaxSupport.sendSuccessText(null, re);

  • 2.3.2 使用微信內置的JS調起微信支付

    前臺的調用就很簡單了,看下官方給的示例代碼:
  • function onBridgeReady(){
  • WeixinJSBridge.invoke(
  • 'getBrandWCPayRequest', {
  • "appId":"wx2421bk1c4370c43b", //公眾號名稱,由商戶傳入
  • "timeStamp":"1395712654", //時間戳,自1970年以來的秒數
  • "nonceStr":"e61463f8efa94090b1f366cccfbbb444", //隨機串
  • "package":"prepay_id=u802345jfgjsdfgsdg888",
  • "signType":"MD5", //微信簽名方式:
  • "paySign":"70EA570631E4B79628FBCS90534C63FF7FADD89" //微信簽名
  • },
  • function(res){
  • if(res.err_msg == "get_brand_wcpay_request:ok" ) {} ?
  • // 使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功后返回ok,但并不保證它絕對可靠。
  • }
  • );
  • }
  • if (typeof WeixinJSBridge == "undefined"){
  • if( document.addEventListener ){
  • document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
  • }else if (document.attachEvent){
  • document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
  • document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
  • }
  • }else{
  • onBridgeReady();
  • }

  • 使用時直接替換掉invoke方法中的參數即可,實際上如果后臺直接是傳遞的JSON字符串到前臺,可以直接解析為JS對象作為參數,下面貼我自己的代碼:
  • $().invoke("/pay/do/pay.q", null, function (re) {
  • var result = JSON.parse(re);
  • function onBridgeReady(){
  • WeixinJSBridge.invoke(
  • 'getBrandWCPayRequest', result, function(res){
  • alert(JSON.stringify(res));
  • if(res.err_msg == "get_brand_wcpay_request:ok" ) {
  • //doit 這里處理支付成功后的邏輯,通常為頁面跳轉
  • }
  • }
  • );
  • }
  • if (typeof WeixinJSBridge == "undefined"){
  • if( document.addEventListener ){
  • document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
  • }else if (document.attachEvent){
  • document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
  • document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
  • }
  • }else{
  • onBridgeReady();
  • }
  • });

  • 這里還有個 ,是iOS和Android系統不同導致的,如上代碼:
    • 如果你在 var result = JSON.parse(re); 之前再添加一個用于debug的輸出語句 ?alert(re);
    • 你可以看到傳過來的各項參數,其中timeStamp的值是沒有雙引號的,這會導致在iOS中支付出現錯誤,提示缺少timeStamp參數

    ? ? 所以為了兼容,必須要將這個轉換成字符串,帶上雙引號:
  • $().invoke("/pay/do/pay.q", null, function (re) {
  • var result = JSON.parse(re);
  • result['timeStamp'] = result['timeStamp'] + "";
  • function onBridgeReady(){
  • WeixinJSBridge.invoke(
  • 'getBrandWCPayRequest', result, function(res){
  • alert(JSON.stringify(res));
  • if(res.err_msg == "get_brand_wcpay_request:ok" ) {
  • //doit 這里處理支付成功后的邏輯,通常為頁面跳轉
  • }
  • }
  • );
  • }
  • if (typeof WeixinJSBridge == "undefined"){
  • if( document.addEventListener ){
  • document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
  • }else if (document.attachEvent){
  • document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
  • document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
  • }
  • }else{
  • onBridgeReady();
  • }
  • });


  • 另外,在這個頁面調試有個小技巧,將微信回調的JS對象序列化為JSON字符串,進行彈窗顯示:alert(JSON.stringify(res));

    2.4 校驗信息的正確性

    實際上在完成上面的步驟以后,已經可以進行微信支付了。這最后一步主要是為了確認支付信息的正確性,以及傳遞給我們本次支付的一些信息,以便業務處理。
    支付成功后,微信會將本次支付的相關信息,以流的方式發送給我們指定的url地址,而我們指定的url地址,就是第一次組裝xml時 <notify_url> 中填寫的地址,下面我們可以先回顧一下:
  • ...
  • String notifyUrl = "http://k169710n05.51mypc.cn/pay/do/afterPaySuccess.q";
  • ...
  • String xml = "<xml>" +
  • "<appid>" + appId + "</appid>" +
  • "<body>" + body +"</body>" +
  • "<device_info>WEB</device_info>" +
  • "<mch_id>" + merchantId + "</mch_id>" +
  • "<nonce_str>" + nonceStr1 + "</nonce_str>" +
  • "<notify_url>" + notifyUrl +"</notify_url>" +
  • "<openid>" + openId + "</openid>" +
  • "<out_trade_no>" + tradeNo + "</out_trade_no>" +
  • "<total_fee>" + totalFee + "</total_fee>" +
  • "<trade_type>JSAPI</trade_type>" +
  • "<sign>" + sign + "</sign>" +
  • "</xml>";

  • 而我們要做的,就是接受到這些信息后,進行處理,并對微信服務器做出應答。如果微信收到商戶的應答不是成功或超時,微信認為通知失敗,微信會通過一定的策略定期重新發起通知,盡可能提高通知的成功率,但微信不保證通知最終能成功。詳情請參考《 微信支付官方文檔 - 支付結果通知》
    需要做三件事
    • 解析微信發來的信息,通過重新簽名的方式驗證信息的正確性,確認信息是否是微信所發
    • return_code和result_code都是SUCCESS的話,處理商戶自己的業務邏輯
    • 應答微信,告訴它說我們收到信息了,不用再發了(如果不進行應答,則微信服務器會通過一定的策略定期重新發起通知)

    過程也很簡單,將微信發來的流信息解析出來之后,再次調用之前的簽名算法,用計算出來的算法,和微信發來的xml中的簽名sign進行對比,如果相同,則說明是微信返回的通知,響應給微信即可。
    注意:驗證調用返回或微信主動通知簽名時,傳送的sign參數不參與簽名,而是將生成的簽名與該sign值作校驗。也就是說,微信發來的xml中包含元素sign,該元素內容不參與簽名算法之中,而是和最后算法的結果進行比較的,所以傳參進行算法的時候不用加入sign值。
    好了,現在我們先看下微信發回來的流信息是什么,實際上文檔里有說明,就是個xml,我們看下官方的示例:
  • <xml>
  • <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
  • <attach><![CDATA[支付測試]]></attach>
  • <bank_type><![CDATA[CFT]]></bank_type>
  • <fee_type><![CDATA[CNY]]></fee_type>
  • <is_subscribe><![CDATA[Y]]></is_subscribe>
  • <mch_id><![CDATA[10000100]]></mch_id>
  • <nonce_str><![CDATA[5d2b6c2a8db53831f7eda20af46e531c]]></nonce_str>
  • <openid><![CDATA[oUpF8uMEb4qRXf22hE3X68TekukE]]></openid>
  • <out_trade_no><![CDATA[1409811653]]></out_trade_no>
  • <result_code><![CDATA[SUCCESS]]></result_code>
  • <return_code><![CDATA[SUCCESS]]></return_code>
  • <sign><![CDATA[B552ED6B279343CB493C5DD0D78AB241]]></sign>
  • <sub_mch_id><![CDATA[10000100]]></sub_mch_id>
  • <time_end><![CDATA[20140903131540]]></time_end>
  • <total_fee>1</total_fee>
  • <trade_type><![CDATA[JSAPI]]></trade_type>
  • <transaction_id><![CDATA[1004400740201409030005092168]]></transaction_id>
  • </xml>

  • 其中除了sign的值,其他的值需要做成集合進行簽名算法,然后結果和sign值對比,相同的話,給微信一個應答,應答的格式官方也給出了示例,如下:
  • <xml>
  • <return_code><![CDATA[SUCCESS]]></return_code>
  • <return_msg><![CDATA[OK]]></return_msg>
  • </xml>

  • 總之,這一部分還是很簡單的,就直接上我的代碼了:
  • /**
  • * 支付成功后的處理
  • * <p>微信支付成功后,對微信返回的信息進行校驗</p>
  • * @return
  • */
  • public String afterPaySuccess() {
  • HttpServletRequest request = ServletActionContext.getRequest();
  • HttpServletResponse response = ServletActionContext.getResponse();
  • TreeMap<String, String> map = new TreeMap<String, String>();
  • try {
  • //解析xml,存入map
  • InputStream inputStream = request.getInputStream();
  • SAXReader saxReader = new SAXReader();
  • Document document = saxReader.read(inputStream);
  • Element rootElement = document.getRootElement();
  • List<Element> elements = rootElement.elements();
  • String reg = "<!\\[CDATA\\[(.+)\\]\\]>";
  • Pattern pattern = Pattern.compile(reg);
  • for (Element element : elements) {
  • String key = element.getName();
  • String value = element.getText();
  • Matcher matcher = pattern.matcher(value);
  • while (matcher.find()) {
  • value = matcher.group(1);
  • }
  • map.put(key, value);
  • }
  • //如果微信結果通知為失敗
  • if ("FAIL".equals(map.get("return_code"))) {
  • log.debug(map.get("return_msg"));
  • return NONE;
  • }
  • //doit 處理商戶業務邏輯
  • //簽名對比,應答微信服務器
  • String signFromWechat = map.get("sign");
  • map.remove("sign");
  • String sign = SignUtil.createSign(map);
  • if (sign.equals(signFromWechat)) {
  • String responseXml = "<xml>" +
  • "<return_code><![CDATA[SUCCESS]]></return_code>" +
  • "<return_msg><![CDATA[OK]]></return_msg>" +
  • "</xml>";
  • response.getWriter().write(responseXml);
  • }
  • } catch (IOException e) {
  • e.printStackTrace();
  • } catch (DocumentException e) {
  • e.printStackTrace();
  • }
  • return NONE;
  • }

  • 另外,如果在執行支付流程中,有部分數據希望能放在支付完成后再處理,可以在組裝xml的時候放置在attach標簽中;然后在支付完成后微信發送來的xml中,會將原數據在此返回。需要注意的是,該attach有字符串的長度限制(詳見文檔),所以試圖直接在支付處理時直接把某個類的JSON格式放進來留做事后處理,是會出錯的(我就是這樣踩了坑),所以用來傳遞一些核心數據就行了。
    再另外,對于最后這部分,看看微信推薦我們的做法是:當收到通知進行處理時,首先檢查對應業務數據的狀態,判斷該通知是否已經處理過,如果沒有處理過再進行處理,如果處理過直接返回結果成功。在對業務數據進行狀態檢查和處理之前,要采用數據鎖進行并發控制,以避免函數重入造成的數據混亂。另,商戶系統對于支付結果通知的內容一定要做簽名驗證,并校驗返回的訂單金額是否與商戶側的訂單金額一致,防止數據泄漏導致出現“假通知”,造成資金損失。

    3、參考鏈接

    • 微信支付之JSAPI開發第一篇-基本概念
    • 微信公眾號支付開發全過程 --JAVA
    • 原文鏈接 http://www.cnblogs.com/deng-cc/p/7183239.html

    總結

    以上是生活随笔為你收集整理的微信公众号开发,微信支付功能开发(网页JSAPI调用)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。