1. 程式人生 > >基於HTML5之APP微信支付整合實現(轉載)

基於HTML5之APP微信支付整合實現(轉載)

一 摘要

商戶系統和微信支付系統主要互動說明:

步驟1:使用者在商戶APP中選擇商品,提交訂單,選擇微信支付。
步驟2:商戶後臺收到使用者支付單,呼叫微信支付統一下單介面。參見統一下單API。
步驟3:統一下單介面返回正常的prepay_id,再按簽名規範重新生成簽名後,將資料傳輸給APP。參與簽名的欄位名為appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式為Sign=WXPay
步驟4:商戶APP調起微信支付。
步驟5:商戶後臺接收支付通知。
步驟6:商戶後臺查詢支付結果。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

二 效果

1)橫屏效果

這裡寫圖片描述

2)豎屏效果

這裡寫圖片描述

三 具體程式碼實現

1)全域性變數

var payType; //支付方式:200 微信支付, 310 到店支付
        var fromType; //代表從哪裡過來的
        var orderNbr; // 訂單號
        var orderId; // 訂單id
        var orderPrice; // 訂單價格
        var orderName; // 訂單價格
        var projectId; // 專案id
        var serviceType; // 服務型別
        var merchantId; // 商家id
        var parentId;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2)實現過程

mui.plusReady(function() {
            var self = plus.webview.currentWebview();
            fromType = self.fromType;
            orderNbr = self.orderNbr;
            orderId = self.orderId;
            orderPrice = self.orderPrice;
            orderName = self.orderName;
            projectId = self
.projectId; serviceType = self.serviceType; merchantId = self.merchantId; parentId = self.parentId; // 設定展示資料 document.getElementById('order-price').innerHTML = '¥' + orderPrice; document.getElementById('pay-price').innerHTML = '¥' + orderPrice; /* * 獲取支付通道 */ plus.payment.getChannels(function(channels) { for (var i in channels) { var channel = channels[i]; pays[channel.id] = channel; checkServices(channel); //檢測是否安裝支付服務 console.log('======安的支付服務=====' + channel.id) } }, function(e) { mui.toast("獲取支付失敗"); }); //選擇支付模式 radioOnChange(); });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

3)賦值

document.getElementById('wxpay').addEventListener('tap', function() {
            this.querySelector('input').checked = true;
            payType = '200';
            //          console.log("payType"+payType);
        });
        document.getElementById('ddpay').addEventListener('tap', function() {
            this.querySelector('input').checked = true;
            payType = '310';
            //          console.log("payType"+payType);
        });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

4)選擇支付模式

function radioOnChange() {
            var payRadio = document.getElementsByName("radio1");
            for (var i = 0; i < payRadio.length; i++) {
                if (payRadio[i].checked) {
                    payType = payRadio[i].value;
                    console.log('====支付方式payType=====' + payType)
                }
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5)支付

function pay(id) {
            if (w) {
                return;
            } //檢查是否請求訂單中
            var url = PAYSERVER;
            if (mui.os.ios) {
                systemtype = 'IOS';
            }
            if (wxappid == 'wx741484d992c17831') {
                url += 'orderSn=' + orderNbr + '&cMerchantId=' + MERCHANTID + '&type=' + systemtype + '&payType_appId=2';
            } else {
                url += 'orderSn=' + orderNbr + '&cMerchantId=' + MERCHANTID + '&type=' + systemtype;
            }
            w = plus.nativeUI.showWaiting();
            // 請求支付訂單
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url);
            console.log("請求支付訂單:" + url)
            xhr.send();
            xhr.onreadystatechange = function() {
                switch (xhr.readyState) {
                    case 4:
                        w.close();
                        w = null;
                        if (xhr.status == 200) {
                            var data = xhr.responseText;
                            console.log("-----請求訂單成功-----" + data)
                            var prepayid = JSON.parse(data).data.prepayId; //商戶訂單號
                            var timestamp = new Date().getTime(); //當前時間戳
                            if (mui.os.ios) {
                                timestamp = parseInt(timestamp / 1000);
                            }
                            var noncestr = generateMixed(16); //16位隨機字串
                            var signStr = "appid=" + wxappid + "&noncestr=" + noncestr + "&package=" + "Sign=WXPay" + "&partnerid=" + wxpartnerid + "&prepayid=" + prepayid + "&timestamp=" + timestamp + "&key=" + partnerKey;
                            var sign = hex_md5(signStr).toUpperCase(); //生成簽名
                            var order = '{"appid":"' + wxappid + '","noncestr":"' + noncestr + '","package":"Sign=WXPay","partnerid":"' + wxpartnerid + '","prepayid":"' + prepayid + '","timestamp":' + timestamp + ',"sign":"' + sign + '"}';

                            plus.payment.request(pays[id], order, function(result) {
                                plus.nativeUI.alert("支付成功", function() {
                                    orderQueryStatus('0');
                                    //                                  back();
                                }, "支付");
                            }, function(e) {
                                //                              orderQueryStatus('-1');
                                plus.nativeUI.alert("支付失敗", null, "支付失敗"); // + e.code+e.message
                            });
                        } else {
                            plus.nativeUI.alert("獲取訂單資訊失敗!", null, "支付");
                        }
                        break;
                    default:
                        break;
                }
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

6)支付成功或失敗時返回的狀態

function orderQueryStatus(wxCode) {
            var URL_PAY = SERVER_URL + 'wxpay/order/cartOrderQuery.do';
            mui.ajax(URL_PAY, {
                data: {
                    orderSn: orderNbr, //730348977370697729訂單號
                    cMerchantId: MERCHANTID,
                    wx_errcode: wxCode,
                    type: systemtype
                },
                dataType: 'json',
                type: 'post',
                timeout: 10000,
                success: function(data) {
                    /*
                     * 跳到我的訂單
                     */
                    goMyOrder();
                },
                error: function(xhr, type, errorThrown) {
                    mui.toast('網路異常,請稍後再試!');
                }
            });
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

7)我的訂單裡付款,根據訂單orderId改變訂單狀態

function updatePayStatusByOrderid() {
            var URL_1 = SERVER_URL + 'updateOrderPayStatusById.do';
            mui.ajax(URL_1, {
                data: {
                    orderId: orderId, // 訂單號
                    payStatus: payType
                },
                dataType: 'json',
                type: 'post',
                timeout: 10000,
                success: function(data) {
                    if (data.status == 100) {
                        if (payType == 310) {
                            if (plus.webview.getWebviewById(parentId)) {
                                plus.webview.getWebviewById(parentId).reload();
                            }
                            if (plus.webview.getWebviewById('order-detail')) {
                                plus.webview.getWebviewById('order-detail').close();
                            }
                            plus.webview.currentWebview().close();
                        }
                    } else {
                        mui.toast(data.msg);
                    }
                },
                error: function(xhr, type, errorThrown) {
                    mui.toast('網路異常,請稍後再試!');
                }
            });
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

8)跳轉到我的訂單

function goMyOrder() {
            if (plus.webview.getWebviewById('../order/order-main.html')) {
                mui.fire(plus.webview.getWebviewById('../order/order-main.html'), 'refersh');
                plus.webview.currentWebview().close();
            } else {
                mui.openWindow({
                    id: '../order/order-main.html',
                    url: '../order/order-main.html',
                    waiting: {
                        autoShow: true
                    }
                });
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

9)返回事件

/*返回事件*/
        mui.back = function() {
            if (fromType != '') {
                // 從我的訂單進來
                plus.webview.currentWebview().close();
            } else {
                // 購物車或立即預約,提示訂單已經生成
                var btnArray = ['確定', '取消'];
                mui.confirm('\n訂單已經生成可以在訂單管理檢視\n', '', btnArray, function(e) {
                    if (e.index == 0) {
                        // 確定
                        goMyOrder();
                    } else {
                        // 取消
                        var cartOrderView = plus.webview.getWebviewById('cart-order');
                        if (cartOrderView) {
                            cartOrderView.close();
                        }
                        var orderView = plus.webview.getWebviewById('order');
                        if (orderView) {
                            orderView.close();
                        }
                        plus.webview.currentWebview().close();
                    }
                });
            }
        }