(function(){ var version = "2.0.6", hasOwn = {}.hasOwnProperty, PingppSDK = function(){}, cfg = { PINGPP_NOTIFY_URL: 'https://api.pingxx.com/notify/charges/', UPACP_WAP_URL: 'https://gateway.95516.com/gateway/api/frontTransReq.do', ALIPAY_WAP_URL: 'http://wappaygw.alipay.com/service/rest.htm', UPMP_WAP_URL: 'uppay://uppayservice/?style=token&paydata=', JDPAY_WAP_URL: 'https://m.jdpay.com/wepay/web/pay', BFB_SUCCESS: '', YEEPAY_WAP_URL: 'https://ok.yeepay.com/paymobile/api/pay/request', YEEPAY_WAP_TEST_URL: 'http://mobiletest.yeepay.com/paymobile/api/pay/request', PINGPP_MOCK_URL: 'http://sissi.pingxx.com/mock.php' }, channels = { alipay_wap: 'alipay_wap', upmp_wap: 'upmp_wap', upacp_wap: 'upacp_wap', bfb_wap: 'bfb_wap', wx_pub: 'wx_pub', yeepay_wap: 'yeepay_wap', jdpay_wap: 'jdpay_wap' }; PingppSDK.prototype = { version: version, _resultCallback: undefined, _jsApiParameters: {}, _debug: false, _signature: undefined, createPayment: function(charge_json, callback, signature, debug) { if (typeof callback == "function") { this._resultCallback = callback; } if (typeof signature != "undefined") { this._signature = signature; } if (typeof debug == "boolean") { this._debug = debug; } var charge; if(typeof charge_json == "string"){ try{ charge = JSON.parse(charge_json); }catch(err){ this._innerCallback("fail", this._error("json_decode_fail")); return; } }else{ charge = charge_json; } if(typeof charge == "undefined"){ this._innerCallback("fail", this._error("json_decode_fail")); return; } if(!hasOwn.call(charge, 'id')){ this._innerCallback("fail", this._error("invalid_charge", "no_charge_id")); return; } if(!hasOwn.call(charge, 'channel')){ this._innerCallback("fail", this._error("invalid_charge", "no_channel")); return; } var channel = charge['channel']; if(!hasOwn.call(charge, 'credential')){ this._innerCallback("fail", this._error("invalid_charge", "no_credential")); return; } if (!charge['credential']) { this._innerCallback("fail", this._error("invalid_credential", "credential_is_undefined")); return; } if (!hasOwn.call(channels, channel)) { this._innerCallback("fail", this._error("invalid_charge", "no_such_channel:" + channel)); return; } if (!hasOwn.call(charge['credential'], channel)) { this._innerCallback("fail", this._error("invalid_credential", "no_valid_channel_credential")); return; } if(!hasOwn.call(charge, 'livemode')){ this._innerCallback("fail", this._error("invalid_charge", "no_livemode")); return; } if (charge['livemode'] == false) { this._testModeNotify(charge); return; } var credential = charge['credential'][channel]; if (channel == channels.upmp_wap) { // 调起银联支付控件,客户端需要安装银联支付控件才能调起 location.href = cfg.UPMP_WAP_URL + credential['paydata']; } else if (channel == channels.upacp_wap) { form_submit(cfg.UPACP_WAP_URL, 'post', credential); } else if (channel == channels.alipay_wap) { // 调起支付宝手机网页支付 credential['_input_charset'] = 'utf-8'; if (typeof _AP != "undefined") { var query = stringify_data(credential, channel, true); _AP.pay(cfg.ALIPAY_WAP_URL + "?" + query); } else { form_submit(cfg.ALIPAY_WAP_URL, 'get', credential); } } else if (channel == channels.bfb_wap) { if (!hasOwn.call(credential, 'url')) { this._innerCallback("fail", this._error("invalid_credential", "missing_field:url")); return; } location.href = credential['url'] + '?' + stringify_data(credential, channel); } else if (channel == channels.yeepay_wap) { var fields = ["merchantaccount", "encryptkey", "data"]; for(var k in fields){ if(typeof fields[k] !== "function" && !hasOwn.call(credential, fields[k])){ this._innerCallback("fail", this._error("invalid_credential", "missing_field_"+fields[k])); return; } } if (hasOwn.call(credential, "mode") && credential["mode"] == "test") { location.href = cfg.YEEPAY_WAP_TEST_URL + '?' + stringify_data(credential, channel, true); } else { location.href = cfg.YEEPAY_WAP_URL + '?' + stringify_data(credential, channel, true); } } else if (channel == channels.wx_pub) { var fields = ["appId", "timeStamp", "nonceStr", "package", "signType", "paySign"]; for (var k in fields) { if (typeof fields[k] !== "function" && !hasOwn.call(credential, fields[k])) { this._innerCallback("fail", this._error("invalid_credential", "missing_field_"+fields[k])); return; } } this._jsApiParameters = credential; this._callpay(); } else if (channel == channels.jdpay_wap) { form_submit(cfg.JDPAY_WAP_URL, 'post', credential); } }, _jsApiCall: function(){ var self = this; if(self._jsApiParameters != {}){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', self._jsApiParameters, function(res){ if(res.err_msg == 'get_brand_wcpay_request:ok'){ self._innerCallback("success"); }else if(res.err_msg == 'get_brand_wcpay_request:cancel'){ self._innerCallback("cancel"); }else{ self._innerCallback("fail", self._error("wx_result_fail", res.err_msg)); } } ); } }, _callpay: function(){ var self = this; if (typeof wx != "undefined" && typeof self._signature != "undefined") { var wxConfigFailed = false; wx.config({ debug: self._debug, appId: self._jsApiParameters["appId"], timestamp: self._jsApiParameters["timeStamp"], nonceStr: self._jsApiParameters["nonceStr"], signature: self._signature, jsApiList: ['chooseWXPay'] }); wx.ready(function(){ if (wxConfigFailed) { return; } wx.chooseWXPay({ timestamp: self._jsApiParameters["timeStamp"], nonceStr: self._jsApiParameters["nonceStr"], "package": self._jsApiParameters["package"], signType: self._jsApiParameters["signType"], paySign: self._jsApiParameters["paySign"], success: function(res) { if (res.errMsg == "chooseWXPay:ok") { self._innerCallback("success"); } else { self._innerCallback("fail", self._error("wx_result_fail", res.errMsg)); } }, cancel: function(res) { self._innerCallback("cancel"); }, fail: function(res) { self._innerCallback("fail", self._error("wx_result_fail", res.errMsg)); } }); }); wx.error(function(res){ wxConfigFailed = true; self._innerCallback("fail", self._error("wx_config_error", res.errMsg)); }); } else if (typeof WeixinJSBridge == "undefined") { function eventCallback(){ self._jsApiCall(); } if (document.addEventListener) { document.addEventListener('WeixinJSBridgeReady', eventCallback, false); } else if(document.attachEvent) { document.attachEvent('WeixinJSBridgeReady', eventCallback); document.attachEvent('onWeixinJSBridgeReady', eventCallback); } }else{ this._jsApiCall(); } }, _error: function(msg, extra) { msg = (typeof msg == "undefined") ? "" : msg; extra = (typeof extra == "undefined") ? "" : extra; return { msg:msg, extra:extra }; }, _innerCallback: function(result, err) { if (typeof this._resultCallback == "function") { if (typeof err == "undefined") { err = this._error(); } this._resultCallback(result, err); } }, _testModeNotify: function(charge) { var self = this; if (charge['channel'] == channels.wx_pub) { var dopay = confirm("模拟付款?"); if (dopay) { var request = new XMLHttpRequest(); request.open('GET', cfg.PINGPP_NOTIFY_URL+charge['id']+'?livemode=false', true); request.onload = function() { if (request.status >= 200 && request.status < 400 && request.responseText == "success"){ self._innerCallback("success"); } else { var extra = 'http_code:'+request.status+';response:'+request.responseText; self._innerCallback("fail", self._error("testmode_notify_fail", extra)); } }; request.onerror = function() { self._innerCallback("fail", self._error("network_err")); }; request.send(); } else { self._innerCallback("cancel"); } } else { var params = { 'ch_id': charge['id'], 'scheme': 'http', 'channel': charge['channel'] }; if (hasOwn.call(charge, 'order_no')) { params['order_no'] = charge['order_no']; } if (hasOwn.call(charge, 'extra')) { params['extra'] = encodeURIComponent(JSON.stringify(charge['extra'])); } location.href = cfg.PINGPP_MOCK_URL+'?'+stringify_data(params); } } }; function form_submit(url, method, params) { var form = document.createElement("form"); form.setAttribute("method", method); form.setAttribute("action", url); for (var key in params) { if (hasOwn.call(params, key)) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("type", "hidden"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); form.appendChild(hiddenField); } } document.body.appendChild(form); form.submit(); } function stringify_data(data, channel, urlencode) { if (typeof urlencode == "undefined") { urlencode = false; } var output = []; for (var i in data) { if (channel == "bfb_wap" && i == "url") { continue; } if (channel == "yeepay_wap" && i == "mode") { continue; } output.push(i + '=' + (urlencode ? encodeURIComponent(data[i]) : data[i])); } return output.join('&'); } PingppSDK.prototype.payment = PingppSDK.prototype.createPayment; window.pingpp = new PingppSDK(); // aliases window.PINGPP_PAY_SDK = window.PINGPP_WX_PUB = window.pingpp; })();