@flittpayments/js-sdk 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2377 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Modules registry
5
+ * @type {Object<string,any>}
6
+ */
7
+ const modules = {};
8
+ /**
9
+ * @type {Object<string,any>}
10
+ */
11
+ const instance = {};
12
+ /**
13
+ * @param {string} name
14
+ * @param {Object} [params]
15
+ * @returns {{}}
16
+ */
17
+ const newModule = function (name, params) {
18
+ if (!modules[name]) {
19
+ throw Error(['module is undefined', name].join(' '));
20
+ }
21
+ return new modules[name](params || {});
22
+ };
23
+ const addModule = function (name, module) {
24
+ if (modules[name]) {
25
+ throw Error(['module already added', name].join(' '));
26
+ }
27
+ modules[name] = module;
28
+ };
29
+ function Component(name, params) {
30
+ if (instance[name]) return instance[name];
31
+ return instance[name] = newModule(name, params);
32
+ }
33
+ Component.get = function (name, params) {
34
+ return newModule(name, params);
35
+ };
36
+ Component.add = function (name, module) {
37
+ addModule(name, module);
38
+ return this;
39
+ };
40
+
41
+ const digitTest = /^\d+$/;
42
+ const keyBreaker = /([^\[\]]+)|(\[\])/g;
43
+ const paramTest = /([^?#]*)(#.*)?$/;
44
+ const r20 = /%20/g;
45
+ const rbracket = /\[\]$/;
46
+ const matchSymbol = /\s([a-zA-Z]+)/;
47
+ const prep = str => {
48
+ return decodeURIComponent(str.replace(/\+/g, ' '));
49
+ };
50
+ const flatten = array => {
51
+ let result = [];
52
+ forEach(array, item => {
53
+ result = result.concat(isArray(item) ? flatten(item) : item);
54
+ });
55
+ return result;
56
+ };
57
+ const recursiveParams = (prefix, obj, next) => {
58
+ if (isArray(obj)) {
59
+ forEach(obj, (item, prop) => {
60
+ if (rbracket.test(prefix)) {
61
+ next(prefix, item);
62
+ } else {
63
+ recursiveParams(prefix + '[' + (isPlainObject(obj) ? prop : '') + ']', item, next);
64
+ }
65
+ });
66
+ } else if (isPlainObject(obj)) {
67
+ forEach(obj, (item, prop) => {
68
+ recursiveParams(prefix + '[' + prop + ']', item, next);
69
+ });
70
+ } else {
71
+ next(prefix, obj);
72
+ }
73
+ };
74
+ const getType = o => {
75
+ return {}.toString.call(o).match(matchSymbol)[1].toLowerCase();
76
+ };
77
+ const isPlainObject = o => {
78
+ return !!o && typeof o === 'object' && o.constructor === Object;
79
+ };
80
+ const isFunction = o => {
81
+ return getType(o) === 'function';
82
+ };
83
+ const isArray = o => {
84
+ return getType(o) === 'array';
85
+ };
86
+ const isElement = o => {
87
+ return o && o.nodeType === 1;
88
+ };
89
+ const toArray = o => {
90
+ return [].slice.call(o);
91
+ };
92
+ const hasProp = (o, v) => {
93
+ return o && o.hasOwnProperty(v);
94
+ };
95
+ const forEach = (ob, cb, cx) => {
96
+ for (let p in ob) if (hasProp(ob, p)) cb.call(cx || null, ob[p], p);
97
+ };
98
+ const cleanObject = ob => {
99
+ for (let p in ob) {
100
+ if (hasProp(ob, p)) {
101
+ if (ob[p].length === 0) {
102
+ if (isArray(ob)) ob.splice(p, 1);
103
+ if (isPlainObject(ob)) delete ob[p];
104
+ } else if (isPlainObject(ob[p])) {
105
+ cleanObject(ob[p]);
106
+ }
107
+ }
108
+ }
109
+ return ob;
110
+ };
111
+ const extend = (obj, ...args) => {
112
+ forEach(args, function (o) {
113
+ if (o !== null) {
114
+ forEach(o, function (value, key) {
115
+ if (isPlainObject(value)) {
116
+ obj[key] = extend(obj[key] || {}, value);
117
+ } else {
118
+ obj[key] = value;
119
+ }
120
+ });
121
+ }
122
+ });
123
+ return obj;
124
+ };
125
+ const uuid = () => {
126
+ let a = 0,
127
+ b = '';
128
+ while (a++ < 36) {
129
+ if (a * 51 & 52) {
130
+ b += (a ^ 15 ? 8 ^ Math.random() * (a ^ 20 ? 16 : 4) : 4).toString(16);
131
+ } else {
132
+ b += '-';
133
+ }
134
+ }
135
+ return b;
136
+ };
137
+ const isObject = o => {
138
+ return getType(o) === 'object';
139
+ };
140
+ const isRegexp = o => {
141
+ return getType(o) === 'regexp';
142
+ };
143
+ const isArguments = o => {
144
+ return getType(o) === 'arguments';
145
+ };
146
+ const isError = o => {
147
+ return getType(o) === 'error';
148
+ };
149
+ const isDate = o => {
150
+ return getType(o) === 'date';
151
+ };
152
+ const isString = o => {
153
+ return getType(o) === 'string';
154
+ };
155
+ const isNumber = o => {
156
+ return getType(o) === 'number';
157
+ };
158
+ const map = (ob, cb, cx) => {
159
+ let p,
160
+ t,
161
+ r = [];
162
+ for (p in ob) if (hasProp(ob, p)) if ((t = cb.call(cx || null, ob[p], p)) !== undefined) r[p] = t;
163
+ return r;
164
+ };
165
+ const querySelectorAll = (o, p) => {
166
+ return toArray((p || document).querySelectorAll(o));
167
+ };
168
+ const querySelector = (o, p) => {
169
+ return (p || document).querySelector(o);
170
+ };
171
+ const deparam = params => {
172
+ const data = {};
173
+ if (params.charAt(0) === '?') params = params.slice(1);
174
+ if (params && paramTest.test(params)) {
175
+ forEach(params.split('&'), pair => {
176
+ let parts = pair.split('='),
177
+ key = prep(parts.shift()),
178
+ value = prep(parts.join('=')),
179
+ current = data;
180
+ if (key) {
181
+ parts = key.match(keyBreaker);
182
+ for (let j = 0, l = parts.length - 1; j < l; j++) {
183
+ if (!current[parts[j]]) {
184
+ current[parts[j]] = digitTest.test(parts[j + 1]) || parts[j + 1] === '[]' ? [] : {};
185
+ }
186
+ current = current[parts[j]];
187
+ }
188
+ const lastPart = parts.pop();
189
+ if (lastPart === '[]') {
190
+ current.push(value);
191
+ } else {
192
+ current[lastPart] = value;
193
+ }
194
+ }
195
+ });
196
+ }
197
+ return data;
198
+ };
199
+ const param = obj => {
200
+ const result = [];
201
+ forEach(obj, (item, prop) => {
202
+ recursiveParams(prop, item, (key, value) => {
203
+ value = value == null ? '' : value;
204
+ result.push([encodeURIComponent(key), encodeURIComponent(value)].join('='));
205
+ });
206
+ });
207
+ return result.join('&').replace(r20, '+');
208
+ };
209
+ const removeElement = el => {
210
+ el.parentNode.removeChild(el);
211
+ };
212
+ const createElement = tag => {
213
+ return document.createElement(tag);
214
+ };
215
+ const addClass = (...args) => {
216
+ const el = args.shift();
217
+ if (isElement(el) === false) return;
218
+ const classList = el.className.trim().split(/\s+/);
219
+ const tokens = flatten(args.map(item => item.trim().split(/\s+/)));
220
+ tokens.forEach(token => {
221
+ if (token && !~classList.indexOf(token)) {
222
+ classList.push(token);
223
+ }
224
+ });
225
+ el.className = classList.join(' ').trim();
226
+ };
227
+ const removeClass = (...args) => {
228
+ const el = args.shift();
229
+ if (isElement(el) === false) return;
230
+ const classList = el.className.trim().split(/\s+/);
231
+ const tokens = flatten(args.map(item => item.trim().split(/\s+/)));
232
+ tokens.forEach(token => {
233
+ if (token) {
234
+ const index = classList.indexOf(token);
235
+ if (!!~index) {
236
+ classList.splice(index, 1);
237
+ }
238
+ }
239
+ });
240
+ el.className = classList.join(' ').trim();
241
+ };
242
+ const removeAttr = (el, attrs) => {
243
+ if (isElement(el) === false) return false;
244
+ if (isPlainObject(attrs)) {
245
+ forEach(attrs, value => {
246
+ el.removeAttribute(value);
247
+ });
248
+ }
249
+ };
250
+ const addAttr = (el, attrs) => {
251
+ if (isElement(el) === false) return false;
252
+ if (isPlainObject(attrs)) {
253
+ forEach(attrs, (value, name) => {
254
+ el.setAttribute(name, value);
255
+ });
256
+ }
257
+ };
258
+ const getStyle = (el, prop, getComputedStyle) => {
259
+ getComputedStyle = window.getComputedStyle;
260
+ return (getComputedStyle ? getComputedStyle(el) : el['currentStyle'])[prop.replace(/-(\w)/gi, function (word, letter) {
261
+ return letter.toUpperCase();
262
+ })];
263
+ };
264
+ const getPath = path => {
265
+ const props = path.split('.');
266
+ const first = props.shift();
267
+ let value = null;
268
+ if (hasProp(window, first)) {
269
+ value = window[first];
270
+ forEach(props, name => {
271
+ value = hasProp(value, name) ? value[name] : null;
272
+ });
273
+ }
274
+ return value;
275
+ };
276
+ const stringFormat = (format, params, expr) => {
277
+ return (format || '').replace(expr || /{(.+?)}/g, (match, prop) => {
278
+ return params[prop] || match;
279
+ });
280
+ };
281
+ const cssUnit = (value, unit) => {
282
+ return String(value || 0).concat(unit || '').concat(' !important');
283
+ };
284
+ /**
285
+ * @function
286
+ * @type {function(*, *, *)}
287
+ */
288
+ const getPaymentRequest = (cx => {
289
+ let NativePaymentRequest;
290
+ if (hasProp(cx, 'PaymentRequest') && isFunction(cx.PaymentRequest)) {
291
+ NativePaymentRequest = cx.PaymentRequest;
292
+ }
293
+ return (methods, details, options) => {
294
+ let request = null;
295
+ details = details || {};
296
+ details.id = uuid();
297
+ options = options || {};
298
+ if (NativePaymentRequest) {
299
+ try {
300
+ request = new NativePaymentRequest(methods, details, options);
301
+ } catch (e) {
302
+ request = null;
303
+ }
304
+ }
305
+ return request;
306
+ };
307
+ })(window);
308
+ const jsonParse = (value, defaults) => {
309
+ try {
310
+ return JSON.parse(value);
311
+ } catch (e) {
312
+ return defaults;
313
+ }
314
+ };
315
+
316
+ var Utils = /*#__PURE__*/Object.freeze({
317
+ __proto__: null,
318
+ addAttr: addAttr,
319
+ addClass: addClass,
320
+ cleanObject: cleanObject,
321
+ createElement: createElement,
322
+ cssUnit: cssUnit,
323
+ deparam: deparam,
324
+ extend: extend,
325
+ forEach: forEach,
326
+ getPath: getPath,
327
+ getPaymentRequest: getPaymentRequest,
328
+ getStyle: getStyle,
329
+ getType: getType,
330
+ hasProp: hasProp,
331
+ isArguments: isArguments,
332
+ isArray: isArray,
333
+ isDate: isDate,
334
+ isElement: isElement,
335
+ isError: isError,
336
+ isFunction: isFunction,
337
+ isNumber: isNumber,
338
+ isObject: isObject,
339
+ isPlainObject: isPlainObject,
340
+ isRegexp: isRegexp,
341
+ isString: isString,
342
+ jsonParse: jsonParse,
343
+ map: map,
344
+ param: param,
345
+ querySelector: querySelector,
346
+ querySelectorAll: querySelectorAll,
347
+ removeAttr: removeAttr,
348
+ removeClass: removeClass,
349
+ removeElement: removeElement,
350
+ stringFormat: stringFormat,
351
+ toArray: toArray,
352
+ uuid: uuid
353
+ });
354
+
355
+ const ApiOrigin = 'https://pay.flitt.com';
356
+ const ApiEndpoint = {
357
+ gateway: '/latest/checkout-v2/index.html',
358
+ element: '/latest/checkout-v2/button/element.html'
359
+ };
360
+ const ProxyUrl = 'http://secure-redirect.cloudipsp.com/submit/';
361
+ const GooglePayApi = 'https://pay.google.com/gp/p/js/pay.js';
362
+ const GoogleBaseRequest = {
363
+ apiVersion: 2,
364
+ apiVersionMinor: 0,
365
+ allowedPaymentMethods: [{
366
+ type: 'CARD',
367
+ parameters: {
368
+ allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
369
+ allowedCardNetworks: ['AMEX', 'DISCOVER', 'INTERAC', 'JCB', 'MASTERCARD', 'VISA']
370
+ }
371
+ }]
372
+ };
373
+ const GooglePayLanguages = ['ar', 'bg', 'ca', 'zh', 'hr', 'cs', 'da', 'nl', 'en', 'et', 'fi', 'fr', 'de', 'el', 'id', 'it', 'ja', 'ko', 'ms', 'no', 'pl', 'pt', 'ru', 'sr', 'sk', 'sl', 'es', 'sv', 'th', 'tr', 'uk'];
374
+ const PaymentRequestDetails = {
375
+ total: {
376
+ label: 'Total',
377
+ amount: {
378
+ currency: 'USD',
379
+ value: '0.00'
380
+ }
381
+ }
382
+ };
383
+ const ApiFrameCss = {
384
+ width: '1px !important',
385
+ height: '1px !important',
386
+ left: '1px !important',
387
+ bottom: '1px !important',
388
+ position: 'fixed !important',
389
+ border: '0px !important'
390
+ };
391
+ const ButtonFrameCss = {
392
+ border: 'none !important',
393
+ margin: '0 !important',
394
+ padding: '0 !important',
395
+ display: 'block !important',
396
+ width: '1px !important',
397
+ 'min-width': '100% !important',
398
+ background: 'transparent !important',
399
+ position: 'relative !important',
400
+ opacity: '0 !important',
401
+ overflow: 'hidden !important',
402
+ height: '100% !important',
403
+ outline: 'none !important',
404
+ 'z-index': '1 !important'
405
+ };
406
+ const ButtonFrameAttrs = {
407
+ tabindex: '-1',
408
+ scrolling: 'no',
409
+ frameborder: 0,
410
+ allowtransparency: true,
411
+ allowpaymentrequest: true
412
+ };
413
+ const ButtonCoverCss = {
414
+ 'z-index': '2 !important',
415
+ position: 'absolute !important',
416
+ border: 'none !important',
417
+ background: 'transparent !important',
418
+ left: '0 !important',
419
+ top: '0 !important',
420
+ cursor: 'pointer !important',
421
+ outline: 'none !important',
422
+ width: '100% !important',
423
+ height: '100% !important'
424
+ };
425
+ const ButtonCoverAttrs = {
426
+ role: 'button',
427
+ 'aria-pressed': 'false'
428
+ };
429
+ const ButtonContainerCss = {
430
+ border: '0 !important',
431
+ margin: '0 !important',
432
+ padding: '0 !important',
433
+ display: 'block !important',
434
+ background: 'transparent !important',
435
+ 'user-select': 'none !important',
436
+ overflow: 'hidden !important',
437
+ position: 'relative !important',
438
+ opacity: '1 !important',
439
+ height: '0 !important',
440
+ width: '100% !important',
441
+ outline: 'none !important'
442
+ };
443
+ const ButtonDefaultColor = 'dark';
444
+ const ButtonColorMap = {
445
+ dark: 'dark',
446
+ light: 'light',
447
+ black: 'dark',
448
+ white: 'light'
449
+ };
450
+ const ButtonLabelMap = {
451
+ ar: '',
452
+ bg: '',
453
+ ca: '',
454
+ zh: '',
455
+ hr: '',
456
+ cs: '',
457
+ da: '',
458
+ nl: '',
459
+ en: 'Pay with',
460
+ et: '',
461
+ es: 'Comprar con',
462
+ el: '',
463
+ fi: '',
464
+ fr: 'Acheter avec',
465
+ de: 'Zahlen über',
466
+ id: '',
467
+ it: 'Acquista con',
468
+ ja: '',
469
+ ko: '',
470
+ ms: '',
471
+ no: '',
472
+ pl: 'Zapłać przez',
473
+ pt: '',
474
+ ru: 'Оплатить через',
475
+ sr: '',
476
+ sk: 'Zaplatiť cez',
477
+ sl: '',
478
+ sv: '',
479
+ th: '',
480
+ tr: '',
481
+ uk: 'Оплатити через'
482
+ };
483
+
484
+ var Config = /*#__PURE__*/Object.freeze({
485
+ __proto__: null,
486
+ ApiEndpoint: ApiEndpoint,
487
+ ApiFrameCss: ApiFrameCss,
488
+ ApiOrigin: ApiOrigin,
489
+ ButtonColorMap: ButtonColorMap,
490
+ ButtonContainerCss: ButtonContainerCss,
491
+ ButtonCoverAttrs: ButtonCoverAttrs,
492
+ ButtonCoverCss: ButtonCoverCss,
493
+ ButtonDefaultColor: ButtonDefaultColor,
494
+ ButtonFrameAttrs: ButtonFrameAttrs,
495
+ ButtonFrameCss: ButtonFrameCss,
496
+ ButtonLabelMap: ButtonLabelMap,
497
+ GoogleBaseRequest: GoogleBaseRequest,
498
+ GooglePayApi: GooglePayApi,
499
+ GooglePayLanguages: GooglePayLanguages,
500
+ PaymentRequestDetails: PaymentRequestDetails,
501
+ ProxyUrl: ProxyUrl
502
+ });
503
+
504
+ const PENDING = 0;
505
+ const RESOLVED = 1;
506
+ const REJECTED = 2;
507
+ const PROGRESS = 3;
508
+ function Deferred() {
509
+ const resolveCallbacks = [];
510
+ const rejectCallbacks = [];
511
+ const notifyCallbacks = [];
512
+ let status = PENDING;
513
+ let resultContext = undefined;
514
+ let resultArgs = null;
515
+ let chainArgs = null;
516
+ const executeCallback = (context, args, callbacks) => {
517
+ const list = [].concat(callbacks);
518
+ const save = (chainArgs, isArgs) => {
519
+ if (isArgs) {
520
+ resultArgs = Array.from(chainArgs);
521
+ } else {
522
+ resultArgs = [chainArgs];
523
+ }
524
+ };
525
+ const execute = () => {
526
+ const item = list.shift();
527
+ if (item) {
528
+ chainArgs = item.apply(resultContext, resultArgs);
529
+ if (chainArgs !== undefined) {
530
+ if (chainArgs && chainArgs.then) {
531
+ chainArgs.then((...chainArgs) => {
532
+ save(chainArgs, true);
533
+ execute();
534
+ });
535
+ } else {
536
+ save(chainArgs);
537
+ execute();
538
+ }
539
+ } else {
540
+ execute();
541
+ }
542
+ }
543
+ };
544
+ resultContext = context;
545
+ resultArgs = args;
546
+ execute();
547
+ };
548
+ /**
549
+ * @lends Deferred.prototype
550
+ */
551
+ const promise = {
552
+ done(callback) {
553
+ if (isFunction(callback)) {
554
+ if (status === REJECTED) {
555
+ callback.apply(resultContext, resultArgs);
556
+ }
557
+ resolveCallbacks.push(callback);
558
+ }
559
+ return this;
560
+ },
561
+ fail(callback) {
562
+ if (isFunction(callback)) {
563
+ if (status === REJECTED) {
564
+ callback.apply(resultContext, resultArgs);
565
+ }
566
+ rejectCallbacks.push(callback);
567
+ }
568
+ return this;
569
+ },
570
+ progress(callback) {
571
+ if (isFunction(callback)) {
572
+ if (status === PROGRESS) {
573
+ callback.apply(resultContext, resultArgs);
574
+ }
575
+ notifyCallbacks.push(callback);
576
+ }
577
+ return this;
578
+ },
579
+ always(callback) {
580
+ return this.done(callback).fail(callback);
581
+ },
582
+ then(resolve, reject, progress) {
583
+ if (isFunction(resolve)) {
584
+ this.done(resolve);
585
+ }
586
+ if (isFunction(reject)) {
587
+ this.fail(reject);
588
+ }
589
+ if (isFunction(progress)) {
590
+ this.progress(reject);
591
+ }
592
+ return this;
593
+ },
594
+ promise(object) {
595
+ if (object === null) {
596
+ return promise;
597
+ }
598
+ forEach(promise, (item, prop) => {
599
+ object[prop] = item;
600
+ });
601
+ return object;
602
+ },
603
+ state: function () {
604
+ return status;
605
+ },
606
+ isPending() {
607
+ return status === PENDING;
608
+ },
609
+ isRejected() {
610
+ return status === REJECTED;
611
+ },
612
+ isResolved() {
613
+ return status === RESOLVED;
614
+ },
615
+ resetState() {
616
+ status = PENDING;
617
+ return this;
618
+ },
619
+ resolveWith(context, args) {
620
+ if (status === PENDING) {
621
+ status = RESOLVED;
622
+ executeCallback(context, args, resolveCallbacks);
623
+ }
624
+ return this;
625
+ },
626
+ rejectWith(context, args) {
627
+ if (status === PENDING) {
628
+ status = REJECTED;
629
+ executeCallback(context, args, rejectCallbacks);
630
+ }
631
+ return this;
632
+ },
633
+ notifyWith(context, args) {
634
+ if (status === PENDING) {
635
+ status = PROGRESS;
636
+ executeCallback(context, args, notifyCallbacks);
637
+ status = PENDING;
638
+ }
639
+ return this;
640
+ },
641
+ resolve() {
642
+ return this.resolveWith(this, Array.from(arguments));
643
+ },
644
+ reject() {
645
+ return this.rejectWith(this, Array.from(arguments));
646
+ },
647
+ notify() {
648
+ return this.notifyWith(this, Array.from(arguments));
649
+ }
650
+ };
651
+ return promise;
652
+ }
653
+
654
+ let init = false;
655
+ const fnTest = /xyz/.test(function () {
656
+ return 'xyz';
657
+ }.toString()) ? /\b_super\b/ : /.*/;
658
+ function ClassObject() {}
659
+ ClassObject.prototype._super = function () {};
660
+ ClassObject.prototype.instance = function (params) {
661
+ return new this.constructor(params);
662
+ };
663
+ ClassObject.prototype.proxy = function (fn) {
664
+ fn = typeof fn == 'string' ? this[fn] : fn;
665
+ return function (cx, cb) {
666
+ return function () {
667
+ return cb.apply(cx, [this].concat(Array.prototype.slice.call(arguments)));
668
+ };
669
+ }(this, fn);
670
+ };
671
+ function superMethod(parent, name, method) {
672
+ return function () {
673
+ let temp = this._super,
674
+ result;
675
+ this._super = parent[name];
676
+ result = method.apply(this, arguments);
677
+ this._super = temp;
678
+ return result;
679
+ };
680
+ }
681
+ function assign(target, instance) {
682
+ let prop,
683
+ proto,
684
+ parent = target.prototype;
685
+ init = true;
686
+ proto = new target();
687
+ init = false;
688
+ for (prop in instance) {
689
+ if (instance.hasOwnProperty(prop)) {
690
+ if (typeof parent[prop] == 'function' && typeof instance[prop] == 'function' && fnTest.test(instance[prop])) {
691
+ proto[prop] = superMethod(parent, prop, instance[prop]);
692
+ } else {
693
+ proto[prop] = instance[prop];
694
+ }
695
+ }
696
+ }
697
+ return proto;
698
+ }
699
+ ClassObject.extend = function extend(instance) {
700
+ function Class() {
701
+ if (!init && this) this['init'].apply(this, arguments);
702
+ }
703
+ Class.prototype = assign(this, instance);
704
+ Class.prototype.constructor = Class;
705
+ Class.extend = extend;
706
+ return Class;
707
+ };
708
+
709
+ const Event = ClassObject.extend({
710
+ init() {
711
+ this.events = {};
712
+ this.empty = [];
713
+ },
714
+ on(type, callback) {
715
+ (this.events[type] = this.events[type] || []).push(callback);
716
+ return this;
717
+ },
718
+ off(type, callback) {
719
+ type || (this.events = {});
720
+ let list = this.events[type] || this.empty,
721
+ i = list.length = callback ? list.length : 0;
722
+ while (i--) callback === list[i] && list.splice(i, 1);
723
+ return this;
724
+ },
725
+ trigger(type) {
726
+ let e = this.events[type] || this.empty,
727
+ list = e.length > 0 ? e.slice(0, e.length) : e,
728
+ i = 0,
729
+ j;
730
+ while (j = list[i++]) j.apply(j, this.empty.slice.call(arguments, 1));
731
+ return this;
732
+ }
733
+ });
734
+
735
+ const Module = ClassObject.extend({
736
+ utils: Utils,
737
+ getListener() {
738
+ if (!this._listener_) this._listener_ = new Event();
739
+ return this._listener_;
740
+ },
741
+ destroy() {
742
+ this.off();
743
+ },
744
+ on(type, callback) {
745
+ this.getListener().on(type, callback);
746
+ return this;
747
+ },
748
+ off(type, callback) {
749
+ this.getListener().off(type, callback);
750
+ return this;
751
+ },
752
+ proxy(fn) {
753
+ if (!this._proxy_cache_) this._proxy_cache_ = {};
754
+ if (this.utils.isString(fn)) {
755
+ if (!this._proxy_cache_[fn]) {
756
+ this._proxy_cache_[fn] = this._super(fn);
757
+ }
758
+ return this._proxy_cache_[fn];
759
+ }
760
+ return this._super(fn);
761
+ },
762
+ trigger() {
763
+ this.getListener().trigger.apply(this.getListener(), arguments);
764
+ return this;
765
+ },
766
+ each(ob, cb) {
767
+ this.utils.forEach(ob, this.proxy(cb));
768
+ },
769
+ addAttr(el, ob) {
770
+ if (!this.utils.isElement(el)) return false;
771
+ this.utils.forEach(ob, function (v, k) {
772
+ el.setAttribute(k, v);
773
+ });
774
+ },
775
+ addCss(el, ob) {
776
+ if (!this.utils.isElement(el)) return false;
777
+ this.utils.forEach(ob, function (v, k) {
778
+ this.addCssProperty(el, k, v);
779
+ }, this);
780
+ },
781
+ addCssProperty(el, style, value) {
782
+ let result = el.style.cssText.match(new RegExp('(?:[;\\s]|^)(' + style.replace('-', '\\-') + '\\s*:(.*?)(;|$))')),
783
+ idx;
784
+ if (result) {
785
+ idx = result.index + result[0].indexOf(result[1]);
786
+ el.style.cssText = el.style.cssText.substring(0, idx) + style + ': ' + value + ';' + el.style.cssText.substring(idx + result[1].length);
787
+ } else {
788
+ el.style.cssText += ' ' + style + ': ' + value + ';';
789
+ }
790
+ },
791
+ addEvent(el, ev, cb) {
792
+ if (!el || !ev || !cb) return false;
793
+ cb = this.proxy(cb);
794
+ if (el.addEventListener) el.addEventListener(ev, cb);else if (el['attachEvent']) el['attachEvent']('on' + ev, cb);
795
+ },
796
+ removeEvent(el, ev, cb) {
797
+ if (!el || !ev || !cb) return false;
798
+ cb = this.proxy(cb);
799
+ if (el.removeEventListener) el.removeEventListener(ev, cb, false);else if (el['detachEvent']) el['detachEvent']('on' + ev, cb);
800
+ },
801
+ prepareForm(url, data, target, method) {
802
+ const form = this.utils.createElement('form');
803
+ this.addAttr(form, {
804
+ action: url,
805
+ target: target || '_self',
806
+ method: method || 'POST'
807
+ });
808
+ this.addCss(form, {
809
+ display: 'none'
810
+ });
811
+ this.utils.forEach(data, function (v, k, el) {
812
+ el = this.utils.createElement('input');
813
+ el.type = 'hidden';
814
+ el.name = k;
815
+ el.value = v;
816
+ form.appendChild(el);
817
+ }, this);
818
+ return form;
819
+ }
820
+ });
821
+
822
+ const Connector = Module.extend({
823
+ ns: 'crossDomain',
824
+ origin: '*',
825
+ uniqueId: 1,
826
+ signature: null,
827
+ init(params) {
828
+ this.setTarget(params.target);
829
+ this.setOrigin(params.origin);
830
+ this.create();
831
+ },
832
+ create() {
833
+ this.addEvent(window, 'message', 'router');
834
+ },
835
+ setOrigin(origin) {
836
+ this.origin = origin || '*';
837
+ },
838
+ setTarget(target) {
839
+ this.target = target;
840
+ return this;
841
+ },
842
+ getUID() {
843
+ return ++this.uniqueId;
844
+ },
845
+ destroy() {
846
+ this.removeEvent(window, 'message', 'router');
847
+ this._super();
848
+ },
849
+ router(window, ev, response) {
850
+ if (this.target !== ev.source) return false;
851
+ try {
852
+ response = JSON.parse(ev.data);
853
+ } catch (e) {}
854
+ if (response && response.action && response.data) {
855
+ this.trigger(response.action, response.data);
856
+ }
857
+ },
858
+ send(action, data, request, options) {
859
+ if (!this.target) {
860
+ return;
861
+ }
862
+ request = JSON.stringify({
863
+ action: action,
864
+ data: data
865
+ });
866
+ options = {
867
+ targetOrigin: this.origin,
868
+ delegate: 'payment'
869
+ };
870
+ try {
871
+ this.target.postMessage(request, options);
872
+ } catch (e) {
873
+ this.target.postMessage(request, this.origin, []);
874
+ }
875
+ }
876
+ });
877
+
878
+ var styles = data => `
879
+ <style>
880
+ .flitt-modal {
881
+ box-sizing: border-box;
882
+ margin: 100px auto;
883
+ max-width: 680px;
884
+ background-color: #fff;
885
+ border-radius: 5px;
886
+ box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
887
+ overflow: hidden;
888
+ }
889
+
890
+ @media (max-width: 850px) {
891
+ .flitt-modal {
892
+ margin: 50px auto;
893
+ }
894
+ }
895
+
896
+ @media (max-width: 695px) {
897
+ .flitt-modal {
898
+ max-width: 100%;
899
+ margin: 5px;
900
+ }
901
+ }
902
+
903
+ .flitt-modal-wrapper {
904
+ box-sizing: border-box;
905
+ overflow: auto;
906
+ position: fixed;
907
+ z-index: 99999;
908
+ left: 0;
909
+ bottom: 0;
910
+ top: 0;
911
+ right: 0;
912
+ background-color: rgba(0, 0, 0, 0.2);
913
+ }
914
+
915
+ .flitt-modal-header {
916
+ box-sizing: border-box;
917
+ background-color: #fafafa;
918
+ height: 50px;
919
+ box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
920
+ border-top-left-radius: 5px;
921
+ border-top-right-radius: 5px;
922
+ }
923
+
924
+ .flitt-modal-close {
925
+ box-sizing: border-box;
926
+ float: right;
927
+ overflow: hidden;
928
+ height: 50px;
929
+ text-decoration: none;
930
+ border-top-right-radius: 5px;
931
+ color: #949494;
932
+ }
933
+
934
+ .flitt-modal-close:hover, .flitt-modal-close:focus, .flitt-modal-close:active {
935
+ text-decoration: none;
936
+ color: #646464;
937
+ }
938
+
939
+ .flitt-modal-close:before {
940
+ content: "×";
941
+ font-size: 50px;
942
+ line-height: 50px;
943
+ padding: 0 10px;
944
+ }
945
+
946
+ .flitt-modal-title {
947
+ box-sizing: border-box;
948
+ border-top-left-radius: 5px;
949
+ line-height: 20px;
950
+ height: 50px;
951
+ padding: 5px 15px;
952
+ font-size: 12px;
953
+ display: table-cell;
954
+ vertical-align: middle;
955
+ }
956
+ .flitt-modal-content {
957
+ box-sizing: border-box;
958
+ border-bottom-left-radius: 5px;
959
+ min-height: 650px;
960
+ }
961
+ .flitt-modal-iframe {
962
+ overflow-x: hidden;
963
+ border: 0;
964
+ display: block;
965
+ width: 100%;
966
+ height: 750px;
967
+ }
968
+ </style>
969
+ `;
970
+
971
+ var acs = data => `
972
+ ${styles()}
973
+ <div class="flitt-modal-wrapper">
974
+ <div class="flitt-modal">
975
+ <div class="flitt-modal-header">
976
+ <a href="javascript:void(0)" class="flitt-modal-close"></a>
977
+ <div class="flitt-modal-title">
978
+ ${data.messages.modalHeader}
979
+ <a href='javascript:void(0)'>${data.messages.modalLinkLabel}</a>
980
+ </div>
981
+ </div>
982
+ <div class="flitt-modal-content">
983
+ <iframe src="about:blank" class="flitt-modal-iframe" frameborder="0" allowtransparency="true"></iframe>
984
+ </div>
985
+ </div>
986
+ </div>
987
+ `;
988
+
989
+ var Views = /*#__PURE__*/Object.freeze({
990
+ __proto__: null,
991
+ acs: acs
992
+ });
993
+
994
+ function empty(name) {
995
+ return function (data) {
996
+ return ['template', name, 'not found'].join(' ');
997
+ };
998
+ }
999
+ const Template = ClassObject.extend({
1000
+ init(name) {
1001
+ this.view = Views[name] || empty(name);
1002
+ },
1003
+ render(data) {
1004
+ return this.view(data);
1005
+ }
1006
+ });
1007
+
1008
+ const Modal = Module.extend({
1009
+ init(data) {
1010
+ this.checkout = data.checkout;
1011
+ this.model = data.model || {};
1012
+ this.messages = data.checkout.params.messages || {};
1013
+ this.template = new Template('acs');
1014
+ this.body = this.utils.querySelector('body');
1015
+ this.initModal();
1016
+ this.initConnector();
1017
+ },
1018
+ initModal() {
1019
+ this.name = ['modal-iframe', this.getRandomNumber()].join('-');
1020
+ this.modal = this.utils.createElement('div');
1021
+ this.modal.innerHTML = this.template.render({
1022
+ model: this.model,
1023
+ messages: this.messages
1024
+ });
1025
+ this.iframe = this.find('.flitt-modal-iframe');
1026
+ this.addAttr(this.iframe, {
1027
+ name: this.name,
1028
+ id: this.name
1029
+ });
1030
+ if (this.model['send_data']) {
1031
+ this.form = this.prepareForm(this.model['url'], this.model['send_data'], this.name);
1032
+ this.modal.appendChild(this.form);
1033
+ } else {
1034
+ this.iframe.src = this.model['url'];
1035
+ }
1036
+ this.addEvent(this.find('.flitt-modal-close'), 'click', 'closeModal');
1037
+ this.addEvent(this.find('.flitt-modal-title a'), 'click', 'submitForm');
1038
+ this.initScrollbar();
1039
+ this.body.appendChild(this.modal);
1040
+ if (this.form) {
1041
+ this.form.submit();
1042
+ }
1043
+ },
1044
+ measureScrollbar() {
1045
+ const scrollDiv = document.createElement('div');
1046
+ scrollDiv.className = 'modal-scrollbar-measure';
1047
+ this.body.appendChild(scrollDiv);
1048
+ this.utils.removeElement(scrollDiv);
1049
+ return scrollDiv.offsetWidth - scrollDiv.clientWidth;
1050
+ },
1051
+ checkScrollbar() {
1052
+ let documentElementRect;
1053
+ let fullWindowWidth = window.innerWidth;
1054
+ if (!fullWindowWidth) {
1055
+ documentElementRect = document.documentElement.getBoundingClientRect();
1056
+ fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
1057
+ }
1058
+ this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth;
1059
+ this.scrollbarWidth = this.measureScrollbar();
1060
+ },
1061
+ initScrollbar() {
1062
+ this.checkScrollbar();
1063
+ this.bodyPad = parseInt(this.utils.getStyle(this.body, 'padding-right') || 0, 10);
1064
+ this.originalBodyPad = document.body.style.paddingRight || '';
1065
+ this.originalOverflow = document.body.style.overflow || '';
1066
+ if (this.bodyIsOverflowing) {
1067
+ this.addCss(this.body, {
1068
+ paddingRight: [this.bodyPad + this.scrollbarWidth, 'px'].join(''),
1069
+ overflow: 'hidden'
1070
+ });
1071
+ }
1072
+ },
1073
+ resetScrollbar() {
1074
+ this.addCss(this.body, {
1075
+ paddingRight: this.originalBodyPad ? [this.originalBodyPad, 'px'].join('') : '',
1076
+ overflow: this.originalOverflow
1077
+ });
1078
+ },
1079
+ getRandomNumber() {
1080
+ return Math.round(Math.random() * 1000000000);
1081
+ },
1082
+ find(selector) {
1083
+ return this.utils.querySelector(selector, this.modal);
1084
+ },
1085
+ closeModal(el, ev) {
1086
+ ev.preventDefault();
1087
+ this.trigger('close', this.data);
1088
+ this.removeModal();
1089
+ },
1090
+ submitForm(el, ev) {
1091
+ ev.preventDefault();
1092
+ this.trigger('submit', this.data);
1093
+ this.addAttr(this.form, {
1094
+ target: '_blank'
1095
+ });
1096
+ this.form.submit();
1097
+ },
1098
+ removeModal() {
1099
+ this.destroy();
1100
+ },
1101
+ destroy() {
1102
+ this.utils.removeElement(this.modal);
1103
+ this.resetScrollbar();
1104
+ this.connector.destroy();
1105
+ this._super();
1106
+ },
1107
+ initConnector() {
1108
+ this.connector = new Connector({
1109
+ target: this.iframe.contentWindow
1110
+ });
1111
+ this.connector.on('response', this.proxy('onResponse'));
1112
+ },
1113
+ onResponse(ev, data) {
1114
+ this.sendResponse(data);
1115
+ this.removeModal();
1116
+ },
1117
+ sendResponse(data) {
1118
+ this.checkout.connector.send('request', {
1119
+ uid: data.uid,
1120
+ action: 'api.checkout.proxy',
1121
+ method: 'send',
1122
+ params: data
1123
+ });
1124
+ }
1125
+ });
1126
+
1127
+ const Model = Module.extend({
1128
+ init(data) {
1129
+ this.data = data || {};
1130
+ this.create();
1131
+ },
1132
+ create() {},
1133
+ eachProps(args) {
1134
+ const name = args[1] ? args[0] : null;
1135
+ const callback = args[1] ? args[1] : args[0];
1136
+ const list = name ? this.alt(name, []) : this.data;
1137
+ return {
1138
+ list: list,
1139
+ callback: callback
1140
+ };
1141
+ },
1142
+ each() {
1143
+ const props = this.eachProps(arguments);
1144
+ for (let prop in props.list) {
1145
+ if (props.list.hasOwnProperty(prop)) {
1146
+ props.callback(this.instance(props.list[prop]), props.list[prop], prop);
1147
+ }
1148
+ }
1149
+ },
1150
+ filter() {
1151
+ const props = this.eachProps(arguments);
1152
+ for (let prop in props.list) {
1153
+ if (props.list.hasOwnProperty(prop)) {
1154
+ const item = this.instance(props.list[prop]);
1155
+ if (props.callback(item, props.list[prop], prop)) {
1156
+ return props.list[prop];
1157
+ }
1158
+ }
1159
+ }
1160
+ },
1161
+ find() {
1162
+ const props = this.eachProps(arguments);
1163
+ for (let prop in props.list) {
1164
+ if (props.list.hasOwnProperty(prop)) {
1165
+ const item = this.instance(props.list[prop]);
1166
+ if (props.callback(item, props.list[prop], prop)) {
1167
+ return item;
1168
+ }
1169
+ }
1170
+ }
1171
+ return false;
1172
+ },
1173
+ alt(prop, defaults) {
1174
+ prop = this.attr(prop);
1175
+ return typeof prop === 'undefined' ? defaults : prop;
1176
+ },
1177
+ attr(key, value) {
1178
+ let i = 0,
1179
+ data = this.data,
1180
+ name = (key || '').split('.'),
1181
+ prop = name.pop(),
1182
+ len = arguments.length;
1183
+ for (; i < name.length; i++) {
1184
+ if (data && data.hasOwnProperty(name[i])) {
1185
+ data = data[name[i]];
1186
+ } else {
1187
+ if (len === 2) {
1188
+ data = data[name[i]] = {};
1189
+ } else {
1190
+ break;
1191
+ }
1192
+ }
1193
+ }
1194
+ if (len === 1) {
1195
+ return data ? data[prop] : undefined;
1196
+ }
1197
+ if (len === 2) {
1198
+ data[prop] = value;
1199
+ }
1200
+ return this;
1201
+ },
1202
+ stringify() {
1203
+ return JSON.stringify(this.serialize());
1204
+ },
1205
+ serialize() {
1206
+ return this.data;
1207
+ }
1208
+ });
1209
+
1210
+ const Response = Model.extend({
1211
+ stringFormat(string) {
1212
+ const that = this;
1213
+ return (string || '').replace(/{(.+?)}/g, function (match, prop) {
1214
+ return that.attr(['order.order_data', prop].join('.')) || match;
1215
+ });
1216
+ },
1217
+ setConnector(connector) {
1218
+ this.connector = connector;
1219
+ return this;
1220
+ },
1221
+ setUID(uid) {
1222
+ this.uid = uid;
1223
+ return this;
1224
+ },
1225
+ getUID() {
1226
+ return this.uid;
1227
+ },
1228
+ formDataProxy(url, data, target, method) {
1229
+ location.assign([ProxyUrl, JSON.stringify({
1230
+ url: url,
1231
+ params: data,
1232
+ target: target,
1233
+ method: method
1234
+ })].join('#'));
1235
+ },
1236
+ formDataSubmit(url, data, target, method) {
1237
+ if (url.match(/^http:/)) {
1238
+ return this.formDataProxy(url, data, target, method);
1239
+ }
1240
+ const action = this.stringFormat(url);
1241
+ const form = this.prepareForm(action, data, target, method);
1242
+ const body = this.utils.querySelector('body');
1243
+ body.appendChild(form);
1244
+ form.submit();
1245
+ form.parentNode.removeChild(form);
1246
+ },
1247
+ inProgress() {
1248
+ return this.attr('order.in_progress');
1249
+ },
1250
+ readyToSubmit() {
1251
+ return this.attr('order.ready_to_submit');
1252
+ },
1253
+ waitForResponse() {
1254
+ return this.attr('order.pending');
1255
+ },
1256
+ needVerifyCode() {
1257
+ return this.attr('order.need_verify_code');
1258
+ },
1259
+ redirectUrl() {
1260
+ if (this.attr('url')) {
1261
+ this.redirectToUrl(this.attr('url'));
1262
+ return true;
1263
+ }
1264
+ return false;
1265
+ },
1266
+ redirectToUrl(url) {
1267
+ location.assign(url);
1268
+ },
1269
+ submitToMerchant() {
1270
+ const ready = this.attr('order.ready_to_submit');
1271
+ const url = this.attr('model.url') || this.attr('order.response_url');
1272
+ const method = this.attr('order.method');
1273
+ const action = this.attr('order.action');
1274
+ const data = this.attr('model.send_data') || this.attr('order.order_data');
1275
+ if (ready && url && data) {
1276
+ if (action === 'redirect' || data['get_without_parameters'] === true) {
1277
+ this.redirectToUrl(url);
1278
+ } else {
1279
+ this.formDataSubmit(url, data, '_self', method);
1280
+ }
1281
+ return true;
1282
+ }
1283
+ },
1284
+ submitForm() {
1285
+ const method = this.attr('method');
1286
+ const url = this.attr('url');
1287
+ const data = this.attr('send_data');
1288
+ if (url && data) {
1289
+ this.formDataSubmit(url, data, '_self', method);
1290
+ return true;
1291
+ }
1292
+ return false;
1293
+ },
1294
+ sendResponse() {
1295
+ const action = this.attr('action');
1296
+ if (action === 'submit') return this.submitForm();
1297
+ if (action === 'redirect') return this.redirectUrl();
1298
+ return false;
1299
+ },
1300
+ prepare3dsData() {
1301
+ const params = {};
1302
+ const data = this.attr('submit3ds');
1303
+ if (data['3ds']) {
1304
+ params.token = this.attr('token');
1305
+ params.uid = this.getUID();
1306
+ params.frame = true;
1307
+ if (data['send_data'].TermUrl) {
1308
+ data['send_data'].TermUrl = [data['send_data'].TermUrl, this.utils.param(params)].join('#!!');
1309
+ }
1310
+ }
1311
+ return data;
1312
+ },
1313
+ waitOn3dsDecline() {
1314
+ const data = this.alt('submit3ds.checkout_data', {
1315
+ js_wait_on_3ds_decline: false,
1316
+ js_wait_on_3ds_decline_duration: 0
1317
+ });
1318
+ return data.js_wait_on_3ds_decline ? data.js_wait_on_3ds_decline_duration : 0;
1319
+ },
1320
+ submit3dsForm() {
1321
+ if (this.attr('submit3ds.checkout_data')) {
1322
+ this.connector.trigger('modal', this.prepare3dsData());
1323
+ }
1324
+ },
1325
+ supportedMethod(method) {
1326
+ const item = this.find('methods', function (item) {
1327
+ return item.alt('supportedMethods', '').match(method);
1328
+ });
1329
+ if (item) {
1330
+ this.attr('methods', [item.serialize()]);
1331
+ } else {
1332
+ this.attr('methods', []);
1333
+ }
1334
+ }
1335
+ });
1336
+
1337
+ const Api = Module.extend({
1338
+ defaults: {
1339
+ origin: ApiOrigin,
1340
+ endpoint: ApiEndpoint,
1341
+ messages: {
1342
+ modalHeader: 'Now you will be redirected to your bank 3DSecure. If you are not redirected please refer',
1343
+ modalLinkLabel: 'link'
1344
+ }
1345
+ },
1346
+ init(params) {
1347
+ this.initParams(params);
1348
+ },
1349
+ url(type, url) {
1350
+ return [this.params.origin, this.params.endpoint[type] || '/', url || ''].join('');
1351
+ },
1352
+ extendParams(params) {
1353
+ this.utils.extend(this.params, params);
1354
+ return this;
1355
+ },
1356
+ initParams(params) {
1357
+ this.params = this.utils.extend({}, this.defaults);
1358
+ this.extendParams(params);
1359
+ this.setOrigin(this.params.origin);
1360
+ this.loaded = false;
1361
+ this.created = false;
1362
+ },
1363
+ setOrigin(origin) {
1364
+ if (this.utils.isString(origin)) {
1365
+ this.params.origin = origin;
1366
+ }
1367
+ return this;
1368
+ },
1369
+ scope(callback) {
1370
+ callback = this.proxy(callback);
1371
+ if (this.createFrame().loaded === true) {
1372
+ callback();
1373
+ } else {
1374
+ this.on('checkout.api', callback);
1375
+ }
1376
+ },
1377
+ request(model, method, params) {
1378
+ const defer = Deferred();
1379
+ const data = {
1380
+ uid: this.connector.getUID(),
1381
+ action: model,
1382
+ method: method,
1383
+ params: params || {}
1384
+ };
1385
+ this.connector.send('request', data);
1386
+ this.connector.on(data.uid, this.proxy(function (ev, response, model, action) {
1387
+ const responseModel = new Response(response);
1388
+ responseModel.setUID(data.uid);
1389
+ responseModel.setConnector(this.connector);
1390
+ action = 'resolveWith';
1391
+ if (responseModel.attr('submit3ds')) {
1392
+ action = 'notifyWith';
1393
+ }
1394
+ if (responseModel.attr('error')) {
1395
+ action = 'rejectWith';
1396
+ }
1397
+ defer[action](this, [responseModel]);
1398
+ }));
1399
+ return defer;
1400
+ },
1401
+ loadFrame(url) {
1402
+ this.iframe = this.utils.createElement('iframe');
1403
+ this.addAttr(this.iframe, {
1404
+ allowtransparency: true,
1405
+ frameborder: 0,
1406
+ scrolling: 'no'
1407
+ });
1408
+ this.addAttr(this.iframe, {
1409
+ src: url
1410
+ });
1411
+ this.addCss(this.iframe, ApiFrameCss);
1412
+ this.body = this.utils.querySelector('body');
1413
+ if (this.body.firstChild) {
1414
+ this.body.insertBefore(this.iframe, this.body.firstChild);
1415
+ } else {
1416
+ this.body.appendChild(this.iframe);
1417
+ }
1418
+ return this.iframe;
1419
+ },
1420
+ createFrame() {
1421
+ if (this.created === false) {
1422
+ this.created = true;
1423
+ this.iframe = this.loadFrame(this.url('gateway'));
1424
+ this.connector = new Connector({
1425
+ target: this.iframe.contentWindow,
1426
+ origin: this.params.origin
1427
+ });
1428
+ this.connector.on('load', this.proxy('onLoadConnector'));
1429
+ this.connector.on('modal', this.proxy('onOpenModal'));
1430
+ }
1431
+ return this;
1432
+ },
1433
+ onOpenModal(xhr, model) {
1434
+ this.modal = new Modal({
1435
+ checkout: this,
1436
+ model: model
1437
+ });
1438
+ this.modal.on('close', this.proxy('_onCloseModal'));
1439
+ },
1440
+ onCloseModal(modal, data) {
1441
+ this.trigger('modal.close', modal, data);
1442
+ },
1443
+ onLoadConnector() {
1444
+ this.loaded = true;
1445
+ this.connector.off('load');
1446
+ this.trigger('checkout.api');
1447
+ this.off('checkout.api');
1448
+ }
1449
+ });
1450
+
1451
+ const GooglePayClient = Module.extend({
1452
+ id: 'google-payments-api',
1453
+ init() {
1454
+ this.client = null;
1455
+ this.wrapper = this.utils.querySelector('head');
1456
+ this.defer = Deferred();
1457
+ },
1458
+ load() {
1459
+ if (this.utils.getPath('google.payments.api.PaymentsClient')) {
1460
+ return this.defer.resolveWith(this);
1461
+ }
1462
+ if (this.utils.querySelector('#'.concat(this.id))) {
1463
+ return this.defer;
1464
+ }
1465
+ this.script = this.utils.createElement('script');
1466
+ this.addAttr(this.script, {
1467
+ id: this.id,
1468
+ async: true,
1469
+ src: GooglePayApi
1470
+ });
1471
+ this.utils.isElement(this.wrapper) && this.wrapper.appendChild(this.script);
1472
+ this.addEvent(this.script, 'load', 'onLoadSuccess');
1473
+ this.addEvent(this.script, 'error', 'onLoadError');
1474
+ return this.defer;
1475
+ },
1476
+ show(methods) {
1477
+ const method = methods.find(function (item) {
1478
+ return item.supportedMethods === 'https://google.com/pay';
1479
+ });
1480
+ const client = this.getClient({
1481
+ environment: method.data.environment
1482
+ });
1483
+ return client.loadPaymentData(method.data);
1484
+ },
1485
+ readyToPay(cx, response) {
1486
+ if (response.result) {
1487
+ this.defer.resolveWith(this);
1488
+ }
1489
+ },
1490
+ onError(cx, error) {
1491
+ this.defer.rejectWith(this, error);
1492
+ },
1493
+ onLoadSuccess() {
1494
+ const client = this.getClient();
1495
+ if (client) client.isReadyToPay(GoogleBaseRequest).then(this.proxy('readyToPay')).catch(this.proxy('onError'));
1496
+ },
1497
+ onLoadError() {
1498
+ this.defer.rejectWith(this);
1499
+ },
1500
+ getClient(options) {
1501
+ if (options || this.client === null) {
1502
+ const PaymentClient = this.utils.getPath('google.payments.api.PaymentsClient');
1503
+ if (PaymentClient) {
1504
+ this.client = new PaymentClient(options);
1505
+ } else {
1506
+ this.onError(null, new Error('Google Client Error'));
1507
+ }
1508
+ }
1509
+ return this.client;
1510
+ }
1511
+ });
1512
+ const GooglePay = new GooglePayClient();
1513
+
1514
+ const getPaymentMethods = () => {
1515
+ return [['google', {
1516
+ supportedMethods: 'https://google.com/pay',
1517
+ data: GoogleBaseRequest
1518
+ }], ['apple', {
1519
+ supportedMethods: 'https://apple.com/apple-pay'
1520
+ }, () => hasProp(window, 'ApplePaySession')]];
1521
+ };
1522
+ let requestDeferred = null;
1523
+ let requestSupported = {
1524
+ fallback: false,
1525
+ provider: []
1526
+ };
1527
+ const getSupportedMethods = () => {
1528
+ if (requestDeferred) return requestDeferred;
1529
+ requestDeferred = Deferred();
1530
+ const methods = getPaymentMethods();
1531
+ const details = PaymentRequestDetails;
1532
+ (function check() {
1533
+ const item = methods.shift();
1534
+ if (item === undefined) {
1535
+ if (requestSupported.provider.indexOf('google') === -1) {
1536
+ requestSupported.fallback = true;
1537
+ requestSupported.provider.push('google');
1538
+ }
1539
+ return requestDeferred.resolve(requestSupported);
1540
+ }
1541
+ const method = item.shift();
1542
+ const config = item.shift();
1543
+ const callback = item.shift();
1544
+ if (isFunction(callback) && callback() === false) {
1545
+ setTimeout(check, 25);
1546
+ return false;
1547
+ }
1548
+ const request = getPaymentRequest([config], details, {});
1549
+ if (request) {
1550
+ request.canMakePayment().then(function (status) {
1551
+ if (status === true) requestSupported.provider.push(method);
1552
+ setTimeout(check, 25);
1553
+ }).catch(function () {
1554
+ setTimeout(check, 25);
1555
+ });
1556
+ } else {
1557
+ setTimeout(check, 25);
1558
+ }
1559
+ })();
1560
+ return requestDeferred;
1561
+ };
1562
+ const PaymentRequestInterface = Module.extend({
1563
+ config: {
1564
+ payment_system: '',
1565
+ fallback: false,
1566
+ methods: [],
1567
+ details: {},
1568
+ options: {}
1569
+ },
1570
+ supported: {
1571
+ fallback: false,
1572
+ provider: []
1573
+ },
1574
+ payload: {
1575
+ payment_system: null,
1576
+ provider: []
1577
+ },
1578
+ params: {},
1579
+ getSupportedMethods() {
1580
+ return getSupportedMethods().then(supported => {
1581
+ this.setSupported(supported);
1582
+ return supported;
1583
+ });
1584
+ },
1585
+ init(params) {
1586
+ this.params = params || {};
1587
+ },
1588
+ setSupported(supported) {
1589
+ this.supported = supported;
1590
+ this.trigger('supported', supported);
1591
+ return this;
1592
+ },
1593
+ setPayload(payload) {
1594
+ this.payload = payload;
1595
+ this.trigger('payload', payload);
1596
+ return this;
1597
+ },
1598
+ setMerchant(merchant) {
1599
+ this.merchant = merchant;
1600
+ },
1601
+ setApi(api) {
1602
+ if (api instanceof Api) this.api = api;
1603
+ return this;
1604
+ },
1605
+ getProviderPayload(method) {
1606
+ return this.payload.provider[method] || {};
1607
+ },
1608
+ isMethodSupported(method) {
1609
+ return this.supported.provider.indexOf(method) !== -1;
1610
+ },
1611
+ isFallbackMethod(method) {
1612
+ return method === 'google' && this.supported.fallback;
1613
+ }
1614
+ });
1615
+ const PaymentRequestApi = PaymentRequestInterface.extend({
1616
+ request(method, params, success, failure) {
1617
+ if (this.api) {
1618
+ this.api.scope(this.proxy(function () {
1619
+ this.api.request('api.checkout.pay', method, params).done(this.proxy(success)).fail(this.proxy(failure));
1620
+ }));
1621
+ }
1622
+ },
1623
+ update(data) {
1624
+ const defer = Deferred();
1625
+ this.request('methods', data, function (cx, model) {
1626
+ this.onUpdate(cx, model);
1627
+ defer.resolveWith(this, [model]);
1628
+ }, function (cx, model) {
1629
+ this.onError(cx, model);
1630
+ defer.rejectWith(this, [model]);
1631
+ });
1632
+ return defer;
1633
+ },
1634
+ onUpdate(cx, model) {
1635
+ this.setPayload(model.serialize());
1636
+ },
1637
+ onError(cx, model) {
1638
+ this.trigger('error', model);
1639
+ },
1640
+ isPending() {
1641
+ return this.pendingState === true;
1642
+ },
1643
+ setPending(state) {
1644
+ this.pendingState = state;
1645
+ setTimeout(() => {
1646
+ this.trigger('pending', state);
1647
+ }, 100);
1648
+ },
1649
+ beforeCallback(defer) {
1650
+ defer.resolve();
1651
+ },
1652
+ setBeforeCallback(callback) {
1653
+ if (isFunction(callback)) {
1654
+ this.beforeCallback = callback;
1655
+ }
1656
+ return this;
1657
+ },
1658
+ before() {
1659
+ if (this.isPending()) return;
1660
+ this.setPending(true);
1661
+ const defer = Deferred();
1662
+ defer.always(this.proxy(function () {
1663
+ this.setPending(false);
1664
+ }));
1665
+ this.beforeCallback(defer);
1666
+ return defer;
1667
+ },
1668
+ pay(method) {
1669
+ if (this.isPending()) return;
1670
+ this.setPending(true);
1671
+ const payload = this.getProviderPayload(method);
1672
+ const response = Deferred();
1673
+ response.always(function () {
1674
+ this.setPending(false);
1675
+ });
1676
+ if (this.isMethodSupported(method) === false) {
1677
+ return response.rejectWith(this, [{
1678
+ test: true
1679
+ }]);
1680
+ }
1681
+ if (this.isFallbackMethod(method)) {
1682
+ this.makePaymentFallback(response, payload.methods);
1683
+ } else {
1684
+ this.makeNativePayment(response, payload);
1685
+ }
1686
+ return response.done(function (details) {
1687
+ this.trigger('details', {
1688
+ payment_system: this.payload.payment_system,
1689
+ data: details
1690
+ });
1691
+ }).fail(function (error) {
1692
+ this.trigger('error', error);
1693
+ if (this.params.embedded === true) {
1694
+ location.reload();
1695
+ this.trigger('reload', this.params);
1696
+ }
1697
+ });
1698
+ },
1699
+ makeNativePayment(defer, payload) {
1700
+ const self = this;
1701
+ const request = getPaymentRequest(payload.methods, payload.details, payload.options);
1702
+ this.addEvent(request, 'merchantvalidation', 'merchantValidation');
1703
+ request.canMakePayment().then(function () {
1704
+ request.show().then(function (response) {
1705
+ response.complete('success').then(function () {
1706
+ defer.resolveWith(self, [response.details]);
1707
+ });
1708
+ }).catch(function (e) {
1709
+ defer.rejectWith(self, [{
1710
+ code: e.code,
1711
+ message: e.message
1712
+ }]);
1713
+ });
1714
+ }).catch(function (e) {
1715
+ defer.rejectWith(self, [{
1716
+ code: e.code,
1717
+ message: e.message
1718
+ }]);
1719
+ });
1720
+ },
1721
+ makePaymentFallback(defer, methods) {
1722
+ const self = this;
1723
+ GooglePay.load().then(() => {
1724
+ GooglePay.show(methods).then(details => {
1725
+ defer.resolveWith(self, [details]);
1726
+ }).catch(e => {
1727
+ defer.rejectWith(self, [{
1728
+ code: e.code,
1729
+ message: e.message
1730
+ }]);
1731
+ });
1732
+ });
1733
+ },
1734
+ appleSession(params) {
1735
+ const defer = Deferred();
1736
+ this.request('session', params, function (c, model) {
1737
+ defer.resolveWith(this, [model.serialize()]);
1738
+ }, function (c, model) {
1739
+ defer.rejectWith(this, [model]);
1740
+ });
1741
+ return defer;
1742
+ },
1743
+ merchantValidation(cx, event) {
1744
+ const {
1745
+ validationURL
1746
+ } = event;
1747
+ const {
1748
+ host
1749
+ } = location;
1750
+ this.appleSession({
1751
+ url: validationURL,
1752
+ domain: host,
1753
+ merchant_id: this.merchant
1754
+ }).done(function (session) {
1755
+ try {
1756
+ event.complete(session.data);
1757
+ } catch (error) {
1758
+ this.trigger('error', error);
1759
+ }
1760
+ }).fail(function (error) {
1761
+ this.trigger('error', error);
1762
+ });
1763
+ }
1764
+ });
1765
+
1766
+ const PaymentElement = Module.extend({
1767
+ defaults: {
1768
+ method: null,
1769
+ appendTo: null,
1770
+ className: 'payment-element',
1771
+ origin: ApiOrigin,
1772
+ endpoint: ApiEndpoint.element,
1773
+ mode: 'plain',
1774
+ color: 'black',
1775
+ lang: 'en',
1776
+ height: 38
1777
+ },
1778
+ init(params) {
1779
+ this.params = {};
1780
+ this.utils.extend(this.params, this.defaults);
1781
+ this.utils.extend(this.params, params);
1782
+ this.initElement();
1783
+ },
1784
+ getElementUrl() {
1785
+ return [this.params.origin, this.params.endpoint].join('');
1786
+ },
1787
+ getElementOptions() {
1788
+ return this.utils.param({
1789
+ method: this.params.method,
1790
+ mode: this.params.mode,
1791
+ style: this.params.style,
1792
+ color: this.params.color,
1793
+ lang: this.params.lang
1794
+ });
1795
+ },
1796
+ initElement() {
1797
+ this.element = this.utils.createElement('div');
1798
+ this.iframe = this.utils.createElement('iframe');
1799
+ this.button = this.utils.createElement('a');
1800
+ this.addCss(this.element, ButtonContainerCss);
1801
+ this.addCss(this.button, ButtonCoverCss);
1802
+ this.addAttr(this.button, ButtonCoverAttrs);
1803
+ this.addCss(this.iframe, ButtonFrameCss);
1804
+ this.addAttr(this.iframe, ButtonFrameAttrs);
1805
+ this.addAttr(this.iframe, {
1806
+ src: [this.getElementUrl(), this.getElementOptions()].join('?')
1807
+ });
1808
+ this.addEvent(this.iframe, 'load', 'onloadConnector');
1809
+ this.addEvent(this.iframe, 'error', 'errorConnector');
1810
+ this.addAttr(this.element, {
1811
+ class: this.params.className
1812
+ });
1813
+ this.element.appendChild(this.iframe);
1814
+ this.element.appendChild(this.button);
1815
+ },
1816
+ errorConnector() {
1817
+ log('frame load error');
1818
+ },
1819
+ onloadConnector() {
1820
+ this.connector = new Connector({
1821
+ target: this.iframe.contentWindow,
1822
+ origin: this.params.origin
1823
+ });
1824
+ },
1825
+ send(action, data) {
1826
+ if (this.connector) {
1827
+ this.connector.send(action, data);
1828
+ }
1829
+ },
1830
+ onEvent(cx, ev) {
1831
+ ev.preventDefault();
1832
+ if (this.pending) return false;
1833
+ this.send('event', {
1834
+ type: ev.type
1835
+ });
1836
+ },
1837
+ onClick() {
1838
+ if (this.pending) return false;
1839
+ this.request.before().done(this.proxy('onClickDone')).fail(this.proxy('onClickFail'));
1840
+ },
1841
+ onClickDone() {
1842
+ this.request.pay(this.params.method);
1843
+ },
1844
+ onClickFail() {},
1845
+ onSupported(cx, supported) {
1846
+ if (supported.provider.includes(this.params.method)) {
1847
+ this.mount();
1848
+ }
1849
+ },
1850
+ onPayload(cx, payload) {
1851
+ if (payload.allowed.includes(this.params.method)) {
1852
+ this.show();
1853
+ }
1854
+ },
1855
+ onPending(cx, state) {
1856
+ this.pending = state;
1857
+ this.send('pending', {
1858
+ state: state
1859
+ });
1860
+ },
1861
+ initEvents() {
1862
+ this.addEvent(this.button, 'mouseenter', 'onEvent');
1863
+ this.addEvent(this.button, 'mouseleave', 'onEvent');
1864
+ this.addEvent(this.button, 'blur', 'onEvent');
1865
+ this.addEvent(this.button, 'focus', 'onEvent');
1866
+ this.addEvent(this.button, 'click', 'onClick');
1867
+ },
1868
+ setPaymentRequest(request) {
1869
+ if (!(request instanceof PaymentRequestApi)) throw Error('request is not instance of PaymentRequestApi');
1870
+ this.request = request;
1871
+ const onSupported = this.proxy('onSupported');
1872
+ const onPayload = this.proxy('onPayload');
1873
+ const onPending = this.proxy('onPending');
1874
+ this.request.off('supported', onSupported).on('supported', onSupported);
1875
+ this.request.off('payload', onPayload).on('payload', onPayload);
1876
+ this.request.off('pending', onPending).on('pending', onPending);
1877
+ return this;
1878
+ },
1879
+ appendTo(appendTo) {
1880
+ const container = this.utils.querySelector(appendTo);
1881
+ if (container) container.appendChild(this.element);
1882
+ this.initEvents();
1883
+ return this;
1884
+ },
1885
+ mount() {
1886
+ this.appendTo(this.params.appendTo);
1887
+ },
1888
+ isMounted() {
1889
+ return document.body.contains(this.element);
1890
+ },
1891
+ show() {
1892
+ if (this.isMounted() === false) return this;
1893
+ this.addCss(this.iframe, {
1894
+ transition: 'opacity 0.6s 0.4s ease-out',
1895
+ opacity: this.utils.cssUnit(1)
1896
+ });
1897
+ this.addCss(this.element, {
1898
+ transition: 'height 0.2s ease-out',
1899
+ height: this.utils.cssUnit(this.params.height, 'px')
1900
+ });
1901
+ this.trigger('show', {});
1902
+ return this;
1903
+ },
1904
+ hide() {
1905
+ if (this.isMounted() === false) return this;
1906
+ this.addCss(this.iframe, {
1907
+ transition: 'opacity 0.4s ease-out',
1908
+ opacity: this.utils.cssUnit(0)
1909
+ });
1910
+ this.addCss(this.element, {
1911
+ transition: 'height 0.2s 0.4s ease-out',
1912
+ height: this.utils.cssUnit(0, 'px')
1913
+ });
1914
+ this.trigger('hide', {});
1915
+ return this;
1916
+ }
1917
+ });
1918
+
1919
+ const PaymentButton = Module.extend({
1920
+ defaults: {
1921
+ origin: ApiOrigin,
1922
+ endpoint: ApiEndpoint,
1923
+ methods: ['apple', 'google'],
1924
+ element: null,
1925
+ style: {
1926
+ height: 38,
1927
+ mode: 'default',
1928
+ type: 'long',
1929
+ color: 'black'
1930
+ },
1931
+ data: {
1932
+ lang: 'en'
1933
+ },
1934
+ before(defer) {
1935
+ defer.resolve();
1936
+ }
1937
+ },
1938
+ init(params) {
1939
+ this.elements = {};
1940
+ this.supported = false;
1941
+ this.params = {
1942
+ element: params.element,
1943
+ methods: params.methods || this.defaults.methods,
1944
+ origin: params.origin || this.defaults.origin,
1945
+ endpoint: this.utils.extend({}, this.defaults.endpoint, params.endpoint),
1946
+ style: this.utils.extend({}, this.defaults.style, params.style),
1947
+ before: params.before || this.defaults.before,
1948
+ data: this.utils.extend({}, this.defaults.data, params.data)
1949
+ };
1950
+ this.initApi(params.api);
1951
+ this.initPaymentRequestApi();
1952
+ this.initElements();
1953
+ this.update();
1954
+ },
1955
+ initApi(api) {
1956
+ if (api instanceof Api) {
1957
+ this.api = api;
1958
+ } else {
1959
+ this.api = new Api({
1960
+ origin: this.params.origin,
1961
+ endpoint: this.params.endpoint
1962
+ });
1963
+ }
1964
+ },
1965
+ initPaymentRequestApi() {
1966
+ this.request = new PaymentRequestApi();
1967
+ this.request.setApi(this.api);
1968
+ this.request.setMerchant(this.params.data.merchant_id);
1969
+ this.request.setBeforeCallback(this.params.before);
1970
+ this.request.on('details', this.proxy('onDetails'));
1971
+ this.request.on('error', this.proxy('onError'));
1972
+ },
1973
+ initElements() {
1974
+ const style = this.params.style;
1975
+ const data = this.params.data;
1976
+ const origin = this.params.origin;
1977
+ const appendTo = this.params.element;
1978
+ const endpoint = this.params.endpoint.element;
1979
+ const request = this.request;
1980
+ this.container = this.utils.querySelector(this.params.element);
1981
+ this.addCss(this.container, {
1982
+ display: 'flex',
1983
+ gap: '1rem',
1984
+ 'flex-direction': 'column'
1985
+ });
1986
+ forEach(this.params.methods, function (method) {
1987
+ const element = new PaymentElement({
1988
+ origin: origin,
1989
+ endpoint: endpoint,
1990
+ method: method,
1991
+ appendTo: appendTo,
1992
+ color: style.color,
1993
+ mode: style.mode,
1994
+ lang: data.lang,
1995
+ height: style.height
1996
+ });
1997
+ element.setPaymentRequest(request);
1998
+ });
1999
+ request.getSupportedMethods();
2000
+ },
2001
+ update(data) {
2002
+ return this.request.update(this.utils.extend(this.params.data, data || {}));
2003
+ },
2004
+ onDetails(cx, data) {
2005
+ this.api.scope(() => {
2006
+ this.api.request('api.checkout.form', 'request', this.utils.extend({}, this.params.data, data)).done(this.proxy('onSuccess')).fail(this.proxy('onError'));
2007
+ });
2008
+ },
2009
+ onSuccess(cx, data) {
2010
+ this.trigger('success', data);
2011
+ },
2012
+ onError(cx, data) {
2013
+ this.trigger('error', data);
2014
+ }
2015
+ });
2016
+
2017
+ const parseConfig = config => {
2018
+ const data = {
2019
+ payment_system: config.payment_system,
2020
+ provider: {}
2021
+ };
2022
+ const methods = config.methods || [];
2023
+ const details = config.details || {};
2024
+ const options = config.options || {};
2025
+ const regex = new RegExp('//([a-z]+)\\.com/');
2026
+ methods.forEach(function (item) {
2027
+ const match = regex.exec(item.supportedMethods);
2028
+ if (match === null) return;
2029
+ data.provider[match[1]] = {
2030
+ methods: [item],
2031
+ details: details,
2032
+ options: options
2033
+ };
2034
+ });
2035
+ return data;
2036
+ };
2037
+ const PaymentContainer = Module.extend({
2038
+ defaults: {
2039
+ element: null,
2040
+ method: 'card',
2041
+ data: {
2042
+ lang: 'en'
2043
+ },
2044
+ style: {}
2045
+ },
2046
+ init(params) {
2047
+ this.initParams(params);
2048
+ this.initEvents();
2049
+ },
2050
+ initParams(params) {
2051
+ this.params = this.utils.extend({}, this.defaults, params);
2052
+ this.element = this.utils.querySelector(this.params.element);
2053
+ this.connector = new Connector({
2054
+ target: window.parent
2055
+ });
2056
+ this.payment = new PaymentRequestApi({
2057
+ embedded: true
2058
+ });
2059
+ },
2060
+ extendParams(params) {
2061
+ this.utils.extend(this.params, {
2062
+ method: params.method,
2063
+ style: params.style,
2064
+ data: params.data,
2065
+ css: params.css
2066
+ });
2067
+ },
2068
+ getGoogleLangSupport(lang, defaults) {
2069
+ return GooglePayLanguages.indexOf(lang) !== -1 ? lang : defaults;
2070
+ },
2071
+ getButtonColor(color) {
2072
+ return ButtonColorMap[color] || ButtonDefaultColor;
2073
+ },
2074
+ getGoogleSvg(color, lang, mode) {
2075
+ const params = {
2076
+ endpoint: 'https://www.gstatic.com/instantbuy/svg',
2077
+ color: this.getButtonColor(color),
2078
+ mode: mode || 'plain',
2079
+ lang: lang || 'en'
2080
+ };
2081
+ let format = 'url("{endpoint}/{color}/{mode}/{lang}.svg")';
2082
+ if (mode === 'plain') {
2083
+ format = 'url("{endpoint}/{color}_gpay.svg")';
2084
+ }
2085
+ if (mode === 'buy') {
2086
+ format = 'url("{endpoint}/{color}/{lang}.svg")';
2087
+ }
2088
+ return this.utils.stringFormat(format, params);
2089
+ },
2090
+ getAppleSvg(color) {
2091
+ const format = 'url("svg/apple-pay-{color}.svg")';
2092
+ const params = {
2093
+ color: this.getButtonColor(color)
2094
+ };
2095
+ return this.utils.stringFormat(format, params);
2096
+ },
2097
+ getAppleLabel(lang) {
2098
+ return ButtonLabelMap[lang || 'en'];
2099
+ },
2100
+ addFrameImage() {
2101
+ const frame = this.utils.querySelector('iframe', this.element) || this.utils.createElement('iframe');
2102
+ const url = 'https://pay.google.com/gp/p/generate_gpay_btn_img';
2103
+ const style = this.params.style || {};
2104
+ const lang = this.getGoogleLangSupport(this.params.data.lang, 'en');
2105
+ const query = {
2106
+ buttonColor: style.color || 'black',
2107
+ browserLocale: lang,
2108
+ buttonSizeMode: 'fill'
2109
+ };
2110
+ const src = [url, this.utils.param(query)].join('?');
2111
+ this.addAttr(frame, {
2112
+ scrolling: 'no',
2113
+ frameborder: 0,
2114
+ src: src
2115
+ });
2116
+ this.element.appendChild(frame);
2117
+ this.element.classList.remove('short', 'long');
2118
+ },
2119
+ styleButton() {
2120
+ let element = this.element;
2121
+ let params = this.params;
2122
+ let method = params.method;
2123
+ let style = params.style || {};
2124
+ let lang = params.data.lang || 'en';
2125
+ let css = params.css || {};
2126
+ element.setAttribute('class', '');
2127
+ element.classList.add('button', 'pending');
2128
+ if (method === 'card') method = 'google';
2129
+ if (method) {
2130
+ element.classList.add(method);
2131
+ }
2132
+ {
2133
+ element.classList.add(lang);
2134
+ }
2135
+ if (style.type) {
2136
+ element.classList.add(style.type);
2137
+ }
2138
+ if (style.mode) {
2139
+ element.classList.add(style.mode);
2140
+ }
2141
+ if (style.color) {
2142
+ element.classList.add(style.color);
2143
+ }
2144
+ if (method === 'google') {
2145
+ if (style.type === 'short') {
2146
+ style.mode = 'plain';
2147
+ }
2148
+ if (style.mode === 'default') {
2149
+ this.addFrameImage();
2150
+ } else {
2151
+ css.image = this.getGoogleSvg(style.color, lang, style.mode);
2152
+ }
2153
+ }
2154
+ if (method === 'apple') {
2155
+ css.image = this.getAppleSvg(style.color);
2156
+ css.label = this.getAppleLabel(lang, style.mode);
2157
+ }
2158
+ {
2159
+ this.utils.forEach(css, function (value, name) {
2160
+ element.style.setProperty(['--', name].join(''), value);
2161
+ });
2162
+ }
2163
+ },
2164
+ initEvents() {
2165
+ this.payment.on('details', this.proxy(function (cx, data) {
2166
+ this.connector.send('details', data);
2167
+ this.connector.send('complete', data);
2168
+ }));
2169
+ this.payment.on('reload', this.proxy(function (cx, data) {
2170
+ this.connector.send('reload', data);
2171
+ }));
2172
+ this.payment.on('error', this.proxy(function (cx, data) {
2173
+ this.connector.send('error', data);
2174
+ }));
2175
+ this.connector.on('options', this.proxy(function (cx, data) {
2176
+ this.extendParams(data);
2177
+ this.styleButton();
2178
+ }));
2179
+ this.connector.on('pay', this.proxy(function () {
2180
+ if (!this.element.classList.contains('pending')) {
2181
+ if (this.params.method === 'apple') {
2182
+ const payload = this.payment.payload || {};
2183
+ const apple = payload.provider['apple'] || {};
2184
+ this.connector.send('pay', {
2185
+ payment_system: payload.payment_system,
2186
+ methods: apple.methods,
2187
+ details: apple.details,
2188
+ options: apple.options
2189
+ });
2190
+ } else {
2191
+ this.payment.setSupported({
2192
+ fallback: false,
2193
+ provider: ['google']
2194
+ }).pay('google');
2195
+ }
2196
+ }
2197
+ }));
2198
+ this.connector.on('config', this.proxy(function (cx, data) {
2199
+ this.payment.setPayload(data = parseConfig(data));
2200
+ if (data.payment_system && Object.keys(data.provider).length > 0) {
2201
+ this.element.classList.remove('pending');
2202
+ this.element.classList.add('ready');
2203
+ this.connector.send('show', {});
2204
+ } else {
2205
+ this.connector.send('hide', {});
2206
+ }
2207
+ }));
2208
+ this.connector.on('event', this.proxy(function (cx, data) {
2209
+ if (data.type === 'mouseenter') {
2210
+ this.element.classList.add('hover');
2211
+ }
2212
+ if (data.type === 'mouseleave') {
2213
+ this.element.classList.remove('hover');
2214
+ }
2215
+ if (data.type === 'focusin') {
2216
+ this.element.classList.add('active');
2217
+ }
2218
+ if (data.type === 'focusout') {
2219
+ this.element.classList.remove('active');
2220
+ }
2221
+ }));
2222
+ }
2223
+ });
2224
+
2225
+ const Widget = Api.extend({
2226
+ init(params) {
2227
+ this.initParams(params);
2228
+ this.initWidget();
2229
+ },
2230
+ initWidget() {
2231
+ this.initOptions(this.params.options);
2232
+ if (this.utils.isString(this.params.element)) {
2233
+ this.initElement(this.params.element);
2234
+ }
2235
+ },
2236
+ initOptions() {
2237
+ if (this.utils.isPlainObject(this.params.options)) {
2238
+ this.params.options = this.params.options || {};
2239
+ }
2240
+ },
2241
+ initElement(el) {},
2242
+ addSelectorEvent(el, ev, cb) {
2243
+ this.each(this.utils.querySelectorAll(el), function (cx, element) {
2244
+ this.addEvent(element, ev, cb);
2245
+ });
2246
+ return this;
2247
+ },
2248
+ getRequestParams() {
2249
+ return {};
2250
+ },
2251
+ sendRequest(el, ev) {
2252
+ if (ev.defaultPrevented) return;
2253
+ ev.preventDefault();
2254
+ this.trigger('request', this.getRequestParams(el));
2255
+ this.scope(function () {
2256
+ this.request('api.checkout.form', 'request', this.getRequestParams(el)).done(this.proxy('onSuccess')).fail(this.proxy('onError')).progress(this.proxy('onProgress'));
2257
+ });
2258
+ },
2259
+ onProgress(cx, model) {
2260
+ this.trigger('progress', model);
2261
+ },
2262
+ onSuccess(cx, model) {
2263
+ model.sendResponse();
2264
+ model.submitToMerchant();
2265
+ this.trigger('success', model);
2266
+ },
2267
+ onError(cx, model) {
2268
+ this.trigger('error', model);
2269
+ }
2270
+ });
2271
+
2272
+ const FormData = Module.extend({
2273
+ init(form) {
2274
+ this.setFormElement(form);
2275
+ },
2276
+ setFormElement(form) {
2277
+ if (this.utils.isElement(form)) {
2278
+ this.form = form;
2279
+ }
2280
+ },
2281
+ getData(filter) {
2282
+ const params = this.deparam(this.serializeArray());
2283
+ return filter === true ? this.utils.cleanObject(params) : params;
2284
+ },
2285
+ serializeArray() {
2286
+ const list = this.utils.toArray(this.form.elements);
2287
+ return this.utils.map(list, function (field) {
2288
+ if (field.disabled || field.name === '') return;
2289
+ if (field.type.match('checkbox|radio') && !field.checked) return;
2290
+ return {
2291
+ name: field.name,
2292
+ value: field.value
2293
+ };
2294
+ });
2295
+ },
2296
+ serializeAndEncode() {
2297
+ return this.utils.map(this.serializeArray(), function (field) {
2298
+ return [field.name, encodeURIComponent(field.value)].join('=');
2299
+ }).join('&');
2300
+ },
2301
+ deparam(obj) {
2302
+ let prop,
2303
+ result = {};
2304
+ const breaker = /[^\[\]]+|\[\]$/g;
2305
+ const attr = function (name, value) {
2306
+ let i,
2307
+ data = result,
2308
+ last = name.pop(),
2309
+ len = name.length;
2310
+ for (i = 0; i < len; i++) {
2311
+ if (!data[name[i]]) data[name[i]] = len === i + 1 && last === '[]' ? [] : {};
2312
+ data = data[name[i]];
2313
+ }
2314
+ if (last === '[]') {
2315
+ data.push(value);
2316
+ } else {
2317
+ data[last] = value;
2318
+ }
2319
+ };
2320
+ for (prop in obj) {
2321
+ if (obj.hasOwnProperty(prop)) {
2322
+ attr(obj[prop].name.match(breaker), obj[prop].value);
2323
+ }
2324
+ }
2325
+ return result;
2326
+ }
2327
+ });
2328
+ const WidgetForm = Widget.extend({
2329
+ initElement(el) {
2330
+ this.addSelectorEvent(el, 'submit', 'sendRequest');
2331
+ },
2332
+ getRequestParams(el) {
2333
+ return this.utils.extend({}, this.params.options, new FormData(el).getData());
2334
+ }
2335
+ });
2336
+
2337
+ const WidgetButton = Widget.extend({
2338
+ attributes: {},
2339
+ initElement(el) {
2340
+ if (this.utils.isPlainObject(this.params.attributes)) {
2341
+ this.utils.extend(this.attributes, this.params.attributes);
2342
+ }
2343
+ this.addSelectorEvent(el, 'click', 'sendRequest');
2344
+ },
2345
+ getRequestParams(el) {
2346
+ return this.utils.extend({}, this.params.options, this.getElementData(el));
2347
+ },
2348
+ getElementData(el) {
2349
+ const result = {};
2350
+ this.utils.forEach(this.attributes, function (value, key) {
2351
+ if (el.hasAttribute(key)) {
2352
+ result[value] = el.getAttribute(key);
2353
+ }
2354
+ });
2355
+ return result;
2356
+ }
2357
+ });
2358
+
2359
+ Component.add('Api', Api);
2360
+ Component.add('Connector', Connector);
2361
+ Component.add('PaymentButton', PaymentButton);
2362
+ Component.add('PaymentRequestApi', PaymentRequestApi);
2363
+ Component.add('PaymentElement', PaymentElement);
2364
+ Component.add('FormWidget', WidgetForm);
2365
+ Component.add('ButtonWidget', WidgetButton);
2366
+ Component.Utils = Utils;
2367
+ Component.Config = Config;
2368
+ Component.Api = Api;
2369
+ Component.Module = Module;
2370
+ Component.Connector = Connector;
2371
+ Component.Response = Response;
2372
+ Component.PaymentRequestApi = PaymentRequestApi;
2373
+ Component.PaymentContainer = PaymentContainer;
2374
+ Component.PaymentElement = PaymentElement;
2375
+ Component.PaymentButton = PaymentButton;
2376
+
2377
+ module.exports = Component;