PageRenderTime 52ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/addons/payment/static/lib/jquery.payment/jquery.payment.js

https://gitlab.com/padjis/mapan
JavaScript | 500 lines | 462 code | 34 blank | 4 comment | 103 complexity | 2d568840ec879f39174553f0b6c6329d MD5 | raw file
  1. // Generated by CoffeeScript 1.4.0
  2. (function() {
  3. var $, cardFromNumber, cardFromType, cards, defaultFormat, formatBackCardNumber, formatBackExpiry, formatCardNumber, formatExpiry, formatForwardExpiry, formatForwardSlash, hasTextSelected, luhnCheck, reFormatCardNumber, restrictCVC, restrictCardNumber, restrictExpiry, restrictNumeric, setCardType,
  4. __slice = [].slice,
  5. __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
  6. _this = this;
  7. $ = jQuery;
  8. $.payment = {};
  9. $.payment.fn = {};
  10. $.fn.payment = function() {
  11. var args, method;
  12. method = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
  13. return $.payment.fn[method].apply(this, args);
  14. };
  15. defaultFormat = /(\d{1,4})/g;
  16. cards = [
  17. {
  18. type: 'maestro',
  19. pattern: /^(5018|5020|5038|6304|6759|676[1-3])/,
  20. format: defaultFormat,
  21. length: [12, 13, 14, 15, 16, 17, 18, 19],
  22. cvcLength: [3],
  23. luhn: true
  24. }, {
  25. type: 'dinersclub',
  26. pattern: /^(36|38|30[0-5])/,
  27. format: defaultFormat,
  28. length: [14],
  29. cvcLength: [3],
  30. luhn: true
  31. }, {
  32. type: 'laser',
  33. pattern: /^(6706|6771|6709)/,
  34. format: defaultFormat,
  35. length: [16, 17, 18, 19],
  36. cvcLength: [3],
  37. luhn: true
  38. }, {
  39. type: 'jcb',
  40. pattern: /^35/,
  41. format: defaultFormat,
  42. length: [16],
  43. cvcLength: [3],
  44. luhn: true
  45. }, {
  46. type: 'unionpay',
  47. pattern: /^62/,
  48. format: defaultFormat,
  49. length: [16, 17, 18, 19],
  50. cvcLength: [3],
  51. luhn: false
  52. }, {
  53. type: 'discover',
  54. pattern: /^(6011|65|64[4-9]|622)/,
  55. format: defaultFormat,
  56. length: [16],
  57. cvcLength: [3],
  58. luhn: true
  59. }, {
  60. type: 'mastercard',
  61. // ODOO FIX STARTS
  62. // pattern: /^5[1-5]/,
  63. pattern: /^(5[1-5]|2[2-7])/,
  64. // ODOO FIX ENDS
  65. format: defaultFormat,
  66. length: [16],
  67. cvcLength: [3],
  68. luhn: true
  69. }, {
  70. type: 'amex',
  71. pattern: /^3[47]/,
  72. format: /(\d{1,4})(\d{1,6})?(\d{1,5})?/,
  73. length: [15],
  74. cvcLength: [3, 4],
  75. luhn: true
  76. }, {
  77. type: 'visa',
  78. pattern: /^4/,
  79. format: defaultFormat,
  80. length: [13, 14, 15, 16],
  81. cvcLength: [3],
  82. luhn: true
  83. }
  84. ];
  85. cardFromNumber = function(num) {
  86. var card, _i, _len;
  87. num = (num + '').replace(/\D/g, '');
  88. for (_i = 0, _len = cards.length; _i < _len; _i++) {
  89. card = cards[_i];
  90. if (card.pattern.test(num)) {
  91. return card;
  92. }
  93. }
  94. };
  95. cardFromType = function(type) {
  96. var card, _i, _len;
  97. for (_i = 0, _len = cards.length; _i < _len; _i++) {
  98. card = cards[_i];
  99. if (card.type === type) {
  100. return card;
  101. }
  102. }
  103. };
  104. luhnCheck = function(num) {
  105. var digit, digits, odd, sum, _i, _len;
  106. odd = true;
  107. sum = 0;
  108. digits = (num + '').split('').reverse();
  109. for (_i = 0, _len = digits.length; _i < _len; _i++) {
  110. digit = digits[_i];
  111. digit = parseInt(digit, 10);
  112. if ((odd = !odd)) {
  113. digit *= 2;
  114. }
  115. if (digit > 9) {
  116. digit -= 9;
  117. }
  118. sum += digit;
  119. }
  120. return sum % 10 === 0;
  121. };
  122. hasTextSelected = function($target) {
  123. var _ref;
  124. if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== $target.prop('selectionEnd')) {
  125. return true;
  126. }
  127. if (typeof document !== "undefined" && document !== null ? (_ref = document.selection) != null ? typeof _ref.createRange === "function" ? _ref.createRange().text : void 0 : void 0 : void 0) {
  128. return true;
  129. }
  130. return false;
  131. };
  132. reFormatCardNumber = function(e) {
  133. var _this = this;
  134. return setTimeout(function() {
  135. var $target, value;
  136. $target = $(e.currentTarget);
  137. value = $target.val();
  138. value = $.payment.formatCardNumber(value);
  139. return $target.val(value);
  140. });
  141. };
  142. formatCardNumber = function(e) {
  143. var $target, card, digit, length, re, upperLength, value;
  144. digit = String.fromCharCode(e.which);
  145. if (!/^\d+$/.test(digit)) {
  146. return;
  147. }
  148. $target = $(e.currentTarget);
  149. value = $target.val();
  150. card = cardFromNumber(value + digit);
  151. length = (value.replace(/\D/g, '') + digit).length;
  152. upperLength = 16;
  153. if (card) {
  154. upperLength = card.length[card.length.length - 1];
  155. }
  156. if (length >= upperLength) {
  157. return;
  158. }
  159. if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) {
  160. return;
  161. }
  162. if (card && card.type === 'amex') {
  163. re = /^(\d{4}|\d{4}\s\d{6})$/;
  164. } else {
  165. re = /(?:^|\s)(\d{4})$/;
  166. }
  167. if (re.test(value)) {
  168. e.preventDefault();
  169. return $target.val(value + ' ' + digit);
  170. } else if (re.test(value + digit)) {
  171. e.preventDefault();
  172. return $target.val(value + digit + ' ');
  173. }
  174. };
  175. formatBackCardNumber = function(e) {
  176. var $target, value;
  177. $target = $(e.currentTarget);
  178. value = $target.val();
  179. if (e.meta) {
  180. return;
  181. }
  182. if (e.which !== 8) {
  183. return;
  184. }
  185. if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) {
  186. return;
  187. }
  188. if (/\d\s$/.test(value)) {
  189. e.preventDefault();
  190. return $target.val(value.replace(/\d\s$/, ''));
  191. } else if (/\s\d?$/.test(value)) {
  192. e.preventDefault();
  193. return $target.val(value.replace(/\s\d?$/, ''));
  194. }
  195. };
  196. formatExpiry = function(e) {
  197. var $target, digit, val;
  198. digit = String.fromCharCode(e.which);
  199. if (!/^\d+$/.test(digit)) {
  200. return;
  201. }
  202. $target = $(e.currentTarget);
  203. val = $target.val() + digit;
  204. if (/^\d$/.test(val) && (val !== '0' && val !== '1')) {
  205. e.preventDefault();
  206. return $target.val("0" + val + " / ");
  207. } else if (/^\d\d$/.test(val)) {
  208. e.preventDefault();
  209. return $target.val("" + val + " / ");
  210. }
  211. };
  212. formatForwardExpiry = function(e) {
  213. var $target, digit, val;
  214. digit = String.fromCharCode(e.which);
  215. if (!/^\d+$/.test(digit)) {
  216. return;
  217. }
  218. $target = $(e.currentTarget);
  219. val = $target.val();
  220. if (/^\d\d$/.test(val)) {
  221. return $target.val("" + val + " / ");
  222. }
  223. };
  224. formatForwardSlash = function(e) {
  225. var $target, slash, val;
  226. slash = String.fromCharCode(e.which);
  227. if (slash !== '/') {
  228. return;
  229. }
  230. $target = $(e.currentTarget);
  231. val = $target.val();
  232. if (/^\d$/.test(val) && val !== '0') {
  233. return $target.val("0" + val + " / ");
  234. }
  235. };
  236. formatBackExpiry = function(e) {
  237. var $target, value;
  238. if (e.meta) {
  239. return;
  240. }
  241. $target = $(e.currentTarget);
  242. value = $target.val();
  243. if (e.which !== 8) {
  244. return;
  245. }
  246. if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) {
  247. return;
  248. }
  249. if (/\d(\s|\/)+$/.test(value)) {
  250. e.preventDefault();
  251. return $target.val(value.replace(/\d(\s|\/)*$/, ''));
  252. } else if (/\s\/\s?\d?$/.test(value)) {
  253. e.preventDefault();
  254. return $target.val(value.replace(/\s\/\s?\d?$/, ''));
  255. }
  256. };
  257. restrictNumeric = function(e) {
  258. var input;
  259. if (e.metaKey || e.ctrlKey) {
  260. return true;
  261. }
  262. if (e.which === 32) {
  263. return false;
  264. }
  265. if (e.which === 0) {
  266. return true;
  267. }
  268. if (e.which < 33) {
  269. return true;
  270. }
  271. input = String.fromCharCode(e.which);
  272. return !!/[\d\s]/.test(input);
  273. };
  274. restrictCardNumber = function(e) {
  275. var $target, card, digit, value;
  276. $target = $(e.currentTarget);
  277. digit = String.fromCharCode(e.which);
  278. if (!/^\d+$/.test(digit)) {
  279. return;
  280. }
  281. if (hasTextSelected($target)) {
  282. return;
  283. }
  284. value = ($target.val() + digit).replace(/\D/g, '');
  285. card = cardFromNumber(value);
  286. if (card) {
  287. return value.length <= card.length[card.length.length - 1];
  288. } else {
  289. return value.length <= 16;
  290. }
  291. };
  292. restrictExpiry = function(e) {
  293. var $target, digit, value;
  294. $target = $(e.currentTarget);
  295. digit = String.fromCharCode(e.which);
  296. if (!/^\d+$/.test(digit)) {
  297. return;
  298. }
  299. if (hasTextSelected($target)) {
  300. return;
  301. }
  302. value = $target.val() + digit;
  303. value = value.replace(/\D/g, '');
  304. if (value.length > 6) {
  305. return false;
  306. }
  307. };
  308. restrictCVC = function(e) {
  309. var $target, digit, val;
  310. $target = $(e.currentTarget);
  311. digit = String.fromCharCode(e.which);
  312. if (!/^\d+$/.test(digit)) {
  313. return;
  314. }
  315. val = $target.val() + digit;
  316. return val.length <= 4;
  317. };
  318. setCardType = function(e) {
  319. var $target, allTypes, card, cardType, val;
  320. $target = $(e.currentTarget);
  321. val = $target.val();
  322. cardType = $.payment.cardType(val) || 'unknown';
  323. if (!$target.hasClass(cardType)) {
  324. allTypes = (function() {
  325. var _i, _len, _results;
  326. _results = [];
  327. for (_i = 0, _len = cards.length; _i < _len; _i++) {
  328. card = cards[_i];
  329. _results.push(card.type);
  330. }
  331. return _results;
  332. })();
  333. $target.removeClass('unknown');
  334. $target.removeClass(allTypes.join(' '));
  335. $target.addClass(cardType);
  336. $target.toggleClass('identified', cardType !== 'unknown');
  337. return $target.trigger('payment.cardType', cardType);
  338. }
  339. };
  340. $.payment.fn.formatCardCVC = function() {
  341. this.payment('restrictNumeric');
  342. this.on('keypress', restrictCVC);
  343. return this;
  344. };
  345. $.payment.fn.formatCardExpiry = function() {
  346. this.payment('restrictNumeric');
  347. this.on('keypress', restrictExpiry);
  348. this.on('keypress', formatExpiry);
  349. this.on('keypress', formatForwardSlash);
  350. this.on('keypress', formatForwardExpiry);
  351. this.on('keydown', formatBackExpiry);
  352. return this;
  353. };
  354. $.payment.fn.formatCardNumber = function() {
  355. this.payment('restrictNumeric');
  356. this.on('keypress', restrictCardNumber);
  357. this.on('keypress', formatCardNumber);
  358. this.on('keydown', formatBackCardNumber);
  359. this.on('keyup', setCardType);
  360. this.on('paste', reFormatCardNumber);
  361. return this;
  362. };
  363. $.payment.fn.restrictNumeric = function() {
  364. this.on('keypress', restrictNumeric);
  365. return this;
  366. };
  367. $.payment.fn.cardExpiryVal = function() {
  368. return $.payment.cardExpiryVal($(this).val());
  369. };
  370. $.payment.cardExpiryVal = function(value) {
  371. var month, prefix, year, _ref;
  372. value = value.replace(/\s/g, '');
  373. _ref = value.split('/', 2), month = _ref[0], year = _ref[1];
  374. if ((year != null ? year.length : void 0) === 2 && /^\d+$/.test(year)) {
  375. prefix = (new Date).getFullYear();
  376. prefix = prefix.toString().slice(0, 2);
  377. year = prefix + year;
  378. }
  379. month = parseInt(month, 10);
  380. year = parseInt(year, 10);
  381. return {
  382. month: month,
  383. year: year
  384. };
  385. };
  386. $.payment.validateCardNumber = function(num) {
  387. var card, _ref;
  388. num = (num + '').replace(/\s+|-/g, '');
  389. if (!/^\d+$/.test(num)) {
  390. return false;
  391. }
  392. card = cardFromNumber(num);
  393. if (!card) {
  394. return false;
  395. }
  396. return (_ref = num.length, __indexOf.call(card.length, _ref) >= 0) && (card.luhn === false || luhnCheck(num));
  397. };
  398. $.payment.validateCardExpiry = function(month, year) {
  399. var currentTime, expiry, prefix, _ref;
  400. if (typeof month === 'object' && 'month' in month) {
  401. _ref = month, month = _ref.month, year = _ref.year;
  402. }
  403. if (!(month && year)) {
  404. return false;
  405. }
  406. month = $.trim(month);
  407. year = $.trim(year);
  408. if (!/^\d+$/.test(month)) {
  409. return false;
  410. }
  411. if (!/^\d+$/.test(year)) {
  412. return false;
  413. }
  414. if (!(parseInt(month, 10) <= 12)) {
  415. return false;
  416. }
  417. if (year.length === 2) {
  418. prefix = (new Date).getFullYear();
  419. prefix = prefix.toString().slice(0, 2);
  420. year = prefix + year;
  421. }
  422. expiry = new Date(year, month);
  423. currentTime = new Date;
  424. expiry.setMonth(expiry.getMonth() - 1);
  425. expiry.setMonth(expiry.getMonth() + 1, 1);
  426. return expiry > currentTime;
  427. };
  428. $.payment.validateCardCVC = function(cvc, type) {
  429. var _ref, _ref1;
  430. cvc = $.trim(cvc);
  431. if (!/^\d+$/.test(cvc)) {
  432. return false;
  433. }
  434. if (type) {
  435. return _ref = cvc.length, __indexOf.call((_ref1 = cardFromType(type)) != null ? _ref1.cvcLength : void 0, _ref) >= 0;
  436. } else {
  437. return cvc.length >= 3 && cvc.length <= 4;
  438. }
  439. };
  440. $.payment.cardType = function(num) {
  441. var _ref;
  442. if (!num) {
  443. return null;
  444. }
  445. return ((_ref = cardFromNumber(num)) != null ? _ref.type : void 0) || null;
  446. };
  447. $.payment.formatCardNumber = function(num) {
  448. var card, groups, upperLength, _ref;
  449. card = cardFromNumber(num);
  450. if (!card) {
  451. return num;
  452. }
  453. upperLength = card.length[card.length.length - 1];
  454. num = num.replace(/\D/g, '');
  455. num = num.slice(0, +upperLength + 1 || 9e9);
  456. if (card.format.global) {
  457. return (_ref = num.match(card.format)) != null ? _ref.join(' ') : void 0;
  458. } else {
  459. groups = card.format.exec(num);
  460. if (groups != null) {
  461. groups.shift();
  462. }
  463. return groups != null ? groups.join(' ') : void 0;
  464. }
  465. };
  466. }).call(this);