ctk-1.0.0.js 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250
  1. !function (win, func) {
  2. typeof define == "function" && (define.amd || define.cmd) ? define(function() {
  3. return func(win);
  4. }) : func(win);
  5. }(this, function(win) {
  6. var andHandler = win.CTKJavaScriptHandler;
  7. var andApiLevel = andHandler && andHandler.getApiLevel() || 0;
  8. var iosHandler, iosApiLevel = 0;
  9. var NET_URL = 'http://121.52.250.37:15080';
  10. var TOUCHLIFE_URL = 'http://121.52.250.37:15080';
  11. var readyList = [];
  12. var ALIPAY_TYPE = 'alipay';
  13. var WEIPAY_TYPE = 'weipay';
  14. var WEIPAY_OEM_TYPE = 'weipay_oem';
  15. var successLogin, failLogin;
  16. var successSelect, failSelect;
  17. var payCallBack;
  18. var totalFee = 0, tradeService = '', products = [], cards = [];
  19. var submit;
  20. var loading, loadImg, loadText, loadTimer;
  21. var sucGetAddrCb; //address iframe post message;
  22. var addrFrame, addrLink; //address iframe;
  23. var addrFrameId = 'i-ct-op-address';
  24. var hasLoadAddressIFrame = false;
  25. var frame, link; //cashier iframe;
  26. var originDisplayState;
  27. var payType = '';
  28. var isIOS = win.navigator.userAgent.toLowerCase().indexOf('iphone') != -1;
  29. var base64 = new Base64();
  30. var apiList = {
  31. ready: { ios: 0, and: 0 },
  32. logged: { ios: 1, and: 10 },
  33. login: { ios: 1, and: 10 },
  34. select: { ios: 0, and: 0 },
  35. pay: {
  36. alipay: { ios: 1, and: 10 },
  37. weipay: { ios: 3, and: 19 }
  38. },
  39. show: { ios: 0, and: 0 },
  40. dismiss: { ios: 0, and: 0 },
  41. getLocation: { ios: 1, and: 0}
  42. }
  43. var caller = arguments.callee
  44. caller.NET_URL = NET_URL;
  45. caller.TOUCHLIFE_URL = TOUCHLIFE_URL;
  46. caller.pageBack = pageBack;
  47. caller.getToken = getToken;
  48. caller.getSecret = getSecret;
  49. caller.collectScenarioParams = collectScenarioParams;
  50. caller.andApiLevel = andApiLevel;
  51. caller.isIOS = isIOS;
  52. caller.shareToWechat = shareToWechat;
  53. caller.shareToMoment = shareToMoment;
  54. caller.loadFile = loadFile;
  55. caller.getItemFromStorage = getItemFromStorage;
  56. loadFile('style', NET_URL + '/res/css/lib/ctk_ui.css');
  57. loadFile('script', NET_URL + '/res/js/lib/ctk_ui.js');
  58. try {
  59. $;
  60. } catch (e) {
  61. try {
  62. window.$ = Zepto;
  63. } catch (e2) {
  64. try {
  65. window.$ = jQuery;
  66. } catch (e3) {
  67. loadFile('script', NET_URL + '/res/js/lib/zepto.v2.js');
  68. }
  69. }
  70. }
  71. if (isIOS) {
  72. (function(callback) {
  73. if (win.WebViewJavascriptBridge) {
  74. callback(WebViewJavascriptBridge)
  75. } else {
  76. document.addEventListener('WebViewJavascriptBridgeReady', function() {
  77. callback(WebViewJavascriptBridge)
  78. }, false);
  79. }
  80. })(function(bridge) {
  81. if (!bridge._messageHandler) {
  82. bridge.init(function(message, responseCallback) {});
  83. }
  84. console.log = function (data) {
  85. WebViewJavascriptBridge.callHandler('log', data, function(response) {});
  86. }
  87. win.onerror = function(sMsg, sUrl, sLine){
  88. console.log('sMsg: ' + sMsg + '; sUrl: ' + sUrl + '; sLine: ' + sLine);
  89. return false;
  90. }
  91. try {
  92. document.readyState == 'complete' && initCTK();
  93. } catch(e) {
  94. console.log('------------- init ctk error');
  95. }
  96. console.log('------------- init callback');
  97. win.CTK = win.CTK || {
  98. dispatchEvent: function() {
  99. console.log('------------- init dispatchEvent');
  100. var self = this;
  101. iosHandler = window.WebViewJavascriptBridge;
  102. iosApiLevel = self.ApiLevel;
  103. caller.iosApiLevel = iosApiLevel;
  104. console.log(iosHandler);
  105. console.log(iosApiLevel);
  106. iosApiLevel >= 3 && (history.back = pageBack);
  107. iosApiLevel >= 1 && (navigator.geolocation && (navigator.geolocation.getCurrentPosition = getCurrentPosition));
  108. readyList.forEach(function(node) {
  109. typeof node == 'function' && node();
  110. });
  111. showTarget(caller);
  112. }
  113. };
  114. var timer = setInterval(function() {
  115. if (window.WebViewJavascriptBridge) {
  116. if (iosHandler) {
  117. clearInterval(timer);
  118. } else {
  119. iosHandler = window.WebViewJavascriptBridge;
  120. iosApiLevel = CTK.ApiLevel;
  121. iosApiLevel >= 3 && (history.back = pageBack);
  122. iosApiLevel >= 1 && (navigator.geolocation && (navigator.geolocation.getCurrentPosition = getCurrentPosition));
  123. readyList.forEach(function(node) {
  124. typeof node == 'function' && node();
  125. });
  126. caller.iosApiLevel = iosApiLevel;
  127. showTarget(caller);
  128. }
  129. }
  130. }, 100);
  131. });
  132. } else {
  133. andApiLevel > 0 && (history.back = pageBack);
  134. if (andApiLevel >= 20) {
  135. andHandler.setOpenOrCloseXinGePush(true);
  136. }
  137. showTarget(caller);
  138. }
  139. // if (window.location.href.indexOf('sdk.hua1000.com/view/pay.html') != -1) {
  140. // showNotice2(caller, {
  141. // text: '点击”立即支付“,立享优惠'
  142. // });
  143. // }
  144. // if (window.location.href.indexOf('sdk.hua1000.com/view/submit.html') != -1) {
  145. // showNotice2(caller, {
  146. // text: '持券用户,立享优惠'
  147. // });
  148. // }
  149. // if (window.location.href.indexOf('sdk.hua1000.com/view/order.html') != -1) {
  150. // showNotice2(caller, {
  151. // text: '点击”立即支付“,立享优惠'
  152. // });
  153. // }
  154. // if (window.location.href.indexOf('http://m.lyancoffee.com/wechat/third/13/order/confirm') != -1) {
  155. // showNotice2(caller, {
  156. // text: '持券用户点“立即支付”可享优惠'
  157. // });
  158. // }
  159. // if (window.location.href.indexOf('http://www.iyishengyuan.com/common_pay_order/1.html') != -1 || window.location.href.indexOf('http://www.iyishengyuan.com/?_a=payOrder&_c=pay') != -1) {
  160. // showNotice2(caller, {
  161. // text: '持券用户点“立即支付”可享优惠',
  162. // type: 'top'
  163. // });
  164. // }
  165. // if (window.location.href.indexOf('http://www.dangaoss.com/h5/cart/checkout') != -1) {
  166. // showNotice2(caller, {
  167. // text: '提交订单,确认配送信息',
  168. // type: 'top'
  169. // });
  170. // }
  171. // if (window.location.href.indexOf('http://www.dangaoss.com/h5/order/show') != -1) {
  172. // showNotice2(caller, {
  173. // text: '点击“立即支付”,持券立享优惠',
  174. // type: 'top'
  175. // });
  176. // }
  177. // if (window.location.href.indexOf('http://www.openlife.mobi/confirmOrderPage?productId=6b33398a-68a0-428b-b756-9aa70c31c432') != -1) {
  178. // showNotice2(caller, {
  179. // text: '点击“确认支付”,持券立享优惠'
  180. // });
  181. // }
  182. window.addEventListener('message', function(event) {
  183. if (event.origin == NET_URL && event.data.type == 'tradeStr') {
  184. var tradeStr = event.data.tradeStr;
  185. payType = event.data.payType;
  186. if (tradeStr) {
  187. if (typeof successSelect == 'function') {
  188. successSelect({
  189. tradeStr: event.data.tradeStr
  190. });
  191. }
  192. } else {
  193. typeof failSelect == 'function' && failSelect({});
  194. }
  195. } else if (event.origin == NET_URL && event.data.type == 'getDefaultAddress') {
  196. var res = {
  197. 'name' : event.data.name,
  198. 'phone' : event.data.phone,
  199. 'province' : event.data.province,
  200. 'city' : event.data.city,
  201. 'country' : event.data.country,
  202. 'addr' : event.data.addr,
  203. 'contact_id' : event.data.contact_id,
  204. };
  205. if (typeof sucGetAddrCb == 'function') {
  206. setTimeout(function() {
  207. var action = event.data.action;
  208. if (!action) {
  209. if (!event.data.noBack) {
  210. if (window.location.hash == '#address') {
  211. hiddenOrShowOtherDiv(addrFrameId, false);
  212. pageBack();
  213. }
  214. }
  215. sucGetAddrCb(res);
  216. } else if (action == 'del') { // 有些业务需要知道某个地址被删除了;
  217. res['action'] = 'del';
  218. sucGetAddrCb(res);
  219. }
  220. }, 200);
  221. }
  222. } else if (event.origin == NET_URL && event.data.type == 'log') {
  223. console.log(event.data.log);
  224. }
  225. });
  226. function initCTK() {
  227. WebViewJavascriptBridge.callHandler('getLoginNumber', null, function(res) {
  228. CTK.LoginNumber = res;
  229. });
  230. WebViewJavascriptBridge.callHandler('getAuthToken', null, function(res) {
  231. CTK.AuthToken = res;
  232. });
  233. WebViewJavascriptBridge.callHandler('getApiLevel', null, function(res) {
  234. CTK.ApiLevel = iosApiLevel = res*1;
  235. });
  236. WebViewJavascriptBridge.callHandler('getSecret', null, function(res) {
  237. CTK.Secret = res;
  238. });
  239. WebViewJavascriptBridge.callHandler('getWXPaySupported', null, function(res) {
  240. switch (res) {
  241. case 'true':
  242. CTK.WXPaySupported = true;
  243. break;
  244. case 'false':
  245. CTK.WXPaySupported = false;
  246. break;
  247. }
  248. });
  249. WebViewJavascriptBridge.callHandler('getWeixinAppInstalled', null, function(res) {
  250. switch (res) {
  251. case 'true':
  252. CTK.WXAppInstalled = true;
  253. break;
  254. case 'false':
  255. CTK.WXAppInstalled = false;
  256. break;
  257. }
  258. });
  259. }
  260. function inner() {
  261. var number = getLoginNumber() + '';
  262. if (number.indexOf('13800000000') != -1) {
  263. return true;
  264. } else {
  265. return false;
  266. }
  267. }
  268. function loadFile(type, url) {
  269. if ((type + url) in window) {
  270. return;
  271. }
  272. var node = document.createElement(type);
  273. var xhr = new XMLHttpRequest();
  274. xhr.onreadystatechange = function() {
  275. if (xhr.readyState == 4 && ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304)) {
  276. node.innerHTML = xhr.responseText;
  277. document.head.appendChild(node);
  278. window[type + url] = true;
  279. }
  280. }
  281. xhr.open("GET", url, false);
  282. xhr.send(null);
  283. }
  284. function initPayPopup() {
  285. frame = document.createElement('div');
  286. link = document.createElement('iframe');
  287. frame.style.cssText = 'position: fixed; top: 0; left: 0; z-index: 9999; width: 100%; height: 100%; display: none';
  288. link.style.cssText = 'display: block; width: 100%; height: 100%';
  289. link.setAttribute('frameborder', '0');
  290. link.src = NET_URL + '/page_v3/cashier.html?tradeService=' + tradeService + '&totalFee=' + totalFee;
  291. frame.appendChild(link);
  292. document.body.appendChild(frame);
  293. window.cashierLink = link;
  294. window.removeEventListener('hashchange', _hideLogin);
  295. window.addEventListener('hashchange', _hideLogin);
  296. //isLoadCompleted用于判断iframe是否加载完毕
  297. link.addEventListener('load',function(){
  298. window.isIframeLoadCompleted = true;
  299. window.loadQueue && window.loadQueue();
  300. },false);
  301. function _hideLogin() {
  302. if (window.location.hash != '#cashier') {
  303. frame.style.display = 'none';
  304. link.contentWindow && link.contentWindow.postMessage({
  305. status: 'close'
  306. }, '*');
  307. }
  308. }
  309. }
  310. function initAddress() {
  311. function _hideLogin() {
  312. var h = window.location.hash;
  313. if (h == '') {
  314. CTAW.hidden();
  315. }
  316. }
  317. //set localstorage native_param_addr
  318. var _addr = getItemFromStorage('native_param_addr');
  319. if (_addr && _addr.length > 0) {
  320. localStorage.setItem('native_param_addr', _addr);
  321. }
  322. console.log('ycs call CTAW init');
  323. CTAW.init();
  324. window.addEventListener('hashchange', _hideLogin);
  325. }
  326. function showPayPopup(inapp) {
  327. var ali = true;
  328. var wei = true;
  329. if (isIOS && iosApiLevel < 3) {
  330. wei = false;
  331. } else if (!isIOS && andApiLevel < 19) {
  332. if (andApiLevel < 10) {
  333. ali = false;
  334. }
  335. wei = false;
  336. } else {
  337. // android higher version
  338. if (!isWXAppInstalled()) {
  339. wei = false;
  340. } else if (!isWXPaySupported()) {
  341. wei = false;
  342. }
  343. }
  344. frame.style.display = 'block';
  345. link.contentWindow.postMessage({
  346. status: 'start',
  347. tradeService: tradeService,
  348. products : products || [],
  349. totalFee: totalFee,
  350. token: getToken(),
  351. secret: getSecret(),
  352. ali: ali,
  353. wei: wei,
  354. inapp: inapp || false
  355. }, '*');
  356. window.location.hash = '#cashier';
  357. }
  358. function showAddress(_curContactId) {
  359. var msg = {
  360. status : 'start'
  361. }
  362. if (_curContactId && _curContactId.length > 5) {
  363. msg.curContactId = _curContactId;
  364. }
  365. if (isIOS) {
  366. var token = getToken();
  367. msg.token = token; //iOS在跨域的情况下,iframe页面无法通过调接口获取token,需要传参;
  368. addrLink.contentWindow.postMessage(msg, '*');
  369. setTimeout(function() {
  370. addrFrame.style.display = 'block';
  371. window.location.hash = '#address';
  372. hiddenOrShowOtherDiv(addrFrameId, true);
  373. }, 500);
  374. } else {
  375. // 地址控件页面要求一个状态切换,即输入框页面滑动,为了不让用户看到,先发一个message告诉地址控件页面滑动;
  376. // 也发现在部分机型上,父页面的点击事件会传到地址控件页面导致出错,将timeout时间设为500可以解决该问题;
  377. addrLink.contentWindow.postMessage(msg, '*');
  378. setTimeout(function() {
  379. addrFrame.style.display = 'block';
  380. window.location.hash = '#address';
  381. hiddenOrShowOtherDiv(addrFrameId, true);
  382. }, 500);
  383. }
  384. }
  385. // iOS特殊处理,iPhone6、5c上发现弹出键盘后会把父页面显示出来;
  386. // hidden 必须是 true,false成对调用,当hidden为true时初始化originDisplayState;
  387. function hiddenOrShowOtherDiv(assignId, hidden) {
  388. if (!isIOS) {
  389. return;
  390. }
  391. var cs = document.body.children;
  392. if (hidden) {
  393. originDisplayState = new Array(cs.length + 2);
  394. }
  395. for (var i = 0; i < cs.length; ++i) {
  396. var item = cs[i];
  397. if (item.tagName == 'SCRIPT') { // script标签忽略;
  398. continue;
  399. }
  400. if (item.getAttribute('id') == assignId) { // 需要显示的iframe忽略;
  401. continue;
  402. }
  403. if (hidden) { // 隐藏所有子元素,先记录原来的状态;
  404. originDisplayState[i] = item.style.display;
  405. item.style.display = 'none';
  406. } else { // 恢复所有子元素原来的状态;
  407. item.style.display = originDisplayState[i];
  408. }
  409. }
  410. }
  411. function decodeIOSSecret(secret) {
  412. var e = "";
  413. for (var i = 0; i < secret.length; i++)
  414. {
  415. e += String.fromCharCode((secret.charCodeAt(i) - 33) / 3);
  416. }
  417. var middle = e.length - parseInt(e.length / 4);
  418. var prefix = e.substring(0, middle);
  419. var suffix = e.substring(middle, e.length);
  420. var unmix = suffix + prefix;
  421. middle = unmix.length - parseInt(unmix.length / 7);
  422. prefix = unmix.substring(0, middle);
  423. suffix = unmix.substring(middle, unmix.length);
  424. return suffix + prefix;
  425. }
  426. function payResult(resCode){
  427. var url = 'http://open.cootekservice.com/pay/result?transactionId=' + localStorage.getItem('transaction_id') + "&resCode=" + resCode + '&_token=' + getToken();
  428. var xhr = new XMLHttpRequest();
  429. xhr.open("GET", url, true);
  430. xhr.send(null);
  431. }
  432. function initLoading() {
  433. loading = document.createElement('div');
  434. loadImg = document.createElement('img');
  435. loadText = document.createElement('p');
  436. loading.style.cssText = 'position: fixed; top: 50%; left: 50%; -webkit-transform: translate(-50%, -50%); display: inline-block; background-color: rgba(0, 0, 0, 0.7); border-radius: 3px; z-index: 10000; white-space: nowrap';
  437. loadImg.style.cssText = 'position: absolute; top: 50%; left: 5px; margin-top: -6px; width: 12px; height: 12px';
  438. loadText.style.cssText = 'margin-left: 22px; color: #fff; font-size: 1.2rem; height: 3rem; line-height: 3rem; padding-right: 5px';
  439. loadImg.src = NET_URL + '/res/image/load_circle.png';
  440. loading.appendChild(loadImg);
  441. loading.appendChild(loadText);
  442. }
  443. function getAccessToken() {
  444. // 2015-10-14, use AES, see auth/login api response;
  445. // 作好兼容性处理,对于从已登陆的旧版本升级到新版本的用户来说,直接通过接口获取accessToken会得到空值,此时应该继续使用旧的accessToken;
  446. if (andApiLevel >= 32) {
  447. var t = andHandler.getAccessToken();
  448. } else if (isIOS && iosApiLevel >= 20) {
  449. var t = CTK.AccessToken;
  450. }
  451. if (t && t.length > 5) {
  452. return t;
  453. }
  454. var session = {
  455. token: getToken(),
  456. etoken: ''
  457. }
  458. return base64.encode(JSON.stringify(session));
  459. }
  460. function submitPay(event) {
  461. event && event.preventDefault();
  462. event && event.stopPropagation();
  463. var ret = {
  464. "paymentType": payType,
  465. "authToken": getToken(),
  466. }
  467. cards.length > 0 && (ret['cards'] = cards);
  468. failSelect = null;
  469. if (typeof successSelect == 'function') {
  470. submit && submit.removeEventListener('click', submitPay, false);
  471. submit && (submit.style.backgroundColor = '#abcfe9');
  472. successSelect({
  473. tradeStr: base64.encode(JSON.stringify(ret))
  474. });
  475. }
  476. }
  477. function collectScenarioParams(id, name) {
  478. var state = {
  479. 'id' : id,
  480. 'name' : name,
  481. 'version' : 0,
  482. 'city' : getItemFromStorage('city'),
  483. 'geo_city' : getItemFromStorage('native_param_city'),
  484. 'source' : window.location.href,
  485. 'trigger_time': +new Date()
  486. };
  487. state = JSON.stringify(state);
  488. if (!isIOS && andApiLevel >= 3) {
  489. andHandler.appendScenarioNode(state);
  490. } else if (isIOS && iosApiLevel >= 1) {
  491. iosHandler.callHandler('appendScenarioNode', state, function(response) {
  492. console.log(response);
  493. });
  494. } else {
  495. console.log('no appendScenarioNode');
  496. }
  497. }
  498. function shareToWechat(param) {
  499. var hasParam = param.url.indexOf('?') === -1;
  500. url = hasParam ? param.url + '?client=wechat' : param.url + '&client=wechat';
  501. var data = JSON.stringify({
  502. 'type' : 'wechat',
  503. 'msg' : param.msg,
  504. 'url' : url,
  505. 'title' : param.title,
  506. });
  507. if (!isIOS && andApiLevel >= 9) {
  508. andHandler.shareMessage(data);
  509. } else if (isIOS && iosApiLevel >= 4) {
  510. iosHandler.callHandler('shareWXMessage', data, function(response) {
  511. console.log(response);
  512. });
  513. } else {
  514. console.log('no share wechat!');
  515. }
  516. }
  517. function shareToMoment(param) {
  518. var hasParam = param.url.indexOf('?') === -1;
  519. url = hasParam ? param.url + '?client=wechat' : param.url + '&client=wechat';
  520. var data = JSON.stringify({
  521. 'type' : 'wechat_moment',
  522. 'url' : url,
  523. 'title' : param.title,
  524. 'wechat_share_image_kind' : 2,
  525. 'imagePath' : 'webpages/share_icon',
  526. 'imageName' : '',
  527. });
  528. if (!isIOS && andApiLevel >= 15) {
  529. andHandler.shareWechatMoment(data);
  530. } else if (isIOS && iosApiLevel >= 4) {
  531. iosHandler.callHandler('shareWXMoment', data, function(response) {
  532. console.log(response);
  533. });
  534. } else {
  535. console.log('no share moment!');
  536. }
  537. }
  538. function getToken() {
  539. if (isIOS && iosHandler) {
  540. return CTK.AuthToken;
  541. } else {
  542. return andHandler ? andHandler.getAuthToken() : localStorage.getItem('auth_token');
  543. }
  544. }
  545. function pageBack() {
  546. if (!isIOS && andApiLevel >= 1) {
  547. andHandler.backPage();
  548. } else if (isIOS && iosApiLevel >= 3) {
  549. iosHandler.callHandler('backPage', '', function(response) {
  550. console.log(response);
  551. });
  552. } else {
  553. history.back();
  554. }
  555. }
  556. function getLoginNumber() {
  557. if (!isIOS && andApiLevel >= 10) {
  558. return andHandler.getLoginNumber();
  559. } else if (isIOS && iosHandler) {
  560. return CTK.LoginNumber;
  561. } else {
  562. return '';
  563. }
  564. }
  565. function getSecret() {
  566. if (!isIOS && andApiLevel >= 10) {
  567. return andHandler.getSecret();
  568. } else if (isIOS && iosHandler) {
  569. var secret = CTK.Secret;
  570. if (iosApiLevel <= 9) {
  571. secret = decodeIOSSecret(secret);
  572. }
  573. return secret;
  574. } else {
  575. return '';
  576. }
  577. }
  578. // 分服务商、分用户存储的一个key;
  579. // eg. ct_op_storage_addr_com.lyancoffee.coffee_18621213333 表示用户18621213333在连咖啡存储地址的key;
  580. function getStorageKey(tag) {
  581. var ph = getLoginNumber();
  582. if (!ph || ph.length == 0) {
  583. ph = getToken();
  584. }
  585. var key = 'ct_cache_' + ph + '_' + tag;
  586. return key;
  587. }
  588. function isWXAppInstalled() {
  589. if (!isIOS && andApiLevel >= 19) {
  590. return andHandler.isWXAppInstalled();
  591. } else if (isIOS && iosApiLevel >= 3) {
  592. return CTK.WXAppInstalled;
  593. } else {
  594. return false;
  595. }
  596. }
  597. function isWXPaySupported() {
  598. if (!isIOS && andApiLevel >= 19) {
  599. return andHandler.isWXPaySupported();
  600. } else if (isIOS && iosApiLevel >= 3) {
  601. return CTK.WXPaySupported;
  602. } else {
  603. return false;
  604. }
  605. }
  606. function alipayFunc(info) {
  607. if (!isIOS && andApiLevel >= 10) {
  608. return andHandler.alipay(info, 'CTKCallBackFuncs.payCallBack');
  609. } else if (isIOS && iosHandler) {
  610. var info2 = info.slice(0,-1);
  611. // self.alipayCallback = callback;
  612. var data = {
  613. callback: 'CTKCallBackFuncs.alipayHandler',
  614. info: info
  615. };
  616. info2.split('"&').forEach(function(value) {
  617. var item = value.split('="');
  618. data[item[0]] = item[1];
  619. });
  620. console.log('--------- ' + JSON.stringify(data));
  621. iosHandler.callHandler('alipay', JSON.stringify(data), function(response) {
  622. console.log(response)
  623. });
  624. }
  625. }
  626. function weipayFunc(info) {
  627. if (!isIOS && andApiLevel >= 19) {
  628. return andHandler.weixinpay(info, 'CTKCallBackFuncs.payCallBack');
  629. } else if (isIOS && iosApiLevel >= 3) {
  630. var data = JSON.parse(info);
  631. data.callback = 'CTKCallBackFuncs.weipayHandler';
  632. iosHandler.callHandler('weixinpay', JSON.stringify(data), function(response) {
  633. console.log(response)
  634. });
  635. }
  636. }
  637. function locate() {
  638. if (!isIOS && andApiLevel >= 1) {
  639. andHandler.locate();
  640. } else if (isIOS && iosApiLevel >= 1) {
  641. iosHandler.callHandler('locate', 'CTKCallBackFuncs.locateCallback', function(response) {
  642. console.log(response);
  643. });
  644. }
  645. }
  646. function getValue(key, getValue, data) {
  647. if (iosHandler) {
  648. if (CTK[key] && !getValue) {
  649. return CTK[key];
  650. }
  651. if (key == 'LocateCacheTime' && !getValue) {
  652. return CTK.LocateCacheTime || CTK.LocationCacheTime;
  653. }
  654. iosHandler.callHandler('get' + key, data, function(response) {
  655. console.log('respone: ' + response)
  656. switch (response) {
  657. case 'true':
  658. CTK[key] = true;
  659. break;
  660. case 'false':
  661. CTK[key] = false;
  662. break;
  663. default:
  664. CTK[key] = response;
  665. }
  666. });
  667. }
  668. }
  669. function getItemFromStorage(key, noValue) {
  670. if (!isIOS && andApiLevel >= 1) {
  671. return andHandler.storageGetItem(key);
  672. } else if (isIOS) {
  673. if (iosHandler && iosApiLevel <= 2) {
  674. switch (key) {
  675. case 'native_param_location':
  676. return getValue('Location', noValue);
  677. case 'native_param_city':
  678. return getValue('City', noValue);
  679. case 'native_param_addr':
  680. return getValue('Address', noValue);
  681. case 'native_param_locate_cache_time':
  682. return getValue('LocateCacheTime', noValue);
  683. case 'native_param_city_cache_time':
  684. return getValue('CityCacheTime', noValue);
  685. case 'native_param_addr_cache_time':
  686. return getValue('AddrCacheTime', noValue);
  687. default:
  688. return localStorage.getItem(key);
  689. }
  690. } else {
  691. return localStorage.getItem(key);
  692. }
  693. } else {
  694. return localStorage.getItem(key);
  695. }
  696. }
  697. function setItemToStorage(k, v) {
  698. if (!isIOS && andApiLevel > 0) {
  699. andHandler.storageSetItem(k, v);
  700. } else {
  701. localStorage.setItem(k, v);
  702. }
  703. }
  704. function getCurrentPosition(success, error, options) {
  705. ctk.getLocation({
  706. success: function(ret) {
  707. success({
  708. coords: {
  709. city: ret.city,
  710. address: ret.address,
  711. latitude: ret.latitude,
  712. longitude: ret.longitude
  713. },
  714. timestamp: getItemFromStorage('native_param_locate_cache_time')
  715. });
  716. }
  717. });
  718. }
  719. function Base64() {
  720. // private property
  721. _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  722. // public method for encoding
  723. this.encode = function (input) {
  724. var output = "";
  725. var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
  726. var i = 0;
  727. input = _utf8_encode(input);
  728. while (i < input.length) {
  729. chr1 = input.charCodeAt(i++);
  730. chr2 = input.charCodeAt(i++);
  731. chr3 = input.charCodeAt(i++);
  732. enc1 = chr1 >> 2;
  733. enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
  734. enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
  735. enc4 = chr3 & 63;
  736. if (isNaN(chr2)) {
  737. enc3 = enc4 = 64;
  738. } else if (isNaN(chr3)) {
  739. enc4 = 64;
  740. }
  741. output = output +
  742. _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
  743. _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
  744. }
  745. return output;
  746. }
  747. // public method for decoding
  748. this.decode = function (input) {
  749. var output = "";
  750. var chr1, chr2, chr3;
  751. var enc1, enc2, enc3, enc4;
  752. var i = 0;
  753. input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  754. while (i < input.length) {
  755. enc1 = _keyStr.indexOf(input.charAt(i++));
  756. enc2 = _keyStr.indexOf(input.charAt(i++));
  757. enc3 = _keyStr.indexOf(input.charAt(i++));
  758. enc4 = _keyStr.indexOf(input.charAt(i++));
  759. chr1 = (enc1 << 2) | (enc2 >> 4);
  760. chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
  761. chr3 = ((enc3 & 3) << 6) | enc4;
  762. output = output + String.fromCharCode(chr1);
  763. if (enc3 != 64) {
  764. output = output + String.fromCharCode(chr2);
  765. }
  766. if (enc4 != 64) {
  767. output = output + String.fromCharCode(chr3);
  768. }
  769. }
  770. output = _utf8_decode(output);
  771. return output;
  772. }
  773. // private method for UTF-8 encoding
  774. _utf8_encode = function (string) {
  775. string = string.replace(/\r\n/g,"\n");
  776. var utftext = "";
  777. for (var n = 0; n < string.length; n++) {
  778. var c = string.charCodeAt(n);
  779. if (c < 128) {
  780. utftext += String.fromCharCode(c);
  781. } else if((c > 127) && (c < 2048)) {
  782. utftext += String.fromCharCode((c >> 6) | 192);
  783. utftext += String.fromCharCode((c & 63) | 128);
  784. } else {
  785. utftext += String.fromCharCode((c >> 12) | 224);
  786. utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  787. utftext += String.fromCharCode((c & 63) | 128);
  788. }
  789. }
  790. return utftext;
  791. }
  792. // private method for UTF-8 decoding
  793. _utf8_decode = function (utftext) {
  794. var string = "";
  795. var i = 0;
  796. var c = c1 = c2 = 0;
  797. while ( i < utftext.length ) {
  798. c = utftext.charCodeAt(i);
  799. if (c < 128) {
  800. string += String.fromCharCode(c);
  801. i++;
  802. } else if((c > 191) && (c < 224)) {
  803. c2 = utftext.charCodeAt(i+1);
  804. string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
  805. i += 2;
  806. } else {
  807. c2 = utftext.charCodeAt(i+1);
  808. c3 = utftext.charCodeAt(i+2);
  809. string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  810. i += 3;
  811. }
  812. }
  813. return string;
  814. }
  815. }
  816. var ShareCallbacks = {
  817. shareCallback: function(result) {
  818. console.log('share' + result);
  819. },
  820. queryCallback: function(params, reference) {
  821. console.log('params is ' + params + ' reference ' + reference);
  822. }
  823. };
  824. var CTKCallBackFuncs = {
  825. loginCallBack: function(success) {
  826. if (success) {
  827. var phone = getLoginNumber();
  828. typeof successLogin == 'function' && successLogin({
  829. accessToken: getAccessToken()
  830. });
  831. } else {
  832. typeof failLogin == 'function' && failLogin({});
  833. }
  834. },
  835. iosLoginCallBack: function(ret) {
  836. var self = this;
  837. CTK.AuthToken = ret['token'];
  838. CTK.Secret = ret['secret'];
  839. CTK.LoginNumber = ret['loginnumber'];
  840. switch (ret['isLogged']) {
  841. case 'true':
  842. CTK.Logged = true;
  843. break;
  844. case 'false':
  845. CTK.Logged = false;
  846. break;
  847. }
  848. self.loginCallBack(CTK.Logged);
  849. },
  850. payCallBack: function(res) {
  851. console.log('-------------- ' + res);
  852. var resCode;
  853. var success = false;
  854. if (payType == ALIPAY_TYPE) {
  855. resCode = res.slice(14, 18) * 1;
  856. } else if (payType == WEIPAY_TYPE || payType == WEIPAY_OEM_TYPE) {
  857. resCode = res + '';
  858. }
  859. switch(resCode) {
  860. case 9000:
  861. case '0':
  862. resCode = 4102; //success
  863. success = true;
  864. break;
  865. case 8000:
  866. resCode = 4105; //dealing
  867. break;
  868. case 6001:
  869. case '-2':
  870. resCode = 4107; //cancel
  871. break;
  872. case 6002:
  873. case '-1':
  874. resCode = 4108; //network-error
  875. break;
  876. default:
  877. resCode = 4106; //failed
  878. break;
  879. }
  880. payResult(resCode);
  881. console.log('-------------- ' + resCode);
  882. webShare = false;
  883. if (success){
  884. var params = {scene_limit:'AFTER_TRADE', service:tradeService, transaction_id: localStorage.getItem('transaction_id')};
  885. console.log(params);
  886. console.log('---------------------- ' +iosApiLevel)
  887. if (isIOS && iosApiLevel >= 7) {
  888. var paramObj = {"params": JSON.stringify(params)};
  889. iosHandler.callHandler('tryShareWithParams', paramObj, null);
  890. }else if (!isIOS && andApiLevel >= 29) {
  891. andHandler.tryShare(JSON.stringify(params), 'ShareCallbacks.shareCallback');
  892. }else{
  893. console.log('no native share');
  894. webShare = true;
  895. }
  896. }
  897. setTimeout(function() {
  898. window.location.hash == '#cashier' && pageBack();
  899. setTimeout(function() {
  900. payCallBack(resCode);
  901. }, 300);
  902. if(webShare){
  903. loadFile('style', NET_URL + '/res/css/lib/ctk_ui.css');
  904. loadFile('script', NET_URL + '/res/js/lib/ctk_ui.js');
  905. caller.ctk = ctk;
  906. ctk.ready(function(){
  907. setTimeout(function() {
  908. getShare(caller, tradeService);
  909. }, 500);
  910. });
  911. }
  912. }, 100);
  913. },
  914. alipayHandler: function(ret) {
  915. console.log('------------- ret : ' + JSON.stringify(ret));
  916. var self = this;
  917. var result = 'resultStatus={' + ret['resultStatus'] + '};memo={' + ret['memo'] + '};result={' + ret['result'] + '}';
  918. self.payCallBack(result);
  919. },
  920. weipayHandler: function(ret) {
  921. var self = this;
  922. self.payCallBack(ret);
  923. },
  924. locateCallback: function(ret) {
  925. getItemFromStorage('native_param_location', true);
  926. getItemFromStorage('native_param_city', true);
  927. getItemFromStorage('native_param_addr', true);
  928. getItemFromStorage('native_param_locate_cache_time', true);
  929. getItemFromStorage('native_param_city_cache_time', true);
  930. getItemFromStorage('native_param_addr_cache_time', true);
  931. },
  932. // private use only
  933. setPayType: function(type) {
  934. payType = type;
  935. },
  936. getPayType: function() {
  937. return payType;
  938. }
  939. }
  940. var ctk = {
  941. ready: function(func) {
  942. if (isIOS && !iosHandler) {
  943. readyList.push(func);
  944. } else {
  945. typeof func == 'function' && func();
  946. }
  947. },
  948. logged: function(param) {
  949. var isLogged;
  950. if (!isIOS && andApiLevel >= 10) {
  951. isLogged = andHandler.isLogged();
  952. } else if (isIOS && iosHandler) {
  953. // isLogged = CTK.Logged;
  954. isLogged = !!CTK.LoginNumber;
  955. } else {
  956. isLogged = false;
  957. }
  958. if (isLogged) {
  959. param.yes({
  960. accessToken: getAccessToken()
  961. });
  962. } else {
  963. param.no({});
  964. }
  965. },
  966. login: function(param) {
  967. successLogin = param.success;
  968. failLogin = param.fail;
  969. if (!isIOS && andApiLevel >= 10) {
  970. andHandler.login('获取验证码', param.phone || '', 'CTKCallBackFuncs.loginCallBack');
  971. } else if (isIOS && iosHandler) {
  972. var data = {
  973. title: '获取验证码',
  974. phone: param.phone || '',
  975. callback: 'CTKCallBackFuncs.iosLoginCallBack'
  976. };
  977. iosHandler.callHandler('login', JSON.stringify(data), function(response) {
  978. console.log(response)
  979. });
  980. }
  981. },
  982. select: function(param) {
  983. successSelect = param.success;
  984. failSelect = param.fail;
  985. totalFee = (param.totalFee/100).toFixed(2);
  986. tradeService = param.tradeService;
  987. products = param.products || [];
  988. if (window.isIframeLoadCompleted){
  989. showPayPopup(param.inapp);
  990. }else{
  991. window.loadQueue = function(){
  992. showPayPopup(param.inapp);
  993. };
  994. }
  995. // queryCardInfo();
  996. collectScenarioParams(173, 'payment_popup_show');
  997. },
  998. selectCootek: function(param) {
  999. successSelect = param.success;
  1000. failSelect = param.fail;
  1001. totalFee = (param.totalFee/100).toFixed(2);
  1002. tradeService = param.tradeService;
  1003. products = param.products || [];
  1004. submitPay();
  1005. },
  1006. pay: function(param) {
  1007. console.log('---------- pay start');
  1008. console.log(JSON.stringify(param));
  1009. var payData = JSON.parse(base64.decode(param.payStr));
  1010. console.log('---------- pay data: ' + base64.decode(param.payStr));
  1011. payCallBack = param.finish;
  1012. if (payData.paymentType == ALIPAY_TYPE) {
  1013. console.log('---------- alipay');
  1014. alipayFunc(payData.paymentData);
  1015. } else if (payData.paymentType == WEIPAY_TYPE || payData.paymentType == WEIPAY_OEM_TYPE) {
  1016. console.log('---------- weipay');
  1017. weipayFunc(payData.paymentData);
  1018. }
  1019. localStorage.setItem('transaction_id', payData.transactionId);
  1020. },
  1021. show: function() {
  1022. !loading && initLoading();
  1023. var deg = 0;
  1024. function _rotate() {
  1025. if (deg < 360) {
  1026. deg += 15;
  1027. } else {
  1028. deg = 15;
  1029. }
  1030. loadImg.style.webkitTransform = 'rotate(' + deg + 'deg)';
  1031. }
  1032. loadText.innerHTML = payType == 'alipay' ? '正在跳转支付宝支付' : '正在跳转微信支付';
  1033. loadTimer = setInterval(_rotate, 20);
  1034. document.body.appendChild(loading);
  1035. },
  1036. dismiss: function() {
  1037. if (!loadTimer) {
  1038. return;
  1039. }
  1040. clearInterval(loadTimer);
  1041. loadTimer = null;
  1042. document.body.removeChild(loading);
  1043. },
  1044. checkJsApi: function(param) {
  1045. var result = {};
  1046. var hasCorrectApi = false;
  1047. param.jsApiList.forEach(function(node, i) {
  1048. if (node in apiList) {
  1049. if (node == 'pay') {
  1050. hasCorrectApi = true;
  1051. result.pay = {
  1052. alipay: (isIOS && iosApiLevel >= apiList.pay.alipay.ios) || (!isIOS && andApiLevel >= apiList.pay.alipay.and),
  1053. weipay: (isIOS && iosApiLevel >= apiList.pay.weipay.ios) || (!isIOS && andApiLevel >= apiList.pay.weipay.and)
  1054. }
  1055. } else {
  1056. result[node] = (isIOS && iosApiLevel >= apiList[node].ios) || (!isIOS && andApiLevel >= apiList[node].and);
  1057. }
  1058. } else {
  1059. console.log('txm: api name error! error name: ' + node);
  1060. }
  1061. });
  1062. if (typeof param.success == 'function') {
  1063. param.success({
  1064. errMsg: hasCorrectApi ? 'check success!' : 'no correct api name!',
  1065. result: result
  1066. });
  1067. } else {
  1068. console.log('success callback type error!');
  1069. }
  1070. },
  1071. getLocation: function(param) {
  1072. var lastCacheTime = getItemFromStorage('native_param_locate_cache_time');
  1073. locate();
  1074. var timer = setInterval(_checkCacheTime, 100);
  1075. var count = 0;
  1076. function _checkCacheTime() {
  1077. cacheTime = getItemFromStorage('native_param_locate_cache_time');
  1078. if (cacheTime != lastCacheTime) {
  1079. var loc = getItemFromStorage('native_param_location');
  1080. loc = loc ? JSON.parse(loc) : {};
  1081. clearInterval(timer);
  1082. typeof param.success == 'function' && param.success({
  1083. city: getItemFromStorage('native_param_city') || '',
  1084. address: getItemFromStorage('native_param_addr') || '',
  1085. latitude: loc[0] || '',
  1086. longitude: loc[1] || ''
  1087. });
  1088. }
  1089. count++;
  1090. if (count > 100) {
  1091. clearInterval(timer);
  1092. typeof param.success == 'function' && param.success({
  1093. city: '',
  1094. address: '',
  1095. latitude: '',
  1096. longitude: ''
  1097. });
  1098. }
  1099. }
  1100. },
  1101. config : function(appkey, serviceId, timestamp, charset, signType, host, jsApiList, sign) {
  1102. tradeService = serviceId;
  1103. for (var i = 0; i < jsApiList.length; ++i) {
  1104. var api = jsApiList[i];
  1105. if (api == 'getDefaultAddress') {
  1106. //初始化选择编辑地址页面op_address.html;
  1107. initAddress();
  1108. }
  1109. }
  1110. },
  1111. getDefaultAddress: function(param) {
  1112. function getAddrCb(d) {
  1113. if (typeof param.success == 'function') {
  1114. param.success(d);
  1115. if (window.location.hash == '#address') {
  1116. pageBack();
  1117. }
  1118. } else {
  1119. alert('未知错误,没有接收地址的函数');
  1120. }
  1121. }
  1122. if (param.showAddressPage) { // 弹出地址信息页;
  1123. window.location.hash = '#address';
  1124. CTAW.show(param.curContactId, getAddrCb);
  1125. } else { // 取默认地址的缓存,触宝为第三方作存储,注意做到区分用户,区分服务商存储;
  1126. var k = getStorageKey('default_addr');
  1127. var v = getItemFromStorage(k);
  1128. if (v && v.length > 5) {
  1129. var d = JSON.parse(v);
  1130. param.success(d);
  1131. } else {
  1132. param.success(null);
  1133. }
  1134. }
  1135. },
  1136. processAjaxError: function(req, http_status, res){
  1137. var that = this;
  1138. that.dismiss();
  1139. if (http_status == 'timeout') {
  1140. window.alert("服务器超时,请稍后再试!")
  1141. } else if(http_status == 'abort') {
  1142. window.alert('请求出现错误,请检查您的网络!');
  1143. window.cashierLink.contentWindow.postMessage({
  1144. status: 'active'
  1145. }, "*");
  1146. } else if (http_status == 500) {
  1147. window.alert('您访问太过频繁,请稍后再试!');
  1148. }
  1149. res = (res !== null) && JSON.parse(res);
  1150. switch(res.result_code) {
  1151. case 4002:
  1152. alert('本地时间错误,请求失败,请校准时间后再试!');
  1153. break;
  1154. }
  1155. }
  1156. };
  1157. document.readyState == 'complete' ? initPayPopup() : win.addEventListener('load', initPayPopup, false);
  1158. andApiLevel > 1 && (navigator.geolocation && (navigator.geolocation.getCurrentPosition = getCurrentPosition));
  1159. win.CTKCallBackFuncs = CTKCallBackFuncs;
  1160. win.ShareCallbacks = ShareCallbacks;
  1161. return win.ctk = ctk;
  1162. });