@flittpayments/js-sdk 2.0.5 → 2.0.6
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.
- package/dist/cjs/checkout.js +408 -300
- package/dist/esm/checkout.js +418 -334
- package/dist/umd/checkout.js +1 -1
- package/dist/umd/checkout.js.map +1 -1
- package/package.json +1 -1
package/dist/cjs/checkout.js
CHANGED
|
@@ -312,9 +312,144 @@ const jsonParse = (value, defaults) => {
|
|
|
312
312
|
return defaults;
|
|
313
313
|
}
|
|
314
314
|
};
|
|
315
|
+
const PromiseWithResolvers = () => {
|
|
316
|
+
let resolve;
|
|
317
|
+
let reject;
|
|
318
|
+
const promise = new Promise((promiseResolve, promiseReject) => {
|
|
319
|
+
resolve = promiseResolve;
|
|
320
|
+
reject = promiseReject;
|
|
321
|
+
});
|
|
322
|
+
return {
|
|
323
|
+
promise,
|
|
324
|
+
resolve,
|
|
325
|
+
reject
|
|
326
|
+
};
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* @typedef PaymentRequestMethod
|
|
331
|
+
* @property {{[string]:any}} data
|
|
332
|
+
*/
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* @typedef PaymentRequestOptions
|
|
336
|
+
* @property {boolean} [requestPayerEmail]
|
|
337
|
+
* @property {boolean} [requestPayerPhone]
|
|
338
|
+
* @property {boolean} [requestPayerName]
|
|
339
|
+
* @property {boolean} [requestShipping]
|
|
340
|
+
*/
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* @typedef PaymentRequestConfig
|
|
344
|
+
* @property [PaymentRequestMethod] methods
|
|
345
|
+
* @property {{[string]:any}} options
|
|
346
|
+
*/
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* @param {PaymentRequestConfig} config
|
|
350
|
+
*/
|
|
351
|
+
const getAppleSessionConfig = config => {
|
|
352
|
+
const {
|
|
353
|
+
methods,
|
|
354
|
+
details,
|
|
355
|
+
options
|
|
356
|
+
} = config;
|
|
357
|
+
const method = methods.find(item => item.supportedMethods === 'https://apple.com/apple-pay');
|
|
358
|
+
const requiredShippingContactFields = [];
|
|
359
|
+
const requiredBillingContactFields = [];
|
|
360
|
+
if (options.requestShipping) requiredBillingContactFields.push('postalAddress');
|
|
361
|
+
if (options.requestPayerName) requiredShippingContactFields.push('name');
|
|
362
|
+
if (options.requestPayerEmail) requiredShippingContactFields.push('email');
|
|
363
|
+
if (options.requestPayerPhone) requiredShippingContactFields.push('phone');
|
|
364
|
+
//method.data.recurringPaymentRequest = recurringPaymentRequest
|
|
365
|
+
//method.data.deferredPaymentRequest = deferredPaymentRequest
|
|
366
|
+
return {
|
|
367
|
+
version: method.data.version,
|
|
368
|
+
countryCode: method.data.countryCode,
|
|
369
|
+
supportedNetworks: method.data.supportedNetworks,
|
|
370
|
+
merchantCapabilities: method.data.merchantCapabilities,
|
|
371
|
+
merchantIdentifier: method.data.merchantIdentifier,
|
|
372
|
+
lineItems: method.data.lineItems || details.displayItems,
|
|
373
|
+
additionalLineItems: method.data.additionalLineItems,
|
|
374
|
+
recurringPaymentRequest: method.data.recurringPaymentRequest,
|
|
375
|
+
deferredPaymentRequest: method.data.deferredPaymentRequest,
|
|
376
|
+
//
|
|
377
|
+
currencyCode: method.data.currencyCode || details.total.amount.currency,
|
|
378
|
+
total: {
|
|
379
|
+
label: details.total.label,
|
|
380
|
+
amount: details.total.amount.value
|
|
381
|
+
},
|
|
382
|
+
//
|
|
383
|
+
requiredBillingContactFields,
|
|
384
|
+
requiredShippingContactFields
|
|
385
|
+
};
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
// export const deferredPaymentRequest = {
|
|
389
|
+
// paymentDescription: 'Бронювання готельного номеру',
|
|
390
|
+
// deferredBilling: {
|
|
391
|
+
// label: 'Бронювання',
|
|
392
|
+
// amount: '50.00',
|
|
393
|
+
// type: 'final',
|
|
394
|
+
// paymentTiming: 'deferred',
|
|
395
|
+
// deferredPaymentDate: new Date('2026-01-05'),
|
|
396
|
+
// },
|
|
397
|
+
// managementURL: 'https://flitt.ksv.app/manage-booking.html',
|
|
398
|
+
// }
|
|
399
|
+
|
|
400
|
+
// export const recurringPaymentRequest = {
|
|
401
|
+
// paymentDescription: 'Місячна підписка',
|
|
402
|
+
// regularBilling: {
|
|
403
|
+
// label: 'Підписка на місяць',
|
|
404
|
+
// amount: '20.00',
|
|
405
|
+
// type: 'final',
|
|
406
|
+
// paymentTiming: 'recurring',
|
|
407
|
+
// recurringPaymentStartDate: new Date('2026-01-01T00:00:00'),
|
|
408
|
+
// recurringPaymentIntervalUnit: 'month',
|
|
409
|
+
// recurringPaymentIntervalCount: 6,
|
|
410
|
+
// recurringPaymentEndDate: new Date('2028-01-01T00:00:00'),
|
|
411
|
+
// },
|
|
412
|
+
// managementURL: 'https://flitt.ksv.app/manage-subscription.html',
|
|
413
|
+
// }
|
|
414
|
+
|
|
415
|
+
const getFunction = path => {
|
|
416
|
+
const props = path.split('.');
|
|
417
|
+
const value = props.reduce((acc, cur) => {
|
|
418
|
+
if (acc && acc.hasOwnProperty(cur)) {
|
|
419
|
+
acc = acc[cur];
|
|
420
|
+
return acc;
|
|
421
|
+
}
|
|
422
|
+
return null;
|
|
423
|
+
}, window);
|
|
424
|
+
return isFunction(value) ? value : value;
|
|
425
|
+
};
|
|
426
|
+
const loadExternalApi = (url, path) => {
|
|
427
|
+
const [existScript] = toArray(document.scripts).filter(script => script.src === url);
|
|
428
|
+
if (existScript) return Promise.resolve(getFunction(path));
|
|
429
|
+
const {
|
|
430
|
+
promise,
|
|
431
|
+
resolve
|
|
432
|
+
} = PromiseWithResolvers();
|
|
433
|
+
const script = document.createElement('script');
|
|
434
|
+
script.async = true;
|
|
435
|
+
script.src = url;
|
|
436
|
+
script.addEventListener('load', () => {
|
|
437
|
+
const value = getFunction(path);
|
|
438
|
+
console.log('api loading', 'success', url);
|
|
439
|
+
resolve(value);
|
|
440
|
+
});
|
|
441
|
+
script.addEventListener('error', e => {
|
|
442
|
+
const value = getFunction(path);
|
|
443
|
+
console.log('api loading', 'error', url);
|
|
444
|
+
resolve(value);
|
|
445
|
+
});
|
|
446
|
+
document.head.appendChild(script);
|
|
447
|
+
return promise;
|
|
448
|
+
};
|
|
315
449
|
|
|
316
450
|
var Utils = /*#__PURE__*/Object.freeze({
|
|
317
451
|
__proto__: null,
|
|
452
|
+
PromiseWithResolvers: PromiseWithResolvers,
|
|
318
453
|
addAttr: addAttr,
|
|
319
454
|
addClass: addClass,
|
|
320
455
|
cleanObject: cleanObject,
|
|
@@ -323,6 +458,8 @@ var Utils = /*#__PURE__*/Object.freeze({
|
|
|
323
458
|
deparam: deparam,
|
|
324
459
|
extend: extend,
|
|
325
460
|
forEach: forEach,
|
|
461
|
+
getAppleSessionConfig: getAppleSessionConfig,
|
|
462
|
+
getFunction: getFunction,
|
|
326
463
|
getPath: getPath,
|
|
327
464
|
getPaymentRequest: getPaymentRequest,
|
|
328
465
|
getStyle: getStyle,
|
|
@@ -340,6 +477,7 @@ var Utils = /*#__PURE__*/Object.freeze({
|
|
|
340
477
|
isRegexp: isRegexp,
|
|
341
478
|
isString: isString,
|
|
342
479
|
jsonParse: jsonParse,
|
|
480
|
+
loadExternalApi: loadExternalApi,
|
|
343
481
|
map: map,
|
|
344
482
|
param: param,
|
|
345
483
|
querySelector: querySelector,
|
|
@@ -370,6 +508,32 @@ const GoogleBaseRequest = {
|
|
|
370
508
|
}
|
|
371
509
|
}]
|
|
372
510
|
};
|
|
511
|
+
const PaymentMethodsConfig = [{
|
|
512
|
+
url: 'https://pay.google.com/gp/p/js/pay.js',
|
|
513
|
+
name: 'google',
|
|
514
|
+
path: 'google.payments.api.PaymentsClient',
|
|
515
|
+
callback(PaymentsClient) {
|
|
516
|
+
if (PaymentsClient) {
|
|
517
|
+
return new PaymentsClient({
|
|
518
|
+
environment: 'TEST'
|
|
519
|
+
}).isReadyToPay(GoogleBaseRequest).catch(e => {
|
|
520
|
+
console.log(e);
|
|
521
|
+
return false;
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
}, {
|
|
527
|
+
url: 'https://applepay.cdn-apple.com/jsapi/1.latest/apple-pay-sdk.js',
|
|
528
|
+
name: 'apple',
|
|
529
|
+
path: 'ApplePaySession',
|
|
530
|
+
callback(ApplePaySession) {
|
|
531
|
+
if (ApplePaySession) {
|
|
532
|
+
return ApplePaySession.supportsVersion(3);
|
|
533
|
+
}
|
|
534
|
+
return false;
|
|
535
|
+
}
|
|
536
|
+
}];
|
|
373
537
|
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
538
|
const PaymentRequestDetails = {
|
|
375
539
|
total: {
|
|
@@ -497,6 +661,7 @@ var Config = /*#__PURE__*/Object.freeze({
|
|
|
497
661
|
GoogleBaseRequest: GoogleBaseRequest,
|
|
498
662
|
GooglePayApi: GooglePayApi,
|
|
499
663
|
GooglePayLanguages: GooglePayLanguages,
|
|
664
|
+
PaymentMethodsConfig: PaymentMethodsConfig,
|
|
500
665
|
PaymentRequestDetails: PaymentRequestDetails,
|
|
501
666
|
ProxyUrl: ProxyUrl
|
|
502
667
|
});
|
|
@@ -551,28 +716,31 @@ function Deferred() {
|
|
|
551
716
|
const promise = {
|
|
552
717
|
done(callback) {
|
|
553
718
|
if (isFunction(callback)) {
|
|
554
|
-
if (
|
|
719
|
+
if (this.isResolved()) {
|
|
555
720
|
callback.apply(resultContext, resultArgs);
|
|
721
|
+
} else {
|
|
722
|
+
resolveCallbacks.push(callback);
|
|
556
723
|
}
|
|
557
|
-
resolveCallbacks.push(callback);
|
|
558
724
|
}
|
|
559
725
|
return this;
|
|
560
726
|
},
|
|
561
727
|
fail(callback) {
|
|
562
728
|
if (isFunction(callback)) {
|
|
563
|
-
if (
|
|
729
|
+
if (this.isRejected()) {
|
|
564
730
|
callback.apply(resultContext, resultArgs);
|
|
731
|
+
} else {
|
|
732
|
+
rejectCallbacks.push(callback);
|
|
565
733
|
}
|
|
566
|
-
rejectCallbacks.push(callback);
|
|
567
734
|
}
|
|
568
735
|
return this;
|
|
569
736
|
},
|
|
570
737
|
progress(callback) {
|
|
571
738
|
if (isFunction(callback)) {
|
|
572
|
-
if (
|
|
739
|
+
if (this.isProgress()) {
|
|
573
740
|
callback.apply(resultContext, resultArgs);
|
|
741
|
+
} else {
|
|
742
|
+
notifyCallbacks.push(callback);
|
|
574
743
|
}
|
|
575
|
-
notifyCallbacks.push(callback);
|
|
576
744
|
}
|
|
577
745
|
return this;
|
|
578
746
|
},
|
|
@@ -612,26 +780,25 @@ function Deferred() {
|
|
|
612
780
|
isResolved() {
|
|
613
781
|
return status === RESOLVED;
|
|
614
782
|
},
|
|
615
|
-
|
|
616
|
-
status
|
|
617
|
-
return this;
|
|
783
|
+
isProgress() {
|
|
784
|
+
return status === PROGRESS;
|
|
618
785
|
},
|
|
619
786
|
resolveWith(context, args) {
|
|
620
|
-
if (
|
|
787
|
+
if (this.isPending()) {
|
|
621
788
|
status = RESOLVED;
|
|
622
789
|
executeCallback(context, args, resolveCallbacks);
|
|
623
790
|
}
|
|
624
791
|
return this;
|
|
625
792
|
},
|
|
626
793
|
rejectWith(context, args) {
|
|
627
|
-
if (
|
|
794
|
+
if (this.isPending()) {
|
|
628
795
|
status = REJECTED;
|
|
629
796
|
executeCallback(context, args, rejectCallbacks);
|
|
630
797
|
}
|
|
631
798
|
return this;
|
|
632
799
|
},
|
|
633
800
|
notifyWith(context, args) {
|
|
634
|
-
if (
|
|
801
|
+
if (this.isPending()) {
|
|
635
802
|
status = PROGRESS;
|
|
636
803
|
executeCallback(context, args, notifyCallbacks);
|
|
637
804
|
status = PENDING;
|
|
@@ -1345,6 +1512,7 @@ const Api = Module.extend({
|
|
|
1345
1512
|
}
|
|
1346
1513
|
},
|
|
1347
1514
|
init(params) {
|
|
1515
|
+
this.iframeDeferred = Deferred();
|
|
1348
1516
|
this.initParams(params);
|
|
1349
1517
|
},
|
|
1350
1518
|
url(type, url) {
|
|
@@ -1358,8 +1526,6 @@ const Api = Module.extend({
|
|
|
1358
1526
|
this.params = this.utils.extend({}, this.defaults);
|
|
1359
1527
|
this.extendParams(params);
|
|
1360
1528
|
this.setOrigin(this.params.origin);
|
|
1361
|
-
this.loaded = false;
|
|
1362
|
-
this.created = false;
|
|
1363
1529
|
},
|
|
1364
1530
|
setOrigin(origin) {
|
|
1365
1531
|
if (this.utils.isString(origin)) {
|
|
@@ -1370,16 +1536,21 @@ const Api = Module.extend({
|
|
|
1370
1536
|
scope(callback) {
|
|
1371
1537
|
callback = this.proxy(callback);
|
|
1372
1538
|
this.domReady(function () {
|
|
1373
|
-
|
|
1374
|
-
|
|
1539
|
+
this.createFrame();
|
|
1540
|
+
if (this.iframeDeferred.isPending()) {
|
|
1541
|
+
this.iframeDeferred.done(callback);
|
|
1375
1542
|
} else {
|
|
1376
|
-
|
|
1543
|
+
callback();
|
|
1377
1544
|
}
|
|
1378
1545
|
});
|
|
1379
1546
|
},
|
|
1380
1547
|
domReady(callback) {
|
|
1381
1548
|
callback = this.proxy(callback);
|
|
1382
|
-
document.readyState
|
|
1549
|
+
if (document.readyState === 'loading') {
|
|
1550
|
+
window.addEventListener('DOMContentLoaded', callback);
|
|
1551
|
+
} else {
|
|
1552
|
+
callback();
|
|
1553
|
+
}
|
|
1383
1554
|
},
|
|
1384
1555
|
request(model, method, params) {
|
|
1385
1556
|
const defer = Deferred();
|
|
@@ -1405,7 +1576,8 @@ const Api = Module.extend({
|
|
|
1405
1576
|
}));
|
|
1406
1577
|
return defer;
|
|
1407
1578
|
},
|
|
1408
|
-
|
|
1579
|
+
createFrame() {
|
|
1580
|
+
if (this.iframe) return this;
|
|
1409
1581
|
this.iframe = this.utils.createElement('iframe');
|
|
1410
1582
|
this.addAttr(this.iframe, {
|
|
1411
1583
|
allowtransparency: true,
|
|
@@ -1413,31 +1585,29 @@ const Api = Module.extend({
|
|
|
1413
1585
|
scrolling: 'no'
|
|
1414
1586
|
});
|
|
1415
1587
|
this.addAttr(this.iframe, {
|
|
1416
|
-
src: url
|
|
1588
|
+
src: this.url('gateway')
|
|
1417
1589
|
});
|
|
1418
1590
|
this.addCss(this.iframe, ApiFrameCss);
|
|
1419
|
-
|
|
1591
|
+
if (this.utils.isElement(this.params.container)) {
|
|
1592
|
+
this.container = this.params.container;
|
|
1593
|
+
}
|
|
1594
|
+
if (this.utils.isString(this.params.container)) {
|
|
1595
|
+
this.container = this.utils.querySelector(this.params.container);
|
|
1596
|
+
}
|
|
1420
1597
|
if (this.container) {
|
|
1421
1598
|
if (this.container.firstChild) {
|
|
1422
1599
|
this.container.insertBefore(this.iframe, this.container.firstChild);
|
|
1423
1600
|
} else {
|
|
1424
1601
|
this.container.appendChild(this.iframe);
|
|
1425
1602
|
}
|
|
1426
|
-
} else {
|
|
1427
|
-
throw Error(`container element not found: querySelector("${this.params.container}")`);
|
|
1428
|
-
}
|
|
1429
|
-
return this.iframe;
|
|
1430
|
-
},
|
|
1431
|
-
createFrame() {
|
|
1432
|
-
if (this.created === false) {
|
|
1433
|
-
this.created = true;
|
|
1434
|
-
this.iframe = this.loadFrame(this.url('gateway'));
|
|
1435
1603
|
this.connector = new Connector({
|
|
1436
1604
|
target: this.iframe.contentWindow,
|
|
1437
1605
|
origin: this.params.origin
|
|
1438
1606
|
});
|
|
1439
1607
|
this.connector.on('load', this.proxy('onLoadConnector'));
|
|
1440
1608
|
this.connector.on('modal', this.proxy('onOpenModal'));
|
|
1609
|
+
} else {
|
|
1610
|
+
throw Error(`container element not found: document.querySelector("${this.params.container}")`);
|
|
1441
1611
|
}
|
|
1442
1612
|
return this;
|
|
1443
1613
|
},
|
|
@@ -1452,125 +1622,36 @@ const Api = Module.extend({
|
|
|
1452
1622
|
this.trigger('modal.close', modal, data);
|
|
1453
1623
|
},
|
|
1454
1624
|
onLoadConnector() {
|
|
1455
|
-
this.
|
|
1625
|
+
this.iframeDeferred.resolve(true);
|
|
1456
1626
|
this.connector.off('load');
|
|
1457
|
-
this.trigger('checkout.api');
|
|
1458
|
-
this.off('checkout.api');
|
|
1459
|
-
}
|
|
1460
|
-
});
|
|
1461
|
-
|
|
1462
|
-
const GooglePayClient = Module.extend({
|
|
1463
|
-
id: 'google-payments-api',
|
|
1464
|
-
init() {
|
|
1465
|
-
this.client = null;
|
|
1466
|
-
this.wrapper = this.utils.querySelector('head');
|
|
1467
|
-
this.defer = Deferred();
|
|
1468
|
-
},
|
|
1469
|
-
load() {
|
|
1470
|
-
if (this.utils.getPath('google.payments.api.PaymentsClient')) {
|
|
1471
|
-
return this.defer.resolveWith(this);
|
|
1472
|
-
}
|
|
1473
|
-
if (this.utils.querySelector('#'.concat(this.id))) {
|
|
1474
|
-
return this.defer;
|
|
1475
|
-
}
|
|
1476
|
-
this.script = this.utils.createElement('script');
|
|
1477
|
-
this.addAttr(this.script, {
|
|
1478
|
-
id: this.id,
|
|
1479
|
-
async: true,
|
|
1480
|
-
src: GooglePayApi
|
|
1481
|
-
});
|
|
1482
|
-
this.utils.isElement(this.wrapper) && this.wrapper.appendChild(this.script);
|
|
1483
|
-
this.addEvent(this.script, 'load', 'onLoadSuccess');
|
|
1484
|
-
this.addEvent(this.script, 'error', 'onLoadError');
|
|
1485
|
-
return this.defer;
|
|
1486
|
-
},
|
|
1487
|
-
show(methods) {
|
|
1488
|
-
const method = methods.find(function (item) {
|
|
1489
|
-
return item.supportedMethods === 'https://google.com/pay';
|
|
1490
|
-
});
|
|
1491
|
-
const client = this.getClient({
|
|
1492
|
-
environment: method.data.environment
|
|
1493
|
-
});
|
|
1494
|
-
return client.loadPaymentData(method.data);
|
|
1495
|
-
},
|
|
1496
|
-
readyToPay(cx, response) {
|
|
1497
|
-
if (response.result) {
|
|
1498
|
-
this.defer.resolveWith(this);
|
|
1499
|
-
}
|
|
1500
|
-
},
|
|
1501
|
-
onError(cx, error) {
|
|
1502
|
-
this.defer.rejectWith(this, error);
|
|
1503
|
-
},
|
|
1504
|
-
onLoadSuccess() {
|
|
1505
|
-
const client = this.getClient();
|
|
1506
|
-
if (client) client.isReadyToPay(GoogleBaseRequest).then(this.proxy('readyToPay')).catch(this.proxy('onError'));
|
|
1507
|
-
},
|
|
1508
|
-
onLoadError() {
|
|
1509
|
-
this.defer.rejectWith(this);
|
|
1510
|
-
},
|
|
1511
|
-
getClient(options) {
|
|
1512
|
-
if (options || this.client === null) {
|
|
1513
|
-
const PaymentClient = this.utils.getPath('google.payments.api.PaymentsClient');
|
|
1514
|
-
if (PaymentClient) {
|
|
1515
|
-
this.client = new PaymentClient(options);
|
|
1516
|
-
} else {
|
|
1517
|
-
this.onError(null, new Error('Google Client Error'));
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1520
|
-
return this.client;
|
|
1521
1627
|
}
|
|
1522
1628
|
});
|
|
1523
|
-
const GooglePay = new GooglePayClient();
|
|
1524
1629
|
|
|
1525
|
-
|
|
1526
|
-
return [['google', {
|
|
1527
|
-
supportedMethods: 'https://google.com/pay',
|
|
1528
|
-
data: GoogleBaseRequest
|
|
1529
|
-
}], ['apple', {
|
|
1530
|
-
supportedMethods: 'https://apple.com/apple-pay'
|
|
1531
|
-
}, () => hasProp(window, 'ApplePaySession')]];
|
|
1532
|
-
};
|
|
1533
|
-
let requestDeferred = null;
|
|
1534
|
-
let requestSupported = {
|
|
1535
|
-
fallback: false,
|
|
1536
|
-
provider: []
|
|
1537
|
-
};
|
|
1630
|
+
let supportedMethodsDeferred = null;
|
|
1538
1631
|
const getSupportedMethods = () => {
|
|
1539
|
-
if (
|
|
1540
|
-
|
|
1541
|
-
const
|
|
1542
|
-
const
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1632
|
+
if (supportedMethodsDeferred) return supportedMethodsDeferred;
|
|
1633
|
+
supportedMethodsDeferred = Deferred();
|
|
1634
|
+
const promises = [];
|
|
1635
|
+
const supported = {
|
|
1636
|
+
provider: []
|
|
1637
|
+
};
|
|
1638
|
+
forEach(PaymentMethodsConfig, method => {
|
|
1639
|
+
promises.push(loadExternalApi(method.url, method.path).then(method.callback).then(state => {
|
|
1640
|
+
if (state) {
|
|
1641
|
+
supported.provider.push(method.name);
|
|
1642
|
+
} else {
|
|
1643
|
+
console.log('error loading api', google);
|
|
1549
1644
|
}
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
}
|
|
1559
|
-
const request = getPaymentRequest([config], details, {});
|
|
1560
|
-
if (request) {
|
|
1561
|
-
request.canMakePayment().then(function (status) {
|
|
1562
|
-
if (status === true) requestSupported.provider.push(method);
|
|
1563
|
-
setTimeout(check, 25);
|
|
1564
|
-
}).catch(function () {
|
|
1565
|
-
setTimeout(check, 25);
|
|
1566
|
-
});
|
|
1567
|
-
} else {
|
|
1568
|
-
setTimeout(check, 25);
|
|
1569
|
-
}
|
|
1570
|
-
})();
|
|
1571
|
-
return requestDeferred;
|
|
1645
|
+
}));
|
|
1646
|
+
});
|
|
1647
|
+
Promise.all(promises).then(() => {
|
|
1648
|
+
supportedMethodsDeferred.resolve(supported);
|
|
1649
|
+
}, () => {
|
|
1650
|
+
supportedMethodsDeferred.resolve(supported);
|
|
1651
|
+
});
|
|
1652
|
+
return supportedMethodsDeferred;
|
|
1572
1653
|
};
|
|
1573
|
-
const
|
|
1654
|
+
const PaymentRequestApi = Module.extend({
|
|
1574
1655
|
config: {
|
|
1575
1656
|
payment_system: '',
|
|
1576
1657
|
fallback: false,
|
|
@@ -1609,6 +1690,16 @@ const PaymentRequestInterface = Module.extend({
|
|
|
1609
1690
|
setMerchant(merchant) {
|
|
1610
1691
|
this.merchant = merchant;
|
|
1611
1692
|
},
|
|
1693
|
+
setBeforeCallback(beforeCallback) {
|
|
1694
|
+
if (isFunction(beforeCallback)) {
|
|
1695
|
+
this.params.before = beforeCallback;
|
|
1696
|
+
}
|
|
1697
|
+
},
|
|
1698
|
+
setAfterCallback(afterCallback) {
|
|
1699
|
+
if (isFunction(afterCallback)) {
|
|
1700
|
+
this.params.after = afterCallback;
|
|
1701
|
+
}
|
|
1702
|
+
},
|
|
1612
1703
|
setApi(api) {
|
|
1613
1704
|
if (api instanceof Api) this.api = api;
|
|
1614
1705
|
return this;
|
|
@@ -1621,32 +1712,40 @@ const PaymentRequestInterface = Module.extend({
|
|
|
1621
1712
|
},
|
|
1622
1713
|
isFallbackMethod(method) {
|
|
1623
1714
|
return method === 'google' && this.supported.fallback;
|
|
1624
|
-
}
|
|
1625
|
-
|
|
1626
|
-
const
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
}));
|
|
1715
|
+
},
|
|
1716
|
+
request(model, method, params, success, failure) {
|
|
1717
|
+
const context = this;
|
|
1718
|
+
if (context.api) {
|
|
1719
|
+
context.api.scope(function () {
|
|
1720
|
+
context.api.request(model, method, params).done(success).fail(failure);
|
|
1721
|
+
});
|
|
1632
1722
|
}
|
|
1633
1723
|
},
|
|
1634
|
-
|
|
1724
|
+
session(params) {
|
|
1635
1725
|
const defer = Deferred();
|
|
1636
|
-
this.request('
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
this.onError(cx, model);
|
|
1641
|
-
defer.rejectWith(this, [model]);
|
|
1726
|
+
this.request('api.checkout.pay', 'session', params, function (model) {
|
|
1727
|
+
defer.resolve(model.serialize());
|
|
1728
|
+
}, function (model) {
|
|
1729
|
+
defer.reject(model);
|
|
1642
1730
|
});
|
|
1643
1731
|
return defer;
|
|
1644
1732
|
},
|
|
1645
|
-
|
|
1646
|
-
this.
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1733
|
+
update(data) {
|
|
1734
|
+
if (this.isPending()) return;
|
|
1735
|
+
this.setPending(true);
|
|
1736
|
+
const context = this;
|
|
1737
|
+
const defer = Deferred();
|
|
1738
|
+
this.params.data = data;
|
|
1739
|
+
this.request('api.checkout.pay', 'methods', this.params.data, function (model) {
|
|
1740
|
+
context.setPending(false);
|
|
1741
|
+
context.setPayload(model.serialize());
|
|
1742
|
+
defer.resolve(model);
|
|
1743
|
+
}, function (model) {
|
|
1744
|
+
context.setPending(false);
|
|
1745
|
+
context.trigger('error', model);
|
|
1746
|
+
defer.reject(model);
|
|
1747
|
+
});
|
|
1748
|
+
return defer;
|
|
1650
1749
|
},
|
|
1651
1750
|
isPending() {
|
|
1652
1751
|
return this.pendingState === true;
|
|
@@ -1654,123 +1753,100 @@ const PaymentRequestApi = PaymentRequestInterface.extend({
|
|
|
1654
1753
|
setPending(state) {
|
|
1655
1754
|
this.pendingState = state;
|
|
1656
1755
|
clearTimeout(this.pendingTimeoutEvent);
|
|
1657
|
-
this.pendingTimeoutEvent = setTimeout(()
|
|
1658
|
-
|
|
1659
|
-
},
|
|
1660
|
-
},
|
|
1661
|
-
beforeCallback(defer) {
|
|
1662
|
-
defer.resolve();
|
|
1663
|
-
},
|
|
1664
|
-
setBeforeCallback(callback) {
|
|
1665
|
-
if (isFunction(callback)) {
|
|
1666
|
-
this.beforeCallback = callback;
|
|
1667
|
-
}
|
|
1668
|
-
return this;
|
|
1756
|
+
this.pendingTimeoutEvent = setTimeout(function (context) {
|
|
1757
|
+
context.trigger('pending', state);
|
|
1758
|
+
}, 50, this);
|
|
1669
1759
|
},
|
|
1670
1760
|
before() {
|
|
1671
1761
|
if (this.isPending()) return;
|
|
1672
1762
|
this.setPending(true);
|
|
1673
1763
|
const defer = Deferred();
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1764
|
+
const context = this;
|
|
1765
|
+
defer.always(function () {
|
|
1766
|
+
context.setPending(false);
|
|
1767
|
+
});
|
|
1768
|
+
this.params.before(defer);
|
|
1678
1769
|
return defer;
|
|
1679
1770
|
},
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
this.
|
|
1683
|
-
|
|
1684
|
-
const response = Deferred();
|
|
1685
|
-
response.always(function () {
|
|
1686
|
-
this.setPending(false);
|
|
1687
|
-
});
|
|
1688
|
-
if (this.isMethodSupported(method) === false) {
|
|
1689
|
-
return response.rejectWith(this, [{
|
|
1690
|
-
test: true
|
|
1691
|
-
}]);
|
|
1692
|
-
}
|
|
1693
|
-
if (this.isFallbackMethod(method)) {
|
|
1694
|
-
this.makePaymentFallback(response, payload.methods);
|
|
1695
|
-
} else {
|
|
1696
|
-
this.makeNativePayment(response, payload);
|
|
1697
|
-
}
|
|
1698
|
-
return response.done(function (details) {
|
|
1699
|
-
this.trigger('details', {
|
|
1700
|
-
payment_system: this.payload.payment_system,
|
|
1701
|
-
data: details
|
|
1702
|
-
});
|
|
1703
|
-
}).fail(function (error) {
|
|
1704
|
-
this.trigger('error', error);
|
|
1705
|
-
if (this.params.embedded === true) {
|
|
1706
|
-
location.reload();
|
|
1707
|
-
this.trigger('reload', this.params);
|
|
1708
|
-
}
|
|
1709
|
-
});
|
|
1771
|
+
after(params) {
|
|
1772
|
+
const defer = Deferred();
|
|
1773
|
+
this.params.after(defer, params);
|
|
1774
|
+
return defer;
|
|
1710
1775
|
},
|
|
1711
|
-
|
|
1712
|
-
const
|
|
1713
|
-
const request =
|
|
1714
|
-
this.
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
}
|
|
1776
|
+
withApplePay(response, config) {
|
|
1777
|
+
const sessionConfig = getAppleSessionConfig(config);
|
|
1778
|
+
const request = new ApplePaySession(sessionConfig.version, sessionConfig);
|
|
1779
|
+
const merchant = this.merchant;
|
|
1780
|
+
const context = this;
|
|
1781
|
+
request.onvalidatemerchant = function (event) {
|
|
1782
|
+
context.session({
|
|
1783
|
+
url: event.validationURL,
|
|
1784
|
+
domain: location.host,
|
|
1785
|
+
merchant_id: merchant
|
|
1786
|
+
}).done(session => {
|
|
1787
|
+
try {
|
|
1788
|
+
request.completeMerchantValidation(session.data);
|
|
1789
|
+
} catch (error) {
|
|
1790
|
+
response.reject({
|
|
1791
|
+
code: error.code,
|
|
1792
|
+
message: error.message
|
|
1793
|
+
});
|
|
1794
|
+
}
|
|
1725
1795
|
});
|
|
1726
|
-
}
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1796
|
+
};
|
|
1797
|
+
request.oncancel = function () {
|
|
1798
|
+
response.reject({
|
|
1799
|
+
code: 20,
|
|
1800
|
+
message: 'cancel'
|
|
1801
|
+
});
|
|
1802
|
+
};
|
|
1803
|
+
request.onpaymentauthorized = function (event) {
|
|
1804
|
+
request.completePayment(ApplePaySession.STATUS_SUCCESS);
|
|
1805
|
+
response.resolve(event.payment);
|
|
1806
|
+
};
|
|
1807
|
+
request.begin();
|
|
1732
1808
|
},
|
|
1733
|
-
|
|
1734
|
-
const
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1809
|
+
withGooglePay(response, config) {
|
|
1810
|
+
const {
|
|
1811
|
+
methods
|
|
1812
|
+
} = config;
|
|
1813
|
+
const method = methods.find(item => item.supportedMethods === 'https://google.com/pay');
|
|
1814
|
+
const client = new google.payments.api.PaymentsClient({
|
|
1815
|
+
environment: method.data.environment
|
|
1816
|
+
});
|
|
1817
|
+
client.loadPaymentData(method.data).then(paymentData => {
|
|
1818
|
+
response.resolve(paymentData);
|
|
1819
|
+
}).catch(error => {
|
|
1820
|
+
response.reject({
|
|
1821
|
+
code: error.code,
|
|
1822
|
+
message: error.message
|
|
1743
1823
|
});
|
|
1744
1824
|
});
|
|
1745
1825
|
},
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
this.
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1826
|
+
pay(method) {
|
|
1827
|
+
if (this.isPending()) return;
|
|
1828
|
+
this.setPending(true);
|
|
1829
|
+
const context = this;
|
|
1830
|
+
const response = Deferred();
|
|
1831
|
+
const payload = this.getProviderPayload(method);
|
|
1832
|
+
response.always(function () {
|
|
1833
|
+
context.setPending(false);
|
|
1752
1834
|
});
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
}).done(function (session) {
|
|
1767
|
-
try {
|
|
1768
|
-
event.complete(session.data);
|
|
1769
|
-
} catch (error) {
|
|
1770
|
-
this.trigger('error', error);
|
|
1771
|
-
}
|
|
1835
|
+
switch (method) {
|
|
1836
|
+
case 'google':
|
|
1837
|
+
this.withGooglePay(response, payload);
|
|
1838
|
+
break;
|
|
1839
|
+
case 'apple':
|
|
1840
|
+
this.withApplePay(response, payload);
|
|
1841
|
+
break;
|
|
1842
|
+
}
|
|
1843
|
+
return response.done(function (data) {
|
|
1844
|
+
context.trigger('details', {
|
|
1845
|
+
payment_system: context.payload.payment_system,
|
|
1846
|
+
data
|
|
1847
|
+
});
|
|
1772
1848
|
}).fail(function (error) {
|
|
1773
|
-
|
|
1849
|
+
context.trigger('error', error);
|
|
1774
1850
|
});
|
|
1775
1851
|
}
|
|
1776
1852
|
});
|
|
@@ -1788,11 +1864,22 @@ const PaymentElement = Module.extend({
|
|
|
1788
1864
|
height: 38
|
|
1789
1865
|
},
|
|
1790
1866
|
init(params) {
|
|
1867
|
+
this.state = {
|
|
1868
|
+
isSupported: false,
|
|
1869
|
+
isAllowed: false,
|
|
1870
|
+
isMounted: false
|
|
1871
|
+
};
|
|
1791
1872
|
this.params = {};
|
|
1792
1873
|
this.utils.extend(this.params, this.defaults);
|
|
1793
1874
|
this.utils.extend(this.params, params);
|
|
1794
1875
|
this.initElement();
|
|
1795
1876
|
},
|
|
1877
|
+
timeout(callback, timeout) {
|
|
1878
|
+
this.timeoutMap = this.timeoutMap || {};
|
|
1879
|
+
clearTimeout(this.timeoutMap[timeout]);
|
|
1880
|
+
this.timeoutMap[callback] = setTimeout(callback, timeout);
|
|
1881
|
+
return this;
|
|
1882
|
+
},
|
|
1796
1883
|
getElementUrl() {
|
|
1797
1884
|
return [this.params.origin, this.params.endpoint].join('');
|
|
1798
1885
|
},
|
|
@@ -1853,19 +1940,18 @@ const PaymentElement = Module.extend({
|
|
|
1853
1940
|
},
|
|
1854
1941
|
onClickFail() {},
|
|
1855
1942
|
onSupported(cx, supported) {
|
|
1856
|
-
|
|
1857
|
-
this.mount();
|
|
1858
|
-
}
|
|
1943
|
+
this.state.isSupported = supported.provider.includes(this.params.method);
|
|
1859
1944
|
},
|
|
1860
1945
|
onPayload(cx, payload) {
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
}
|
|
1946
|
+
this.state.isAllowed = payload.allowed.includes(this.params.method);
|
|
1947
|
+
this.render();
|
|
1864
1948
|
},
|
|
1865
1949
|
onPending(cx, state) {
|
|
1866
1950
|
this.pending = state;
|
|
1867
|
-
this.
|
|
1868
|
-
|
|
1951
|
+
this.addCss(this.element, {
|
|
1952
|
+
transition: 'height 0.2s ease-out, opacity 0.4s ease-out',
|
|
1953
|
+
pointerEvents: this.pending ? 'none' : '',
|
|
1954
|
+
opacity: this.pending ? '0.5' : '1'
|
|
1869
1955
|
});
|
|
1870
1956
|
},
|
|
1871
1957
|
initEvents() {
|
|
@@ -1892,36 +1978,50 @@ const PaymentElement = Module.extend({
|
|
|
1892
1978
|
this.initEvents();
|
|
1893
1979
|
return this;
|
|
1894
1980
|
},
|
|
1895
|
-
|
|
1896
|
-
|
|
1981
|
+
render() {
|
|
1982
|
+
if (this.state.isSupported === false) return this;
|
|
1983
|
+
if (this.state.isAllowed === false) return this;
|
|
1984
|
+
this.mount();
|
|
1985
|
+
this.show();
|
|
1897
1986
|
},
|
|
1898
|
-
|
|
1899
|
-
|
|
1987
|
+
unmount() {
|
|
1988
|
+
if (this.element.parentNode) {
|
|
1989
|
+
this.element.parentNode.removeChild(this.element);
|
|
1990
|
+
}
|
|
1991
|
+
return this;
|
|
1992
|
+
},
|
|
1993
|
+
mount() {
|
|
1994
|
+
if (document.body.contains(this.element) === false) {
|
|
1995
|
+
this.appendTo(this.params.appendTo);
|
|
1996
|
+
}
|
|
1997
|
+
return this;
|
|
1900
1998
|
},
|
|
1901
1999
|
show() {
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
2000
|
+
this.timeout(() => {
|
|
2001
|
+
this.addCss(this.iframe, {
|
|
2002
|
+
transition: 'opacity 0.6s 0.4s ease-out',
|
|
2003
|
+
opacity: this.utils.cssUnit(1)
|
|
2004
|
+
});
|
|
2005
|
+
this.addCss(this.element, {
|
|
2006
|
+
transition: 'height 0.2s ease-out',
|
|
2007
|
+
height: this.utils.cssUnit(this.params.height, 'px')
|
|
2008
|
+
});
|
|
2009
|
+
this.trigger('show', {});
|
|
2010
|
+
}, 25);
|
|
1912
2011
|
return this;
|
|
1913
2012
|
},
|
|
1914
2013
|
hide() {
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
2014
|
+
this.timeout(() => {
|
|
2015
|
+
this.addCss(this.iframe, {
|
|
2016
|
+
transition: 'opacity 0.4s ease-out',
|
|
2017
|
+
opacity: this.utils.cssUnit(0)
|
|
2018
|
+
});
|
|
2019
|
+
this.addCss(this.element, {
|
|
2020
|
+
transition: 'height 0.2s 0.4s ease-out',
|
|
2021
|
+
height: this.utils.cssUnit(0, 'px')
|
|
2022
|
+
});
|
|
2023
|
+
this.trigger('hide', {});
|
|
2024
|
+
}, 25);
|
|
1925
2025
|
return this;
|
|
1926
2026
|
}
|
|
1927
2027
|
});
|
|
@@ -1943,6 +2043,9 @@ const PaymentButton = Module.extend({
|
|
|
1943
2043
|
},
|
|
1944
2044
|
before(defer) {
|
|
1945
2045
|
defer.resolve();
|
|
2046
|
+
},
|
|
2047
|
+
after(defer, params) {
|
|
2048
|
+
defer.resolve(params);
|
|
1946
2049
|
}
|
|
1947
2050
|
},
|
|
1948
2051
|
init(params) {
|
|
@@ -1954,7 +2057,8 @@ const PaymentButton = Module.extend({
|
|
|
1954
2057
|
origin: params.origin || this.defaults.origin,
|
|
1955
2058
|
endpoint: this.utils.extend({}, this.defaults.endpoint, params.endpoint),
|
|
1956
2059
|
style: this.utils.extend({}, this.defaults.style, params.style),
|
|
1957
|
-
before: params.before
|
|
2060
|
+
before: isFunction(params.before) ? params.before : this.defaults.before,
|
|
2061
|
+
after: isFunction(params.after) ? params.after : this.defaults.after,
|
|
1958
2062
|
data: this.utils.extend({}, this.defaults.data, params.data)
|
|
1959
2063
|
};
|
|
1960
2064
|
this.initApi(params.api);
|
|
@@ -1979,10 +2083,12 @@ const PaymentButton = Module.extend({
|
|
|
1979
2083
|
}
|
|
1980
2084
|
},
|
|
1981
2085
|
initPaymentRequestApi() {
|
|
1982
|
-
this.request = new PaymentRequestApi(
|
|
2086
|
+
this.request = new PaymentRequestApi({
|
|
2087
|
+
before: this.params.before,
|
|
2088
|
+
after: this.params.after
|
|
2089
|
+
});
|
|
1983
2090
|
this.request.setApi(this.api);
|
|
1984
2091
|
this.request.setMerchant(this.params.data.merchant_id);
|
|
1985
|
-
this.request.setBeforeCallback(this.params.before);
|
|
1986
2092
|
this.request.on('details', this.proxy('onDetails'));
|
|
1987
2093
|
this.request.on('error', this.proxy('onError'));
|
|
1988
2094
|
},
|
|
@@ -2019,7 +2125,9 @@ const PaymentButton = Module.extend({
|
|
|
2019
2125
|
},
|
|
2020
2126
|
onDetails(cx, data) {
|
|
2021
2127
|
this.api.scope(() => {
|
|
2022
|
-
this.
|
|
2128
|
+
this.request.after(this.params.data).done(extendParams => {
|
|
2129
|
+
this.api.request('api.checkout.form', 'request', this.utils.extend({}, this.params.data, extendParams || {}, data)).done(this.proxy('onSuccess')).fail(this.proxy('onError'));
|
|
2130
|
+
});
|
|
2023
2131
|
});
|
|
2024
2132
|
},
|
|
2025
2133
|
onSuccess(cx, data) {
|