@flittpayments/js-sdk 2.0.4 → 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/README.md +7 -7
- package/dist/cjs/checkout.js +419 -300
- package/dist/esm/checkout.js +429 -331
- 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;
|
|
@@ -1338,12 +1505,14 @@ const Api = Module.extend({
|
|
|
1338
1505
|
defaults: {
|
|
1339
1506
|
origin: ApiOrigin,
|
|
1340
1507
|
endpoint: ApiEndpoint,
|
|
1508
|
+
container: 'body',
|
|
1341
1509
|
messages: {
|
|
1342
1510
|
modalHeader: 'Now you will be redirected to your bank 3DSecure. If you are not redirected please refer',
|
|
1343
1511
|
modalLinkLabel: 'link'
|
|
1344
1512
|
}
|
|
1345
1513
|
},
|
|
1346
1514
|
init(params) {
|
|
1515
|
+
this.iframeDeferred = Deferred();
|
|
1347
1516
|
this.initParams(params);
|
|
1348
1517
|
},
|
|
1349
1518
|
url(type, url) {
|
|
@@ -1357,8 +1526,6 @@ const Api = Module.extend({
|
|
|
1357
1526
|
this.params = this.utils.extend({}, this.defaults);
|
|
1358
1527
|
this.extendParams(params);
|
|
1359
1528
|
this.setOrigin(this.params.origin);
|
|
1360
|
-
this.loaded = false;
|
|
1361
|
-
this.created = false;
|
|
1362
1529
|
},
|
|
1363
1530
|
setOrigin(origin) {
|
|
1364
1531
|
if (this.utils.isString(origin)) {
|
|
@@ -1368,10 +1535,21 @@ const Api = Module.extend({
|
|
|
1368
1535
|
},
|
|
1369
1536
|
scope(callback) {
|
|
1370
1537
|
callback = this.proxy(callback);
|
|
1371
|
-
|
|
1372
|
-
|
|
1538
|
+
this.domReady(function () {
|
|
1539
|
+
this.createFrame();
|
|
1540
|
+
if (this.iframeDeferred.isPending()) {
|
|
1541
|
+
this.iframeDeferred.done(callback);
|
|
1542
|
+
} else {
|
|
1543
|
+
callback();
|
|
1544
|
+
}
|
|
1545
|
+
});
|
|
1546
|
+
},
|
|
1547
|
+
domReady(callback) {
|
|
1548
|
+
callback = this.proxy(callback);
|
|
1549
|
+
if (document.readyState === 'loading') {
|
|
1550
|
+
window.addEventListener('DOMContentLoaded', callback);
|
|
1373
1551
|
} else {
|
|
1374
|
-
|
|
1552
|
+
callback();
|
|
1375
1553
|
}
|
|
1376
1554
|
},
|
|
1377
1555
|
request(model, method, params) {
|
|
@@ -1398,7 +1576,8 @@ const Api = Module.extend({
|
|
|
1398
1576
|
}));
|
|
1399
1577
|
return defer;
|
|
1400
1578
|
},
|
|
1401
|
-
|
|
1579
|
+
createFrame() {
|
|
1580
|
+
if (this.iframe) return this;
|
|
1402
1581
|
this.iframe = this.utils.createElement('iframe');
|
|
1403
1582
|
this.addAttr(this.iframe, {
|
|
1404
1583
|
allowtransparency: true,
|
|
@@ -1406,27 +1585,29 @@ const Api = Module.extend({
|
|
|
1406
1585
|
scrolling: 'no'
|
|
1407
1586
|
});
|
|
1408
1587
|
this.addAttr(this.iframe, {
|
|
1409
|
-
src: url
|
|
1588
|
+
src: this.url('gateway')
|
|
1410
1589
|
});
|
|
1411
1590
|
this.addCss(this.iframe, ApiFrameCss);
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
this.body.insertBefore(this.iframe, this.body.firstChild);
|
|
1415
|
-
} else {
|
|
1416
|
-
this.body.appendChild(this.iframe);
|
|
1591
|
+
if (this.utils.isElement(this.params.container)) {
|
|
1592
|
+
this.container = this.params.container;
|
|
1417
1593
|
}
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
if (this.
|
|
1422
|
-
this.
|
|
1423
|
-
|
|
1594
|
+
if (this.utils.isString(this.params.container)) {
|
|
1595
|
+
this.container = this.utils.querySelector(this.params.container);
|
|
1596
|
+
}
|
|
1597
|
+
if (this.container) {
|
|
1598
|
+
if (this.container.firstChild) {
|
|
1599
|
+
this.container.insertBefore(this.iframe, this.container.firstChild);
|
|
1600
|
+
} else {
|
|
1601
|
+
this.container.appendChild(this.iframe);
|
|
1602
|
+
}
|
|
1424
1603
|
this.connector = new Connector({
|
|
1425
1604
|
target: this.iframe.contentWindow,
|
|
1426
1605
|
origin: this.params.origin
|
|
1427
1606
|
});
|
|
1428
1607
|
this.connector.on('load', this.proxy('onLoadConnector'));
|
|
1429
1608
|
this.connector.on('modal', this.proxy('onOpenModal'));
|
|
1609
|
+
} else {
|
|
1610
|
+
throw Error(`container element not found: document.querySelector("${this.params.container}")`);
|
|
1430
1611
|
}
|
|
1431
1612
|
return this;
|
|
1432
1613
|
},
|
|
@@ -1441,125 +1622,36 @@ const Api = Module.extend({
|
|
|
1441
1622
|
this.trigger('modal.close', modal, data);
|
|
1442
1623
|
},
|
|
1443
1624
|
onLoadConnector() {
|
|
1444
|
-
this.
|
|
1625
|
+
this.iframeDeferred.resolve(true);
|
|
1445
1626
|
this.connector.off('load');
|
|
1446
|
-
this.trigger('checkout.api');
|
|
1447
|
-
this.off('checkout.api');
|
|
1448
1627
|
}
|
|
1449
1628
|
});
|
|
1450
1629
|
|
|
1451
|
-
|
|
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
|
-
};
|
|
1630
|
+
let supportedMethodsDeferred = null;
|
|
1527
1631
|
const getSupportedMethods = () => {
|
|
1528
|
-
if (
|
|
1529
|
-
|
|
1530
|
-
const
|
|
1531
|
-
const
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
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);
|
|
1538
1644
|
}
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
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;
|
|
1645
|
+
}));
|
|
1646
|
+
});
|
|
1647
|
+
Promise.all(promises).then(() => {
|
|
1648
|
+
supportedMethodsDeferred.resolve(supported);
|
|
1649
|
+
}, () => {
|
|
1650
|
+
supportedMethodsDeferred.resolve(supported);
|
|
1651
|
+
});
|
|
1652
|
+
return supportedMethodsDeferred;
|
|
1561
1653
|
};
|
|
1562
|
-
const
|
|
1654
|
+
const PaymentRequestApi = Module.extend({
|
|
1563
1655
|
config: {
|
|
1564
1656
|
payment_system: '',
|
|
1565
1657
|
fallback: false,
|
|
@@ -1598,6 +1690,16 @@ const PaymentRequestInterface = Module.extend({
|
|
|
1598
1690
|
setMerchant(merchant) {
|
|
1599
1691
|
this.merchant = merchant;
|
|
1600
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
|
+
},
|
|
1601
1703
|
setApi(api) {
|
|
1602
1704
|
if (api instanceof Api) this.api = api;
|
|
1603
1705
|
return this;
|
|
@@ -1610,32 +1712,40 @@ const PaymentRequestInterface = Module.extend({
|
|
|
1610
1712
|
},
|
|
1611
1713
|
isFallbackMethod(method) {
|
|
1612
1714
|
return method === 'google' && this.supported.fallback;
|
|
1613
|
-
}
|
|
1614
|
-
|
|
1615
|
-
const
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
}));
|
|
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
|
+
});
|
|
1621
1722
|
}
|
|
1622
1723
|
},
|
|
1623
|
-
|
|
1724
|
+
session(params) {
|
|
1624
1725
|
const defer = Deferred();
|
|
1625
|
-
this.request('
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
this.onError(cx, model);
|
|
1630
|
-
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);
|
|
1631
1730
|
});
|
|
1632
1731
|
return defer;
|
|
1633
1732
|
},
|
|
1634
|
-
|
|
1635
|
-
this.
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
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;
|
|
1639
1749
|
},
|
|
1640
1750
|
isPending() {
|
|
1641
1751
|
return this.pendingState === true;
|
|
@@ -1643,123 +1753,100 @@ const PaymentRequestApi = PaymentRequestInterface.extend({
|
|
|
1643
1753
|
setPending(state) {
|
|
1644
1754
|
this.pendingState = state;
|
|
1645
1755
|
clearTimeout(this.pendingTimeoutEvent);
|
|
1646
|
-
this.pendingTimeoutEvent = setTimeout(()
|
|
1647
|
-
|
|
1648
|
-
},
|
|
1649
|
-
},
|
|
1650
|
-
beforeCallback(defer) {
|
|
1651
|
-
defer.resolve();
|
|
1652
|
-
},
|
|
1653
|
-
setBeforeCallback(callback) {
|
|
1654
|
-
if (isFunction(callback)) {
|
|
1655
|
-
this.beforeCallback = callback;
|
|
1656
|
-
}
|
|
1657
|
-
return this;
|
|
1756
|
+
this.pendingTimeoutEvent = setTimeout(function (context) {
|
|
1757
|
+
context.trigger('pending', state);
|
|
1758
|
+
}, 50, this);
|
|
1658
1759
|
},
|
|
1659
1760
|
before() {
|
|
1660
1761
|
if (this.isPending()) return;
|
|
1661
1762
|
this.setPending(true);
|
|
1662
1763
|
const defer = Deferred();
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1764
|
+
const context = this;
|
|
1765
|
+
defer.always(function () {
|
|
1766
|
+
context.setPending(false);
|
|
1767
|
+
});
|
|
1768
|
+
this.params.before(defer);
|
|
1667
1769
|
return defer;
|
|
1668
1770
|
},
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
this.
|
|
1672
|
-
|
|
1673
|
-
const response = Deferred();
|
|
1674
|
-
response.always(function () {
|
|
1675
|
-
this.setPending(false);
|
|
1676
|
-
});
|
|
1677
|
-
if (this.isMethodSupported(method) === false) {
|
|
1678
|
-
return response.rejectWith(this, [{
|
|
1679
|
-
test: true
|
|
1680
|
-
}]);
|
|
1681
|
-
}
|
|
1682
|
-
if (this.isFallbackMethod(method)) {
|
|
1683
|
-
this.makePaymentFallback(response, payload.methods);
|
|
1684
|
-
} else {
|
|
1685
|
-
this.makeNativePayment(response, payload);
|
|
1686
|
-
}
|
|
1687
|
-
return response.done(function (details) {
|
|
1688
|
-
this.trigger('details', {
|
|
1689
|
-
payment_system: this.payload.payment_system,
|
|
1690
|
-
data: details
|
|
1691
|
-
});
|
|
1692
|
-
}).fail(function (error) {
|
|
1693
|
-
this.trigger('error', error);
|
|
1694
|
-
if (this.params.embedded === true) {
|
|
1695
|
-
location.reload();
|
|
1696
|
-
this.trigger('reload', this.params);
|
|
1697
|
-
}
|
|
1698
|
-
});
|
|
1771
|
+
after(params) {
|
|
1772
|
+
const defer = Deferred();
|
|
1773
|
+
this.params.after(defer, params);
|
|
1774
|
+
return defer;
|
|
1699
1775
|
},
|
|
1700
|
-
|
|
1701
|
-
const
|
|
1702
|
-
const request =
|
|
1703
|
-
this.
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
}
|
|
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
|
+
}
|
|
1714
1795
|
});
|
|
1715
|
-
}
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
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();
|
|
1721
1808
|
},
|
|
1722
|
-
|
|
1723
|
-
const
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
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
|
|
1732
1823
|
});
|
|
1733
1824
|
});
|
|
1734
1825
|
},
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
this.
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
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);
|
|
1741
1834
|
});
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
}).done(function (session) {
|
|
1756
|
-
try {
|
|
1757
|
-
event.complete(session.data);
|
|
1758
|
-
} catch (error) {
|
|
1759
|
-
this.trigger('error', error);
|
|
1760
|
-
}
|
|
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
|
+
});
|
|
1761
1848
|
}).fail(function (error) {
|
|
1762
|
-
|
|
1849
|
+
context.trigger('error', error);
|
|
1763
1850
|
});
|
|
1764
1851
|
}
|
|
1765
1852
|
});
|
|
@@ -1777,11 +1864,22 @@ const PaymentElement = Module.extend({
|
|
|
1777
1864
|
height: 38
|
|
1778
1865
|
},
|
|
1779
1866
|
init(params) {
|
|
1867
|
+
this.state = {
|
|
1868
|
+
isSupported: false,
|
|
1869
|
+
isAllowed: false,
|
|
1870
|
+
isMounted: false
|
|
1871
|
+
};
|
|
1780
1872
|
this.params = {};
|
|
1781
1873
|
this.utils.extend(this.params, this.defaults);
|
|
1782
1874
|
this.utils.extend(this.params, params);
|
|
1783
1875
|
this.initElement();
|
|
1784
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
|
+
},
|
|
1785
1883
|
getElementUrl() {
|
|
1786
1884
|
return [this.params.origin, this.params.endpoint].join('');
|
|
1787
1885
|
},
|
|
@@ -1842,19 +1940,18 @@ const PaymentElement = Module.extend({
|
|
|
1842
1940
|
},
|
|
1843
1941
|
onClickFail() {},
|
|
1844
1942
|
onSupported(cx, supported) {
|
|
1845
|
-
|
|
1846
|
-
this.mount();
|
|
1847
|
-
}
|
|
1943
|
+
this.state.isSupported = supported.provider.includes(this.params.method);
|
|
1848
1944
|
},
|
|
1849
1945
|
onPayload(cx, payload) {
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
}
|
|
1946
|
+
this.state.isAllowed = payload.allowed.includes(this.params.method);
|
|
1947
|
+
this.render();
|
|
1853
1948
|
},
|
|
1854
1949
|
onPending(cx, state) {
|
|
1855
1950
|
this.pending = state;
|
|
1856
|
-
this.
|
|
1857
|
-
|
|
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'
|
|
1858
1955
|
});
|
|
1859
1956
|
},
|
|
1860
1957
|
initEvents() {
|
|
@@ -1881,36 +1978,50 @@ const PaymentElement = Module.extend({
|
|
|
1881
1978
|
this.initEvents();
|
|
1882
1979
|
return this;
|
|
1883
1980
|
},
|
|
1884
|
-
|
|
1885
|
-
|
|
1981
|
+
render() {
|
|
1982
|
+
if (this.state.isSupported === false) return this;
|
|
1983
|
+
if (this.state.isAllowed === false) return this;
|
|
1984
|
+
this.mount();
|
|
1985
|
+
this.show();
|
|
1886
1986
|
},
|
|
1887
|
-
|
|
1888
|
-
|
|
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;
|
|
1889
1998
|
},
|
|
1890
1999
|
show() {
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
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);
|
|
1901
2011
|
return this;
|
|
1902
2012
|
},
|
|
1903
2013
|
hide() {
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
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);
|
|
1914
2025
|
return this;
|
|
1915
2026
|
}
|
|
1916
2027
|
});
|
|
@@ -1932,6 +2043,9 @@ const PaymentButton = Module.extend({
|
|
|
1932
2043
|
},
|
|
1933
2044
|
before(defer) {
|
|
1934
2045
|
defer.resolve();
|
|
2046
|
+
},
|
|
2047
|
+
after(defer, params) {
|
|
2048
|
+
defer.resolve(params);
|
|
1935
2049
|
}
|
|
1936
2050
|
},
|
|
1937
2051
|
init(params) {
|
|
@@ -1943,7 +2057,8 @@ const PaymentButton = Module.extend({
|
|
|
1943
2057
|
origin: params.origin || this.defaults.origin,
|
|
1944
2058
|
endpoint: this.utils.extend({}, this.defaults.endpoint, params.endpoint),
|
|
1945
2059
|
style: this.utils.extend({}, this.defaults.style, params.style),
|
|
1946
|
-
before: params.before
|
|
2060
|
+
before: isFunction(params.before) ? params.before : this.defaults.before,
|
|
2061
|
+
after: isFunction(params.after) ? params.after : this.defaults.after,
|
|
1947
2062
|
data: this.utils.extend({}, this.defaults.data, params.data)
|
|
1948
2063
|
};
|
|
1949
2064
|
this.initApi(params.api);
|
|
@@ -1968,10 +2083,12 @@ const PaymentButton = Module.extend({
|
|
|
1968
2083
|
}
|
|
1969
2084
|
},
|
|
1970
2085
|
initPaymentRequestApi() {
|
|
1971
|
-
this.request = new PaymentRequestApi(
|
|
2086
|
+
this.request = new PaymentRequestApi({
|
|
2087
|
+
before: this.params.before,
|
|
2088
|
+
after: this.params.after
|
|
2089
|
+
});
|
|
1972
2090
|
this.request.setApi(this.api);
|
|
1973
2091
|
this.request.setMerchant(this.params.data.merchant_id);
|
|
1974
|
-
this.request.setBeforeCallback(this.params.before);
|
|
1975
2092
|
this.request.on('details', this.proxy('onDetails'));
|
|
1976
2093
|
this.request.on('error', this.proxy('onError'));
|
|
1977
2094
|
},
|
|
@@ -2008,7 +2125,9 @@ const PaymentButton = Module.extend({
|
|
|
2008
2125
|
},
|
|
2009
2126
|
onDetails(cx, data) {
|
|
2010
2127
|
this.api.scope(() => {
|
|
2011
|
-
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
|
+
});
|
|
2012
2131
|
});
|
|
2013
2132
|
},
|
|
2014
2133
|
onSuccess(cx, data) {
|