pingpp.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. (function(){
  2. var
  3. version = "2.0.7",
  4. hasOwn = {}.hasOwnProperty,
  5. PingppSDK = function(){},
  6. cfg = {
  7. PINGPP_NOTIFY_URL: 'https://api.pingxx.com/notify/charges/',
  8. UPACP_WAP_URL: 'https://gateway.95516.com/gateway/api/frontTransReq.do',
  9. ALIPAY_WAP_URL: 'http://wappaygw.alipay.com/service/rest.htm',
  10. UPMP_WAP_URL: 'uppay://uppayservice/?style=token&paydata=',
  11. JDPAY_WAP_URL: 'https://m.jdpay.com/wepay/web/pay',
  12. YEEPAY_WAP_URL: 'https://ok.yeepay.com/paymobile/api/pay/request',
  13. YEEPAY_WAP_TEST_URL: 'http://mobiletest.yeepay.com/paymobile/api/pay/request',
  14. PINGPP_MOCK_URL: 'http://sissi.pingxx.com/mock.php'
  15. },
  16. channels = {
  17. alipay_wap: 'alipay_wap',
  18. upmp_wap: 'upmp_wap',
  19. upacp_wap: 'upacp_wap',
  20. bfb_wap: 'bfb_wap',
  21. wx_pub: 'wx_pub',
  22. yeepay_wap: 'yeepay_wap',
  23. jdpay_wap: 'jdpay_wap'
  24. };
  25. PingppSDK.prototype = {
  26. version: version,
  27. _resultCallback: undefined,
  28. _jsApiParameters: {},
  29. _debug: false,
  30. _signature: undefined,
  31. createPayment: function(charge_json, callback, signature, debug) {
  32. if (typeof callback == "function") {
  33. this._resultCallback = callback;
  34. }
  35. if (typeof signature != "undefined") {
  36. this._signature = signature;
  37. }
  38. if (typeof debug == "boolean") {
  39. this._debug = debug;
  40. }
  41. var charge;
  42. if(typeof charge_json == "string"){
  43. try{
  44. charge = JSON.parse(charge_json);
  45. }catch(err){
  46. this._innerCallback("fail", this._error("json_decode_fail"));
  47. return;
  48. }
  49. }else{
  50. charge = charge_json;
  51. }
  52. if(typeof charge == "undefined"){
  53. this._innerCallback("fail", this._error("json_decode_fail"));
  54. return;
  55. }
  56. if(!hasOwn.call(charge, 'id')){
  57. this._innerCallback("fail", this._error("invalid_charge", "no_charge_id"));
  58. return;
  59. }
  60. if(!hasOwn.call(charge, 'channel')){
  61. this._innerCallback("fail", this._error("invalid_charge", "no_channel"));
  62. return;
  63. }
  64. var channel = charge['channel'];
  65. if(!hasOwn.call(charge, 'credential')){
  66. this._innerCallback("fail", this._error("invalid_charge", "no_credential"));
  67. return;
  68. }
  69. if (!charge['credential']) {
  70. this._innerCallback("fail", this._error("invalid_credential", "credential_is_undefined"));
  71. return;
  72. }
  73. if (!hasOwn.call(channels, channel)) {
  74. this._innerCallback("fail", this._error("invalid_charge", "no_such_channel:" + channel));
  75. return;
  76. }
  77. if (!hasOwn.call(charge['credential'], channel)) {
  78. this._innerCallback("fail", this._error("invalid_credential", "no_valid_channel_credential"));
  79. return;
  80. }
  81. if(!hasOwn.call(charge, 'livemode')){
  82. this._innerCallback("fail", this._error("invalid_charge", "no_livemode"));
  83. return;
  84. }
  85. if (charge['livemode'] == false) {
  86. this._testModeNotify(charge);
  87. return;
  88. }
  89. var credential = charge['credential'][channel];
  90. if (channel == channels.upmp_wap) { // 调起银联支付控件,客户端需要安装银联支付控件才能调起
  91. location.href = cfg.UPMP_WAP_URL + credential['paydata'];
  92. } else if (channel == channels.upacp_wap) {
  93. form_submit(cfg.UPACP_WAP_URL, 'post', credential);
  94. } else if (channel == channels.alipay_wap) { // 调起支付宝手机网页支付
  95. credential['_input_charset'] = 'utf-8';
  96. if (typeof _AP != "undefined") {
  97. var query = stringify_data(credential, channel, true);
  98. _AP.pay(cfg.ALIPAY_WAP_URL + "?" + query);
  99. } else {
  100. form_submit(cfg.ALIPAY_WAP_URL, 'get', credential);
  101. }
  102. } else if (channel == channels.bfb_wap) {
  103. if (!hasOwn.call(credential, 'url')) {
  104. this._innerCallback("fail", this._error("invalid_credential", "missing_field:url"));
  105. return;
  106. }
  107. location.href = credential['url'] + '?' + stringify_data(credential, channel);
  108. } else if (channel == channels.yeepay_wap) {
  109. var fields = ["merchantaccount", "encryptkey", "data"];
  110. for (var k = 0; k < fields.length; k++) {
  111. if(!hasOwn.call(credential, fields[k])){
  112. this._innerCallback("fail", this._error("invalid_credential", "missing_field_"+fields[k]));
  113. return;
  114. }
  115. }
  116. if (hasOwn.call(credential, "mode") && credential["mode"] == "test") {
  117. location.href = cfg.YEEPAY_WAP_TEST_URL + '?' + stringify_data(credential, channel, true);
  118. } else {
  119. location.href = cfg.YEEPAY_WAP_URL + '?' + stringify_data(credential, channel, true);
  120. }
  121. } else if (channel == channels.wx_pub) {
  122. var fields = ["appId", "timeStamp", "nonceStr", "package", "signType", "paySign"];
  123. for (var k = 0; k < fields.length; k++) {
  124. if (!hasOwn.call(credential, fields[k])) {
  125. this._innerCallback("fail", this._error("invalid_credential", "missing_field_"+fields[k]));
  126. return;
  127. }
  128. }
  129. this._jsApiParameters = credential;
  130. this._callpay();
  131. } else if (channel == channels.jdpay_wap) {
  132. form_submit(cfg.JDPAY_WAP_URL, 'post', credential);
  133. }
  134. },
  135. _jsApiCall: function(){
  136. var self = this;
  137. if(self._jsApiParameters != {}){
  138. WeixinJSBridge.invoke(
  139. 'getBrandWCPayRequest',
  140. self._jsApiParameters,
  141. function(res){
  142. if(res.err_msg == 'get_brand_wcpay_request:ok'){
  143. self._innerCallback("success");
  144. }else if(res.err_msg == 'get_brand_wcpay_request:cancel'){
  145. self._innerCallback("cancel");
  146. }else{
  147. self._innerCallback("fail", self._error("wx_result_fail", res.err_msg));
  148. }
  149. }
  150. );
  151. }
  152. },
  153. _callpay: function(){
  154. var self = this;
  155. if (typeof wx != "undefined" && typeof self._signature != "undefined") {
  156. var wxConfigFailed = false;
  157. wx.config({
  158. debug: self._debug,
  159. appId: self._jsApiParameters["appId"],
  160. timestamp: self._jsApiParameters["timeStamp"],
  161. nonceStr: self._jsApiParameters["nonceStr"],
  162. signature: self._signature,
  163. jsApiList: ['chooseWXPay']
  164. });
  165. wx.ready(function(){
  166. if (wxConfigFailed) {
  167. return;
  168. }
  169. wx.chooseWXPay({
  170. timestamp: self._jsApiParameters["timeStamp"],
  171. nonceStr: self._jsApiParameters["nonceStr"],
  172. "package": self._jsApiParameters["package"],
  173. signType: self._jsApiParameters["signType"],
  174. paySign: self._jsApiParameters["paySign"],
  175. success: function(res) {
  176. if (res.errMsg == "chooseWXPay:ok") {
  177. self._innerCallback("success");
  178. } else {
  179. self._innerCallback("fail", self._error("wx_result_fail", res.errMsg));
  180. }
  181. },
  182. cancel: function(res) {
  183. self._innerCallback("cancel");
  184. },
  185. fail: function(res) {
  186. self._innerCallback("fail", self._error("wx_result_fail", res.errMsg));
  187. }
  188. });
  189. });
  190. wx.error(function(res){
  191. wxConfigFailed = true;
  192. self._innerCallback("fail", self._error("wx_config_error", res.errMsg));
  193. });
  194. } else if (typeof WeixinJSBridge == "undefined") {
  195. function eventCallback(){
  196. self._jsApiCall();
  197. }
  198. if (document.addEventListener) {
  199. document.addEventListener('WeixinJSBridgeReady', eventCallback, false);
  200. } else if(document.attachEvent) {
  201. document.attachEvent('WeixinJSBridgeReady', eventCallback);
  202. document.attachEvent('onWeixinJSBridgeReady', eventCallback);
  203. }
  204. }else{
  205. this._jsApiCall();
  206. }
  207. },
  208. _error: function(msg, extra) {
  209. msg = (typeof msg == "undefined") ? "" : msg;
  210. extra = (typeof extra == "undefined") ? "" : extra;
  211. return {
  212. msg:msg,
  213. extra:extra
  214. };
  215. },
  216. _innerCallback: function(result, err) {
  217. if (typeof this._resultCallback == "function") {
  218. if (typeof err == "undefined") {
  219. err = this._error();
  220. }
  221. this._resultCallback(result, err);
  222. }
  223. },
  224. _testModeNotify: function(charge) {
  225. var self = this;
  226. if (charge['channel'] == channels.wx_pub) {
  227. var dopay = confirm("模拟付款?");
  228. if (dopay) {
  229. var request = new XMLHttpRequest();
  230. request.open('GET', cfg.PINGPP_NOTIFY_URL+charge['id']+'?livemode=false', true);
  231. request.onload = function() {
  232. if (request.status >= 200 && request.status < 400 && request.responseText == "success"){
  233. self._innerCallback("success");
  234. } else {
  235. var extra = 'http_code:'+request.status+';response:'+request.responseText;
  236. self._innerCallback("fail", self._error("testmode_notify_fail", extra));
  237. }
  238. };
  239. request.onerror = function() {
  240. self._innerCallback("fail", self._error("network_err"));
  241. };
  242. request.send();
  243. } else {
  244. self._innerCallback("cancel");
  245. }
  246. } else {
  247. var params = {
  248. 'ch_id': charge['id'],
  249. 'scheme': 'http',
  250. 'channel': charge['channel']
  251. };
  252. if (hasOwn.call(charge, 'order_no')) {
  253. params['order_no'] = charge['order_no'];
  254. } else if (hasOwn.call(charge, 'orderNo')) {
  255. params['order_no'] = charge['orderNo'];
  256. }
  257. if (hasOwn.call(charge, 'time_expire')) {
  258. params['time_expire'] = charge['time_expire'];
  259. } else if (hasOwn.call(charge, 'timeExpire')) {
  260. params['time_expire'] = charge['timeExpire'];
  261. }
  262. if (hasOwn.call(charge, 'extra')) {
  263. params['extra'] = encodeURIComponent(JSON.stringify(charge['extra']));
  264. }
  265. location.href = cfg.PINGPP_MOCK_URL+'?'+stringify_data(params);
  266. }
  267. }
  268. };
  269. function form_submit(url, method, params) {
  270. var form = document.createElement("form");
  271. form.setAttribute("method", method);
  272. form.setAttribute("action", url);
  273. for (var key in params) {
  274. if (hasOwn.call(params, key)) {
  275. var hiddenField = document.createElement("input");
  276. hiddenField.setAttribute("type", "hidden");
  277. hiddenField.setAttribute("name", key);
  278. hiddenField.setAttribute("value", params[key]);
  279. form.appendChild(hiddenField);
  280. }
  281. }
  282. document.body.appendChild(form);
  283. form.submit();
  284. }
  285. function stringify_data(data, channel, urlencode) {
  286. if (typeof urlencode == "undefined") {
  287. urlencode = false;
  288. }
  289. var output = [];
  290. for (var i in data) {
  291. if (channel == "bfb_wap" && i == "url") {
  292. continue;
  293. }
  294. if (channel == "yeepay_wap" && i == "mode") {
  295. continue;
  296. }
  297. output.push(i + '=' + (urlencode ? encodeURIComponent(data[i]) : data[i]));
  298. }
  299. return output.join('&');
  300. }
  301. PingppSDK.prototype.payment = PingppSDK.prototype.createPayment;
  302. window.pingpp = new PingppSDK();
  303. // aliases
  304. window.PINGPP_PAY_SDK = window.PINGPP_WX_PUB = window.pingpp;
  305. })();