swell-js 5.8.1 → 5.9.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.
Files changed (82) hide show
  1. package/dist/api.mjs +51 -39
  2. package/dist/attributes.mjs +2 -3
  3. package/dist/cache.mjs +139 -137
  4. package/dist/card.mjs +147 -145
  5. package/dist/cart.mjs +1 -2
  6. package/dist/categories.mjs +2 -3
  7. package/dist/content.mjs +1 -9
  8. package/dist/cookie.mjs +1 -1
  9. package/dist/{index.a8d5c125.mjs → index.777df7a8.mjs} +2 -14
  10. package/dist/index.mjs +1 -1
  11. package/dist/payment.mjs +296 -118
  12. package/dist/products.mjs +8 -12
  13. package/dist/settings.mjs +1 -1
  14. package/dist/subscriptions.mjs +2 -3
  15. package/dist/swell.cjs +605 -424
  16. package/dist/swell.cjs.map +1 -1
  17. package/dist/swell.umd.min.js +604 -423
  18. package/dist/swell.umd.min.js.map +1 -1
  19. package/dist/utils/index.mjs +1 -1
  20. package/package.json +14 -6
  21. package/types/account/camel.ts +10 -7
  22. package/types/account/index.ts +3 -3
  23. package/types/account/snake.ts +5 -5
  24. package/types/attribute/camel.ts +7 -4
  25. package/types/attribute/index.ts +3 -3
  26. package/types/attribute/snake.ts +2 -2
  27. package/types/billing/camel.ts +4 -4
  28. package/types/billing/index.ts +2 -2
  29. package/types/billing/snake.ts +1 -1
  30. package/types/card/camel.ts +5 -5
  31. package/types/card/index.ts +3 -3
  32. package/types/card/snake.ts +3 -3
  33. package/types/cart/camel.ts +17 -14
  34. package/types/cart/index.ts +3 -3
  35. package/types/cart/snake.ts +12 -12
  36. package/types/category/camel.ts +4 -4
  37. package/types/category/index.ts +3 -3
  38. package/types/category/snake.ts +2 -2
  39. package/types/content/camel.ts +5 -5
  40. package/types/content/index.ts +3 -3
  41. package/types/content/snake.ts +3 -3
  42. package/types/coupon/camel.ts +4 -4
  43. package/types/coupon/index.ts +2 -2
  44. package/types/coupon/snake.ts +2 -2
  45. package/types/currency/camel.ts +2 -2
  46. package/types/currency/index.ts +3 -3
  47. package/types/discount/camel.ts +3 -3
  48. package/types/discount/index.ts +2 -2
  49. package/types/giftcard/camel.ts +10 -7
  50. package/types/giftcard/index.ts +2 -2
  51. package/types/giftcard/snake.ts +5 -5
  52. package/types/index.d.cts +207 -0
  53. package/types/index.d.ts +83 -56
  54. package/types/invoice/camel.ts +10 -10
  55. package/types/invoice/index.ts +3 -3
  56. package/types/invoice/snake.ts +8 -8
  57. package/types/order/camel.ts +18 -15
  58. package/types/order/index.ts +3 -3
  59. package/types/order/snake.ts +18 -13
  60. package/types/payment/camel.ts +13 -10
  61. package/types/payment/index.ts +9 -3
  62. package/types/payment/snake.ts +8 -8
  63. package/types/product/camel.ts +5 -5
  64. package/types/product/index.ts +4 -4
  65. package/types/product/snake.ts +3 -3
  66. package/types/promotion/camel.ts +6 -6
  67. package/types/promotion/index.ts +2 -2
  68. package/types/promotion/snake.ts +4 -4
  69. package/types/purchase_link/camel.ts +10 -7
  70. package/types/purchase_link/index.ts +2 -2
  71. package/types/purchase_link/snake.ts +5 -5
  72. package/types/refund/camel.ts +6 -6
  73. package/types/refund/index.ts +2 -2
  74. package/types/refund/snake.ts +4 -4
  75. package/types/shipment_rating/camel.ts +3 -3
  76. package/types/shipment_rating/index.ts +2 -2
  77. package/types/subscription/camel.ts +16 -13
  78. package/types/subscription/index.ts +3 -3
  79. package/types/subscription/snake.ts +16 -11
  80. package/types/user/camel.ts +2 -2
  81. package/types/user/index.ts +3 -3
  82. package/types/user/snake.ts +1 -1
@@ -9938,8 +9938,6 @@
9938
9938
 
9939
9939
  const LOADING_SCRIPTS = {};
9940
9940
 
9941
- let options = {};
9942
-
9943
9941
  function arrayMerge(target, source, options) {
9944
9942
  const destination = target.slice();
9945
9943
  source.forEach((item, index) => {
@@ -9977,14 +9975,6 @@
9977
9975
  return deepmerge$1(x, y, opt);
9978
9976
  }
9979
9977
 
9980
- function setOptions(optns) {
9981
- options = optns;
9982
- }
9983
-
9984
- function getOptions() {
9985
- return options;
9986
- }
9987
-
9988
9978
  function isObject(val) {
9989
9979
  return val && typeof val === 'object' && !(val instanceof Array);
9990
9980
  }
@@ -10066,7 +10056,7 @@
10066
10056
  };
10067
10057
  }
10068
10058
 
10069
- async function vaultRequest(method, url, data) {
10059
+ async function vaultRequest(method, url, data, options) {
10070
10060
  const { vaultUrl, timeout, key } = options;
10071
10061
  const requestData = {
10072
10062
  $jsonp: {
@@ -10250,7 +10240,6 @@
10250
10240
  findIndex: findIndex,
10251
10241
  get: get,
10252
10242
  getLocationParams: getLocationParams,
10253
- getOptions: getOptions,
10254
10243
  isEmpty: isEmpty,
10255
10244
  isEqual: isEqual,
10256
10245
  isFunction: isFunction,
@@ -10265,7 +10254,6 @@
10265
10254
  removeUrlParams: removeUrlParams,
10266
10255
  round: round$1,
10267
10256
  set: set,
10268
- setOptions: setOptions,
10269
10257
  snakeCase: snakeCase,
10270
10258
  stringifyQuery: stringifyQuery,
10271
10259
  toCamel: toCamel,
@@ -10280,171 +10268,173 @@
10280
10268
  vaultRequest: vaultRequest
10281
10269
  });
10282
10270
 
10283
- const cardApi = {
10284
- async createToken(data) {
10285
- let error = null;
10286
- let code = null;
10287
- let param = null;
10288
- if (!data) {
10289
- error = 'Card details are missing in `swell.card.createToken(card)`';
10290
- param = '';
10291
- }
10292
- const card = toSnake(data);
10293
- if (!card.nonce) {
10294
- if (!this.validateNumber(card.number)) {
10295
- error = 'Card number appears to be invalid';
10296
- code = 'invalid_card_number';
10297
- param = 'number';
10298
- }
10299
- if (card.exp) {
10300
- const exp = this.expiry(card.exp);
10301
- card.exp_month = exp.month;
10302
- card.exp_year = exp.year;
10271
+ function methods$e(options) {
10272
+ return {
10273
+ async createToken(data) {
10274
+ let error = null;
10275
+ let code = null;
10276
+ let param = null;
10277
+ if (!data) {
10278
+ error = 'Card details are missing in `swell.card.createToken(card)`';
10279
+ param = '';
10303
10280
  }
10304
- if (!this.validateExpiry(card.exp_month, card.exp_year)) {
10305
- error = 'Card expiry appears to be invalid';
10306
- code = 'invalid_card_expiry';
10307
- param = 'exp_month';
10281
+ const card = toSnake(data);
10282
+ if (!card.nonce) {
10283
+ if (!this.validateNumber(card.number)) {
10284
+ error = 'Card number appears to be invalid';
10285
+ code = 'invalid_card_number';
10286
+ param = 'number';
10287
+ }
10288
+ if (card.exp) {
10289
+ const exp = this.expiry(card.exp);
10290
+ card.exp_month = exp.month;
10291
+ card.exp_year = exp.year;
10292
+ }
10293
+ if (!this.validateExpiry(card.exp_month, card.exp_year)) {
10294
+ error = 'Card expiry appears to be invalid';
10295
+ code = 'invalid_card_expiry';
10296
+ param = 'exp_month';
10297
+ }
10298
+ if (!this.validateCVC(card.cvc)) {
10299
+ error = 'Card CVC code appears to be invalid';
10300
+ code = 'invalid_card_cvc';
10301
+ param = 'exp_cvc';
10302
+ }
10308
10303
  }
10309
- if (!this.validateCVC(card.cvc)) {
10310
- error = 'Card CVC code appears to be invalid';
10311
- code = 'invalid_card_cvc';
10312
- param = 'exp_cvc';
10304
+
10305
+ if (error) {
10306
+ const err = new Error(error);
10307
+ err.code = code || 'invalid_card';
10308
+ err.status = 402;
10309
+ err.param = param;
10310
+ throw err;
10313
10311
  }
10314
- }
10315
10312
 
10316
- if (error) {
10317
- const err = new Error(error);
10318
- err.code = code || 'invalid_card';
10319
- err.status = 402;
10320
- err.param = param;
10321
- throw err;
10322
- }
10313
+ // Get a token from the vault
10314
+ const result = await vaultRequest('post', '/tokens', card, options);
10315
+ if (result.errors) {
10316
+ const param = Object.keys(result.errors)[0];
10317
+ const err = new Error(result.errors[param].message || 'Unknown error');
10318
+ err.code = 'vault_error';
10319
+ err.status = 402;
10320
+ err.param = param;
10321
+ throw err;
10322
+ }
10323
+ return result;
10324
+ },
10323
10325
 
10324
- // Get a token from the vault
10325
- const result = await vaultRequest('post', '/tokens', card);
10326
- if (result.errors) {
10327
- const param = Object.keys(result.errors)[0];
10328
- const err = new Error(result.errors[param].message || 'Unknown error');
10329
- err.code = 'vault_error';
10330
- err.status = 402;
10331
- err.param = param;
10332
- throw err;
10333
- }
10334
- return result;
10335
- },
10326
+ expiry(value) {
10327
+ if (value && value.month && value.year) {
10328
+ return value;
10329
+ }
10336
10330
 
10337
- expiry(value) {
10338
- if (value && value.month && value.year) {
10339
- return value;
10340
- }
10331
+ const parts = new String(value).split(/[\s/-]+/, 2);
10332
+ const month = parts[0];
10341
10333
 
10342
- const parts = new String(value).split(/[\s/-]+/, 2);
10343
- const month = parts[0];
10334
+ const currentYear = new Date().getUTCFullYear().toString();
10335
+ let strYear = parts[1];
10344
10336
 
10345
- const currentYear = new Date().getUTCFullYear().toString();
10346
- let strYear = parts[1];
10337
+ if (strYear.length < currentYear.length) {
10338
+ let fullYear =
10339
+ currentYear.slice(0, currentYear.length - strYear.length) + strYear;
10347
10340
 
10348
- if (strYear.length < currentYear.length) {
10349
- let fullYear =
10350
- currentYear.slice(0, currentYear.length - strYear.length) + strYear;
10341
+ // If the expiration year is less than the current year,
10342
+ // then the expiration year is in the next century.
10343
+ if (fullYear < currentYear) {
10344
+ let year = Number(fullYear);
10345
+ year += 10 ** strYear.length;
10346
+ fullYear = year.toString();
10347
+ }
10351
10348
 
10352
- // If the expiration year is less than the current year,
10353
- // then the expiration year is in the next century.
10354
- if (fullYear < currentYear) {
10355
- let year = Number(fullYear);
10356
- year += 10 ** strYear.length;
10357
- fullYear = year.toString();
10349
+ strYear = fullYear;
10358
10350
  }
10359
10351
 
10360
- strYear = fullYear;
10361
- }
10352
+ return {
10353
+ month: Number.parseInt(month, 10),
10354
+ year: Number.parseInt(strYear, 10),
10355
+ };
10356
+ },
10362
10357
 
10363
- return {
10364
- month: Number.parseInt(month, 10),
10365
- year: Number.parseInt(strYear, 10),
10366
- };
10367
- },
10368
-
10369
- types() {
10370
- let t = {};
10371
- for (let e = 40; e <= 49; ++e) t[e] = 'Visa';
10372
- for (let e = 50; e <= 59; ++e) t[e] = 'MasterCard';
10373
- t[34] = t[37] = 'American Express';
10374
- t[60] = t[62] = t[64] = t[65] = 'Discover';
10375
- t[35] = 'JCB';
10376
- t[30] = t[36] = t[38] = t[39] = 'Diners Club';
10377
- return t;
10378
- },
10379
-
10380
- type(num) {
10381
- return this.types()[num.slice(0, 2)] || 'Unknown';
10382
- },
10383
-
10384
- luhnCheck(num) {
10385
- const numbers = String(num);
10386
- let odd = false;
10387
- let sum = 0;
10388
-
10389
- for (let i = numbers.length - 1; i >= 0; --i) {
10390
- let digit = Number.parseInt(numbers[i], 10);
10391
-
10392
- if (odd) {
10393
- digit *= 2;
10394
-
10395
- if (digit > 9) {
10396
- digit -= 9;
10358
+ types() {
10359
+ let t = {};
10360
+ for (let e = 40; e <= 49; ++e) t[e] = 'Visa';
10361
+ for (let e = 50; e <= 59; ++e) t[e] = 'MasterCard';
10362
+ t[34] = t[37] = 'American Express';
10363
+ t[60] = t[62] = t[64] = t[65] = 'Discover';
10364
+ t[35] = 'JCB';
10365
+ t[30] = t[36] = t[38] = t[39] = 'Diners Club';
10366
+ return t;
10367
+ },
10368
+
10369
+ type(num) {
10370
+ return this.types()[num.slice(0, 2)] || 'Unknown';
10371
+ },
10372
+
10373
+ luhnCheck(num) {
10374
+ const numbers = String(num);
10375
+ let odd = false;
10376
+ let sum = 0;
10377
+
10378
+ for (let i = numbers.length - 1; i >= 0; --i) {
10379
+ let digit = Number.parseInt(numbers[i], 10);
10380
+
10381
+ if (odd) {
10382
+ digit *= 2;
10383
+
10384
+ if (digit > 9) {
10385
+ digit -= 9;
10386
+ }
10397
10387
  }
10398
- }
10399
10388
 
10400
- sum += digit;
10401
- odd = !odd;
10402
- }
10389
+ sum += digit;
10390
+ odd = !odd;
10391
+ }
10403
10392
 
10404
- return sum % 10 === 0;
10405
- },
10393
+ return sum % 10 === 0;
10394
+ },
10406
10395
 
10407
- validateNumber(num) {
10408
- num = String(num).replace(/\s+|-/g, '');
10396
+ validateNumber(num) {
10397
+ num = String(num).replace(/\s+|-/g, '');
10409
10398
 
10410
- return num.length >= 10 && num.length <= 16 && this.luhnCheck(num);
10411
- },
10399
+ return num.length >= 10 && num.length <= 16 && this.luhnCheck(num);
10400
+ },
10412
10401
 
10413
- validateExpiry(month, year) {
10414
- month = String(month).trim();
10415
- year = String(year).trim();
10402
+ validateExpiry(month, year) {
10403
+ month = String(month).trim();
10404
+ year = String(year).trim();
10416
10405
 
10417
- if (!/^\d+$/.test(month) || !/^\d+$/.test(year)) {
10418
- return false;
10419
- }
10406
+ if (!/^\d+$/.test(month) || !/^\d+$/.test(year)) {
10407
+ return false;
10408
+ }
10420
10409
 
10421
- const numMonth = Number.parseInt(month, 10);
10410
+ const numMonth = Number.parseInt(month, 10);
10422
10411
 
10423
- if (numMonth <= 0 || numMonth > 12) {
10424
- return false;
10425
- }
10412
+ if (numMonth <= 0 || numMonth > 12) {
10413
+ return false;
10414
+ }
10426
10415
 
10427
- const date = new Date(year, month);
10428
- date.setMonth(date.getMonth() - 1);
10429
- date.setMonth(date.getMonth() + 1, 1);
10416
+ const date = new Date(year, month);
10417
+ date.setMonth(date.getMonth() - 1);
10418
+ date.setMonth(date.getMonth() + 1, 1);
10430
10419
 
10431
- const diff = date.getTime() - Date.now();
10420
+ const diff = date.getTime() - Date.now();
10432
10421
 
10433
- // The card has expired
10434
- if (diff < 0) {
10435
- return false;
10436
- }
10422
+ // The card has expired
10423
+ if (diff < 0) {
10424
+ return false;
10425
+ }
10437
10426
 
10438
- // The card's validity period must not exceed 50 years from the current time.
10439
- return Math.round(diff / 31_557_600_000) < 50;
10440
- },
10427
+ // The card's validity period must not exceed 50 years from the current time.
10428
+ return Math.round(diff / 31_557_600_000) < 50;
10429
+ },
10441
10430
 
10442
- validateCVC(val) {
10443
- val = String(val).trim();
10431
+ validateCVC(val) {
10432
+ val = String(val).trim();
10444
10433
 
10445
- return /^\d+$/.test(val) && val.length >= 3 && val.length <= 4;
10446
- },
10447
- };
10434
+ return /^\d+$/.test(val) && val.length >= 3 && val.length <= 4;
10435
+ },
10436
+ };
10437
+ }
10448
10438
 
10449
10439
  const COOKIE_MAX_AGE = 604800; // 1 week
10450
10440
 
@@ -10495,191 +10485,191 @@
10495
10485
 
10496
10486
  const RECORD_TIMEOUT = 5000;
10497
10487
 
10498
- let VALUES = {
10499
- /*
10500
- [model]: {
10501
- [id]: {
10502
- data,
10503
- record,
10504
- recordTimer,
10505
- presets,
10488
+ function methods$d(opt) {
10489
+ let VALUES = {
10490
+ /*
10491
+ [model]: {
10492
+ [id]: {
10493
+ data,
10494
+ record,
10495
+ recordTimer,
10496
+ presets,
10497
+ }
10506
10498
  }
10507
- }
10508
- */
10509
- };
10499
+ */
10500
+ };
10510
10501
 
10511
- const cacheApi = {
10512
- options: {
10513
- enabled: true,
10514
- debug: false,
10515
- },
10502
+ return {
10503
+ options: {
10504
+ enabled: true,
10505
+ debug: false,
10506
+ },
10516
10507
 
10517
- debug(...args) {
10518
- if (this.options.debug) {
10519
- console.log(...args);
10520
- }
10521
- },
10508
+ debug(...args) {
10509
+ if (this.options.debug) {
10510
+ console.log(...args);
10511
+ }
10512
+ },
10522
10513
 
10523
- values({ model, id }, setValues = undefined) {
10524
- this.debug('cache.values', ...arguments);
10525
- if (setValues !== undefined) {
10526
- for (let key in setValues) {
10527
- set(VALUES, `${model}.${id}.${key}`, setValues[key]);
10514
+ values({ model, id }, setValues = undefined) {
10515
+ this.debug('cache.values', ...arguments);
10516
+ if (setValues !== undefined) {
10517
+ for (let key in setValues) {
10518
+ set(VALUES, `${model}.${id}.${key}`, setValues[key]);
10519
+ }
10520
+ return;
10528
10521
  }
10529
- return;
10530
- }
10531
- return get(VALUES, `${model}.${id}`, {});
10532
- },
10522
+ return get(VALUES, `${model}.${id}`, {});
10523
+ },
10533
10524
 
10534
- preset(details) {
10535
- this.debug('cache.preset', ...arguments);
10536
- const { presets = [] } = this.values(details);
10537
- presets.push(details);
10538
- this.values(details, { presets });
10539
- },
10525
+ preset(details) {
10526
+ this.debug('cache.preset', ...arguments);
10527
+ const { presets = [] } = this.values(details);
10528
+ presets.push(details);
10529
+ this.values(details, { presets });
10530
+ },
10540
10531
 
10541
- set(details) {
10542
- this.debug('cache.set', ...arguments);
10543
- let { model, id, path, value } = details;
10544
- let { data = {}, record } = this.values(details);
10532
+ set(details) {
10533
+ this.debug('cache.set', ...arguments);
10534
+ let { model, id, path, value } = details;
10535
+ let { data = {}, record } = this.values(details);
10545
10536
 
10546
- if (id === null) {
10547
- return;
10548
- }
10537
+ if (id === null) {
10538
+ return;
10539
+ }
10549
10540
 
10550
- if (record === undefined) {
10551
- return this.preset(details);
10552
- }
10541
+ if (record === undefined) {
10542
+ return this.preset(details);
10543
+ }
10553
10544
 
10554
- data = merge(record || {}, data);
10545
+ data = merge(record || {}, data);
10555
10546
 
10556
- const { useCamelCase } = getOptions();
10557
- if (useCamelCase && value && typeof value === 'object') {
10558
- value = toCamel(value);
10559
- }
10547
+ const { useCamelCase } = opt;
10548
+ if (useCamelCase && value && typeof value === 'object') {
10549
+ value = toCamel(value);
10550
+ }
10560
10551
 
10561
- if (path || value instanceof Array) {
10562
- let upData = { ...(data || {}) };
10563
- let upPath = useCamelCase ? toCamelPath(path) : path;
10564
- set(upData, upPath || '', value);
10565
- data = upData;
10566
- } else if (value && typeof value === 'object') {
10567
- data = data || {};
10568
- data = merge(data, value);
10569
- } else {
10570
- data = value;
10571
- }
10552
+ if (path || value instanceof Array) {
10553
+ let upData = { ...(data || {}) };
10554
+ let upPath = useCamelCase ? toCamelPath(path) : path;
10555
+ set(upData, upPath || '', value);
10556
+ data = upData;
10557
+ } else if (value && typeof value === 'object') {
10558
+ data = data || {};
10559
+ data = merge(data, value);
10560
+ } else {
10561
+ data = value;
10562
+ }
10572
10563
 
10573
- this.values(details, { data });
10564
+ this.values(details, { data });
10574
10565
 
10575
- try {
10576
- // Make sure values have clean refs
10577
- const cache = VALUES[model][id];
10578
- if (cache !== undefined) {
10579
- if (cache.data !== undefined) {
10580
- cache.data = JSON.parse(JSON.stringify(cache.data));
10581
- }
10582
- if (cache.record !== undefined) {
10583
- cache.record = JSON.parse(JSON.stringify(cache.record));
10566
+ try {
10567
+ // Make sure values have clean refs
10568
+ const cache = VALUES[model][id];
10569
+ if (cache !== undefined) {
10570
+ if (cache.data !== undefined) {
10571
+ cache.data = JSON.parse(JSON.stringify(cache.data));
10572
+ }
10573
+ if (cache.record !== undefined) {
10574
+ cache.record = JSON.parse(JSON.stringify(cache.record));
10575
+ }
10584
10576
  }
10577
+ } catch (err) {
10578
+ // noop
10585
10579
  }
10586
- } catch (err) {
10587
- // noop
10588
- }
10589
- },
10580
+ },
10590
10581
 
10591
- get(model, id) {
10592
- this.debug('cache.get', ...arguments);
10593
- const { data, recordTimer } = this.values({ model, id });
10594
- this.debug('cache.get:data+recordTimer', ...arguments);
10595
- if (recordTimer) {
10596
- return data;
10597
- }
10598
- },
10582
+ get(model, id) {
10583
+ this.debug('cache.get', ...arguments);
10584
+ const { data, recordTimer } = this.values({ model, id });
10585
+ this.debug('cache.get:data+recordTimer', ...arguments);
10586
+ if (recordTimer) {
10587
+ return data;
10588
+ }
10589
+ },
10599
10590
 
10600
- setRecord(record, details) {
10601
- this.debug('cache.setRecord', ...arguments);
10602
- let { recordTimer, presets } = this.values(details);
10591
+ setRecord(record, details) {
10592
+ this.debug('cache.setRecord', ...arguments);
10593
+ let { recordTimer, presets } = this.values(details);
10603
10594
 
10604
- if (recordTimer) {
10605
- clearTimeout(recordTimer);
10606
- }
10595
+ if (recordTimer) {
10596
+ clearTimeout(recordTimer);
10597
+ }
10607
10598
 
10608
- recordTimer = setTimeout(() => {
10609
- this.values(details, { record: undefined, recordTimer: undefined });
10610
- }, RECORD_TIMEOUT);
10599
+ recordTimer = setTimeout(() => {
10600
+ this.values(details, { record: undefined, recordTimer: undefined });
10601
+ }, RECORD_TIMEOUT);
10611
10602
 
10612
- // Record has to be null at minimum, not undefined
10613
- this.values(details, {
10614
- record: record !== undefined ? record : null,
10615
- recordTimer,
10616
- });
10603
+ // Record has to be null at minimum, not undefined
10604
+ this.values(details, {
10605
+ record: record !== undefined ? record : null,
10606
+ recordTimer,
10607
+ });
10617
10608
 
10618
- if (presets) {
10619
- for (let preset of presets) {
10620
- this.set(preset);
10609
+ if (presets) {
10610
+ for (let preset of presets) {
10611
+ this.set(preset);
10612
+ }
10613
+ this.values(details, { presets: undefined });
10621
10614
  }
10622
- this.values(details, { presets: undefined });
10623
- }
10624
10615
 
10625
- const result = this.get(details.model, details.id);
10616
+ const result = this.get(details.model, details.id);
10626
10617
 
10627
- return result !== undefined ? result : record;
10628
- },
10618
+ return result !== undefined ? result : record;
10619
+ },
10629
10620
 
10630
- async getFetch(model, id, fetch) {
10631
- if (this.options.enabled) {
10632
- this.debug('cache.getFetch', ...arguments);
10633
- const value = this.get(model, id);
10621
+ async getFetch(model, id, fetch) {
10622
+ if (this.options.enabled) {
10623
+ this.debug('cache.getFetch', ...arguments);
10624
+ const value = this.get(model, id);
10634
10625
 
10635
- if (value !== undefined) {
10636
- return value;
10626
+ if (value !== undefined) {
10627
+ return value;
10628
+ }
10637
10629
  }
10638
- }
10639
10630
 
10640
- const record = await fetch();
10641
- return this.setRecord(record, { model, id });
10642
- },
10631
+ const record = await fetch();
10632
+ return this.setRecord(record, { model, id });
10633
+ },
10643
10634
 
10644
- clear(model = undefined, id = undefined) {
10645
- this.debug('cache.clear', ...arguments);
10646
- if (model) {
10647
- if (id) {
10648
- set(VALUES, `${model}.${id}`, undefined);
10635
+ clear(model = undefined, id = undefined) {
10636
+ this.debug('cache.clear', ...arguments);
10637
+ if (model) {
10638
+ if (id) {
10639
+ set(VALUES, `${model}.${id}`, undefined);
10640
+ } else {
10641
+ set(VALUES, model, undefined);
10642
+ }
10649
10643
  } else {
10650
- set(VALUES, model, undefined);
10644
+ VALUES = {};
10651
10645
  }
10652
- } else {
10653
- VALUES = {};
10654
- }
10655
- },
10656
- };
10646
+ },
10647
+ };
10648
+ }
10657
10649
 
10658
10650
  function methods$c(api) {
10659
10651
  const { get, list } = defaultMethods(api, '/attributes', ['list', 'get']);
10660
10652
 
10661
10653
  return {
10662
10654
  get: (id, ...args) => {
10663
- return cacheApi.getFetch('attributes', id, () => get(id, ...args));
10655
+ return api.cache.getFetch('attributes', id, () => get(id, ...args));
10664
10656
  },
10665
10657
 
10666
10658
  list,
10667
10659
  };
10668
10660
  }
10669
10661
 
10670
- let OPTIONS;
10671
-
10672
10662
  function methods$b(api, opt) {
10673
- OPTIONS = opt;
10674
10663
  const { get, list } = defaultMethods(api, '/products', ['list', 'get']);
10675
10664
  return {
10676
10665
  get: (id, ...args) => {
10677
- return cacheApi.getFetch('products', id, () => get(id, ...args));
10666
+ return api.cache.getFetch('products', id, () => get(id, ...args));
10678
10667
  },
10679
10668
 
10680
10669
  list,
10681
10670
 
10682
- variation: calculateVariation,
10671
+ variation: (input, options, purchaseOption) =>
10672
+ calculateVariation(input, options, purchaseOption, opt),
10683
10673
 
10684
10674
  categories: getCategories,
10685
10675
 
@@ -10759,8 +10749,8 @@
10759
10749
  return null;
10760
10750
  }
10761
10751
 
10762
- function calculateVariation(input, options, purchaseOption) {
10763
- const product = OPTIONS.useCamelCase ? toSnake(input) : input;
10752
+ function calculateVariation(input, options, purchaseOption, opt) {
10753
+ const product = opt.useCamelCase ? toSnake(input) : input;
10764
10754
  const purchaseOp = findPurchaseOption(product, purchaseOption);
10765
10755
  const variation = {
10766
10756
  ...product,
@@ -10823,7 +10813,7 @@
10823
10813
  if (variation.orig_price === undefined) {
10824
10814
  delete variation.orig_price;
10825
10815
  }
10826
- return OPTIONS.useCamelCase ? toCamel(variation) : variation;
10816
+ return opt.useCamelCase ? toCamel(variation) : variation;
10827
10817
  }
10828
10818
 
10829
10819
  function findPurchaseOption(product, purchaseOption) {
@@ -10878,8 +10868,7 @@
10878
10868
  }
10879
10869
 
10880
10870
  async function getFilterableAttributeFilters(api, products, options) {
10881
- const { results: filterableAttributes } = await methods$c(
10882
- api).list({
10871
+ const { results: filterableAttributes } = await methods$c(api).list({
10883
10872
  filterable: true,
10884
10873
  });
10885
10874
 
@@ -11486,19 +11475,29 @@
11486
11475
  }
11487
11476
 
11488
11477
  #getIntent(data) {
11489
- return vaultRequest('GET', '/intent', {
11490
- gateway: this.#gateway,
11491
- account_id: this.#accountId,
11492
- intent: data,
11493
- });
11478
+ return vaultRequest(
11479
+ 'GET',
11480
+ '/intent',
11481
+ {
11482
+ gateway: this.#gateway,
11483
+ account_id: this.#accountId,
11484
+ intent: data,
11485
+ },
11486
+ this.options,
11487
+ );
11494
11488
  }
11495
11489
 
11496
11490
  #createIntent(data) {
11497
- return vaultRequest('POST', '/intent', {
11498
- gateway: this.#gateway,
11499
- account_id: this.#accountId,
11500
- intent: data,
11501
- });
11491
+ return vaultRequest(
11492
+ 'POST',
11493
+ '/intent',
11494
+ {
11495
+ gateway: this.#gateway,
11496
+ account_id: this.#accountId,
11497
+ intent: data,
11498
+ },
11499
+ this.options,
11500
+ );
11502
11501
  }
11503
11502
  }
11504
11503
 
@@ -11653,7 +11652,7 @@
11653
11652
 
11654
11653
  return {
11655
11654
  get: (id, ...args) => {
11656
- return cacheApi.getFetch('categories', id, () => get(id, ...args));
11655
+ return api.cache.getFetch('categories', id, () => get(id, ...args));
11657
11656
  },
11658
11657
 
11659
11658
  list,
@@ -11664,7 +11663,7 @@
11664
11663
  const { get, list } = defaultMethods(api, '/subscriptions', ['list', 'get']);
11665
11664
  return {
11666
11665
  get: (id, ...args) => {
11667
- return cacheApi.getFetch('subscriptions', id, () => get(id, ...args));
11666
+ return api.cache.getFetch('subscriptions', id, () => get(id, ...args));
11668
11667
  },
11669
11668
 
11670
11669
  list,
@@ -11729,7 +11728,7 @@
11729
11728
  const { get, list } = defaultMethods(api, '/invoices', ['list', 'get']);
11730
11729
  return {
11731
11730
  get: (id, ...args) => {
11732
- return cacheApi.getFetch('invoices', id, () => get(id, ...args));
11731
+ return api.cache.getFetch('invoices', id, () => get(id, ...args));
11733
11732
  },
11734
11733
 
11735
11734
  list,
@@ -11739,7 +11738,7 @@
11739
11738
  function methods$5(api, opt) {
11740
11739
  return {
11741
11740
  get: (type, id, query) => {
11742
- return cacheApi.getFetch(`content_${type}`, id, () =>
11741
+ return api.cache.getFetch(`content_${type}`, id, () =>
11743
11742
  api.request('get', `/content/${type}`, id, {
11744
11743
  $preview: opt.previewContent,
11745
11744
  ...(query || {}),
@@ -12110,13 +12109,18 @@
12110
12109
 
12111
12110
  async function loadPaypal(params) {
12112
12111
  if (!window.paypal) {
12113
- const { currency, client_id, merchant_id } = params;
12112
+ const { vault, currency, client_id, merchant_id } = params;
12113
+
12114
12114
  const paypalParams = {
12115
12115
  currency,
12116
12116
  'client-id': client_id,
12117
12117
  commit: false,
12118
12118
  };
12119
12119
 
12120
+ if (vault) {
12121
+ paypalParams.vault = vault;
12122
+ }
12123
+
12120
12124
  if (merchant_id) {
12121
12125
  // paypal express and ppcp onboarded
12122
12126
  paypalParams['merchant-id'] = merchant_id;
@@ -12481,7 +12485,7 @@
12481
12485
  * @returns {Promise<object>}
12482
12486
  */
12483
12487
  async createIntent(data) {
12484
- return vaultRequest('post', '/intent', data);
12488
+ return vaultRequest('post', '/intent', data, this.options);
12485
12489
  }
12486
12490
 
12487
12491
  /**
@@ -12491,7 +12495,7 @@
12491
12495
  * @returns {Promise<object>}
12492
12496
  */
12493
12497
  async updateIntent(data) {
12494
- return vaultRequest('put', '/intent', data);
12498
+ return vaultRequest('put', '/intent', data, this.options);
12495
12499
  }
12496
12500
 
12497
12501
  /**
@@ -12501,7 +12505,7 @@
12501
12505
  * @returns {Promise<object>}
12502
12506
  */
12503
12507
  async authorizeGateway(data) {
12504
- return vaultRequest('post', '/authorization', data);
12508
+ return vaultRequest('post', '/authorization', data, this.options);
12505
12509
  }
12506
12510
 
12507
12511
  /**
@@ -14243,7 +14247,7 @@
14243
14247
 
14244
14248
  // Update cart with new shipping address and force tax recalculation
14245
14249
  let cart = await this.updateCart({
14246
- shipping: convertToSwellAddress$2(
14250
+ shipping: convertToSwellAddress$3(
14247
14251
  intermediatePaymentData.shippingAddress,
14248
14252
  ),
14249
14253
  });
@@ -14509,7 +14513,7 @@
14509
14513
  * @param {google.payments.api.Address} address
14510
14514
  * @returns {Address}
14511
14515
  */
14512
- function convertToSwellAddress$2(address) {
14516
+ function convertToSwellAddress$3(address) {
14513
14517
  return {
14514
14518
  name: address.name,
14515
14519
  address1: address.address1,
@@ -14773,11 +14777,11 @@
14773
14777
  nonce,
14774
14778
  gateway: 'braintree',
14775
14779
  },
14776
- ...convertToSwellAddress$2(billingAddress),
14780
+ ...convertToSwellAddress$3(billingAddress),
14777
14781
  },
14778
14782
  ...(shippingAddress && {
14779
14783
  shipping: {
14780
- ...convertToSwellAddress$2(shippingAddress),
14784
+ ...convertToSwellAddress$3(shippingAddress),
14781
14785
  service: shippingOptionData?.id || undefined,
14782
14786
  },
14783
14787
  }),
@@ -14785,7 +14789,7 @@
14785
14789
 
14786
14790
  if (cart.subscription_delivery) {
14787
14791
  try {
14788
- const card = await cardApi.createToken({
14792
+ const card = await this.api.card.createToken({
14789
14793
  gateway: 'braintree',
14790
14794
  account_id: cart.account_id,
14791
14795
  nonce,
@@ -14814,6 +14818,7 @@
14814
14818
  /** @typedef {import('./payment').default} Payment */
14815
14819
  /** @typedef {import('../../types').Cart} Cart */
14816
14820
  /** @typedef {import('../../types').Address} Address */
14821
+ /** @typedef {import('../../types').CartItemBillingSchedule} CartItemBillingSchedule */
14817
14822
 
14818
14823
  /**
14819
14824
  * @this {Payment}
@@ -14825,7 +14830,7 @@
14825
14830
  // Update cart with Apple Pay shipping address to get shipping options and tax
14826
14831
  // This happens immediately when the sheet opens with the default address
14827
14832
  const cart = await this.updateCart({
14828
- shipping: convertToSwellAddress$1(shippingContact),
14833
+ shipping: convertToSwellAddress$2(shippingContact),
14829
14834
  });
14830
14835
 
14831
14836
  if (!cart.shipment_rating?.services?.length) {
@@ -15114,7 +15119,7 @@
15114
15119
  * @param {ApplePayJS.ApplePayPaymentContact} [address]
15115
15120
  * @returns {Address}
15116
15121
  */
15117
- function convertToSwellAddress$1(address = {}) {
15122
+ function convertToSwellAddress$2(address = {}) {
15118
15123
  return {
15119
15124
  first_name: address.givenName,
15120
15125
  last_name: address.familyName,
@@ -15157,6 +15162,99 @@
15157
15162
  return { requiredBillingContactFields, requiredShippingContactFields };
15158
15163
  }
15159
15164
 
15165
+ /**
15166
+ * @param {CartItemBillingSchedule} schedule
15167
+ * @returns {{ intervalUnit: ApplePayJS.ApplePayRecurringPaymentDateUnit, intervalCount: number }}
15168
+ */
15169
+ function convertSwellScheduleToAppleRecurringInterval(schedule) {
15170
+ let intervalCount = schedule.interval_count || 1;
15171
+ let intervalUnit = 'day';
15172
+
15173
+ switch (schedule.interval) {
15174
+ case 'daily':
15175
+ intervalUnit = 'day';
15176
+ break;
15177
+
15178
+ case 'weekly':
15179
+ intervalUnit = 'day';
15180
+ intervalCount *= 7;
15181
+ break;
15182
+
15183
+ case 'monthly':
15184
+ intervalUnit = 'month';
15185
+ break;
15186
+
15187
+ case 'yearly':
15188
+ intervalUnit = 'year';
15189
+ break;
15190
+ }
15191
+
15192
+ return { intervalUnit, intervalCount };
15193
+ }
15194
+
15195
+ /**
15196
+ * @param {Cart} cart
15197
+ * @param {string} managementUrl
15198
+ * @returns {ApplePayJS.ApplePayRecurringPaymentRequest | undefined}
15199
+ */
15200
+ function getRecurringPaymentRequest(cart, managementUrl) {
15201
+ if (!cart.subscription_delivery) {
15202
+ return undefined;
15203
+ }
15204
+
15205
+ const item = cart.items.find(
15206
+ (item) =>
15207
+ item.purchase_option?.type === 'subscription' &&
15208
+ item.purchase_option.billing_schedule,
15209
+ );
15210
+
15211
+ if (item === undefined) {
15212
+ return undefined;
15213
+ }
15214
+
15215
+ const { intervalUnit, intervalCount } =
15216
+ convertSwellScheduleToAppleRecurringInterval(
15217
+ item.purchase_option.billing_schedule,
15218
+ );
15219
+
15220
+ /** @type {ApplePayJS.ApplePayRecurringPaymentRequest} */
15221
+ const recurringPaymentRequest = {
15222
+ paymentDescription:
15223
+ item.purchase_option.plan_description ||
15224
+ item.purchase_option.plan_name ||
15225
+ item.product_name ||
15226
+ item.product?.name,
15227
+ regularBilling: {
15228
+ type: 'final',
15229
+ label: item.purchase_option.plan_name || 'Subscription',
15230
+ // Calculate the subscription price manually if a trial period is specified.
15231
+ // However, discounts are not included in the calculation due to the difficulty of taking into account all scenarios.
15232
+ amount: (item.purchase_option.billing_schedule.trial_days
15233
+ ? (item.price || 0) * (item.quantity || 1)
15234
+ : item.price_total
15235
+ ).toFixed(2),
15236
+ paymentTiming: 'recurring',
15237
+ recurringPaymentIntervalUnit: intervalUnit,
15238
+ recurringPaymentIntervalCount: intervalCount,
15239
+ },
15240
+ trialBilling: item.purchase_option.billing_schedule.trial_days
15241
+ ? {
15242
+ type: 'final',
15243
+ label: 'Trial',
15244
+ // When a trial period is set, price_total is 0 (usually)
15245
+ amount: Number(item.price_total || 0).toFixed(2),
15246
+ paymentTiming: 'recurring',
15247
+ recurringPaymentIntervalUnit: 'day',
15248
+ recurringPaymentIntervalCount:
15249
+ item.purchase_option.billing_schedule.trial_days,
15250
+ }
15251
+ : undefined,
15252
+ managementURL: managementUrl,
15253
+ };
15254
+
15255
+ return recurringPaymentRequest;
15256
+ }
15257
+
15160
15258
  /** @typedef {import('../../../types').Cart} Cart */
15161
15259
 
15162
15260
  const VERSION$1 = 14;
@@ -15359,16 +15457,16 @@
15359
15457
  nonce: payload.nonce,
15360
15458
  gateway: 'braintree',
15361
15459
  },
15362
- ...convertToSwellAddress$1(billingContact),
15460
+ ...convertToSwellAddress$2(billingContact),
15363
15461
  },
15364
15462
  ...(shippingContact && {
15365
- shipping: convertToSwellAddress$1(shippingContact),
15463
+ shipping: convertToSwellAddress$2(shippingContact),
15366
15464
  }),
15367
15465
  });
15368
15466
 
15369
15467
  if (cart.subscription_delivery) {
15370
15468
  try {
15371
- const card = await cardApi.createToken({
15469
+ const card = await this.api.card.createToken({
15372
15470
  gateway: 'braintree',
15373
15471
  account_id: cart.account_id,
15374
15472
  nonce: payload.nonce,
@@ -15568,7 +15666,7 @@
15568
15666
  * @returns {Promise<object>}
15569
15667
  */
15570
15668
  // eslint-disable-next-line no-unused-vars
15571
- async preparePaymentDataForCartUpdate(paymentData) {
15669
+ async processPaymentData(paymentData) {
15572
15670
  throw new Error('Implement this!');
15573
15671
  }
15574
15672
 
@@ -15590,9 +15688,7 @@
15590
15688
  throw new Error('Google Pay token is missing');
15591
15689
  }
15592
15690
 
15593
- await this.preparePaymentDataForCartUpdate(paymentData).then((data) =>
15594
- this.updateCart(data),
15595
- );
15691
+ await this.processPaymentData(paymentData);
15596
15692
 
15597
15693
  this.onSuccess();
15598
15694
  }
@@ -15715,7 +15811,7 @@
15715
15811
  * @param {google.payments.api.PaymentData} paymentData
15716
15812
  * @returns {Promise<object>}
15717
15813
  */
15718
- async preparePaymentDataForCartUpdate(paymentData) {
15814
+ async processPaymentData(paymentData) {
15719
15815
  const { email, shippingAddress, shippingOptionData, paymentMethodData } =
15720
15816
  paymentData;
15721
15817
 
@@ -15724,7 +15820,7 @@
15724
15820
  tokenizationData: { token },
15725
15821
  } = paymentMethodData;
15726
15822
 
15727
- return {
15823
+ await this.updateCart({
15728
15824
  account: { email },
15729
15825
  billing: {
15730
15826
  method: 'google',
@@ -15734,15 +15830,15 @@
15734
15830
  gateway: 'authorizenet',
15735
15831
  token: base64Encode(token),
15736
15832
  },
15737
- ...convertToSwellAddress$2(billingAddress),
15833
+ ...convertToSwellAddress$3(billingAddress),
15738
15834
  },
15739
15835
  ...(shippingAddress && {
15740
15836
  shipping: {
15741
- ...convertToSwellAddress$2(shippingAddress),
15837
+ ...convertToSwellAddress$3(shippingAddress),
15742
15838
  service: shippingOptionData?.id || undefined,
15743
15839
  },
15744
15840
  }),
15745
- };
15841
+ });
15746
15842
  }
15747
15843
  }
15748
15844
 
@@ -15857,6 +15953,10 @@
15857
15953
  requiredShippingContactFields,
15858
15954
  requiredBillingContactFields,
15859
15955
  supportsCouponCode: true,
15956
+ recurringPaymentRequest: getRecurringPaymentRequest(
15957
+ cart,
15958
+ this.params.managementUrl,
15959
+ ),
15860
15960
  lineItems: getLineItems(cart),
15861
15961
  };
15862
15962
  }
@@ -15879,7 +15979,7 @@
15879
15979
  * @returns {Promise<object>}
15880
15980
  */
15881
15981
  // eslint-disable-next-line no-unused-vars
15882
- async preparePaymentDataForCartUpdate(event) {
15982
+ async processPaymentData(event) {
15883
15983
  throw new Error('Implement this!');
15884
15984
  }
15885
15985
 
@@ -15937,9 +16037,7 @@
15937
16037
  //
15938
16038
  // We store the payment token but DO NOT process the order yet.
15939
16039
  // The user must manually click "Place Order" to complete the transaction.
15940
- await this.preparePaymentDataForCartUpdate(event).then((data) =>
15941
- this.updateCart(data),
15942
- );
16040
+ await this.processPaymentData(event);
15943
16041
 
15944
16042
  // Complete Apple Pay session successfully
15945
16043
  // This closes the Apple Pay sheet and shows success to the user
@@ -16075,12 +16173,12 @@
16075
16173
  * @param {ApplePayJS.ApplePayPaymentAuthorizedEvent} event
16076
16174
  * @returns {Promise<object>}
16077
16175
  */
16078
- async preparePaymentDataForCartUpdate(event) {
16176
+ async processPaymentData(event) {
16079
16177
  const {
16080
16178
  payment: { token, shippingContact, billingContact },
16081
16179
  } = event;
16082
16180
 
16083
- return {
16181
+ return this.updateCart({
16084
16182
  account: {
16085
16183
  email: shippingContact?.emailAddress || billingContact?.emailAddress,
16086
16184
  },
@@ -16092,12 +16190,12 @@
16092
16190
  gateway: 'authorizenet',
16093
16191
  token: base64Encode(JSON.stringify(token.paymentData)),
16094
16192
  },
16095
- ...convertToSwellAddress$1(billingContact),
16193
+ ...convertToSwellAddress$2(billingContact),
16096
16194
  },
16097
16195
  ...(shippingContact && {
16098
- shipping: convertToSwellAddress$1(shippingContact),
16196
+ shipping: convertToSwellAddress$2(shippingContact),
16099
16197
  }),
16100
- };
16198
+ });
16101
16199
  }
16102
16200
  }
16103
16201
 
@@ -16274,7 +16372,7 @@
16274
16372
  ''
16275
16373
  ).replace(/[^0-9]+/g, '');
16276
16374
 
16277
- const cardExpiry = cardApi.expiry(
16375
+ const cardExpiry = this.api.card.expiry(
16278
16376
  this.params.exp ||
16279
16377
  document.getElementById(
16280
16378
  this.params.cardExpiry?.elementId || 'cardExpiry-element',
@@ -16298,7 +16396,7 @@
16298
16396
  ''
16299
16397
  ).trim();
16300
16398
 
16301
- const cardBrand = cardApi.type(cardNumber).toLowerCase();
16399
+ const cardBrand = this.api.card.type(cardNumber).toLowerCase();
16302
16400
 
16303
16401
  const payment = await createConvesioCardPaymentToken(this.method, {
16304
16402
  paymentMethod: {
@@ -16465,7 +16563,7 @@
16465
16563
  * @param {ApplePayJS.ApplePayPaymentAuthorizedEvent} event
16466
16564
  * @returns {Promise<object>}
16467
16565
  */
16468
- async preparePaymentDataForCartUpdate(event) {
16566
+ async processPaymentData(event) {
16469
16567
  const {
16470
16568
  payment: { token, shippingContact, billingContact },
16471
16569
  } = event;
@@ -16489,7 +16587,7 @@
16489
16587
  },
16490
16588
  );
16491
16589
 
16492
- return {
16590
+ return this.updateCart({
16493
16591
  account: {
16494
16592
  email: shippingContact?.emailAddress || billingContact?.emailAddress,
16495
16593
  },
@@ -16504,12 +16602,12 @@
16504
16602
  convesiopay: {
16505
16603
  return_url: this.params.returnUrl,
16506
16604
  },
16507
- ...convertToSwellAddress$1(billingContact),
16605
+ ...convertToSwellAddress$2(billingContact),
16508
16606
  },
16509
16607
  ...(shippingContact && {
16510
- shipping: convertToSwellAddress$1(shippingContact),
16608
+ shipping: convertToSwellAddress$2(shippingContact),
16511
16609
  }),
16512
- };
16610
+ });
16513
16611
  }
16514
16612
  }
16515
16613
 
@@ -16635,7 +16733,7 @@
16635
16733
  * @param {google.payments.api.PaymentData} paymentData
16636
16734
  * @returns {Promise<object>}
16637
16735
  */
16638
- async preparePaymentDataForCartUpdate(paymentData) {
16736
+ async processPaymentData(paymentData) {
16639
16737
  const { email, shippingAddress, shippingOptionData, paymentMethodData } =
16640
16738
  paymentData;
16641
16739
 
@@ -16663,7 +16761,7 @@
16663
16761
  },
16664
16762
  );
16665
16763
 
16666
- return {
16764
+ return this.updateCart({
16667
16765
  account: { email },
16668
16766
  billing: {
16669
16767
  method: 'google',
@@ -16676,15 +16774,15 @@
16676
16774
  convesiopay: {
16677
16775
  return_url: this.params.returnUrl,
16678
16776
  },
16679
- ...convertToSwellAddress$2(billingAddress),
16777
+ ...convertToSwellAddress$3(billingAddress),
16680
16778
  },
16681
16779
  ...(shippingAddress && {
16682
16780
  shipping: {
16683
- ...convertToSwellAddress$2(shippingAddress),
16781
+ ...convertToSwellAddress$3(shippingAddress),
16684
16782
  service: shippingOptionData?.id || undefined,
16685
16783
  },
16686
16784
  }),
16687
- };
16785
+ });
16688
16786
  }
16689
16787
  }
16690
16788
 
@@ -16887,12 +16985,26 @@
16887
16985
  };
16888
16986
  }
16889
16987
 
16988
+ /** @typedef {import('@paypal/paypal-js').PayPalNamespace} PayPal */
16989
+ /** @typedef {import('@paypal/paypal-js').ShippingAddress} ShippingAddress */
16990
+ /** @typedef {import('@paypal/paypal-js').CreateOrderData} CreateOrderData */
16991
+ /** @typedef {import('@paypal/paypal-js').CreateOrderActions} CreateOrderActions */
16992
+ /** @typedef {import('@paypal/paypal-js').OnShippingAddressChangeData} OnShippingAddressChangeData */
16993
+ /** @typedef {import('@paypal/paypal-js').OnShippingAddressChangeActions} OnShippingAddressChangeActions */
16994
+ /** @typedef {import('@paypal/paypal-js').OnShippingOptionsChangeData} OnShippingOptionsChangeData */
16995
+ /** @typedef {import('@paypal/paypal-js').OnShippingOptionsChangeActions} OnShippingOptionsChangeActions */
16996
+ /** @typedef {import('@paypal/paypal-js').OnApproveData} OnApproveData */
16997
+ /** @typedef {import('@paypal/paypal-js').OnApproveActions} OnApproveActions */
16998
+ /** @typedef {import('../../../types').Cart} Cart */
16999
+ /** @typedef {import('../../../types').Address} Address */
17000
+
16890
17001
  class PaypalDirectPayment extends Payment {
16891
17002
  constructor(api, options, params, methods) {
16892
17003
  super(api, options, params, methods.paypal);
16893
17004
  }
16894
17005
 
16895
- get scripts() {
17006
+ /** @param {Cart} cart */
17007
+ getScripts(cart) {
16896
17008
  const { client_id } = this.method;
16897
17009
 
16898
17010
  return [
@@ -16902,11 +17014,13 @@
16902
17014
  client_id,
16903
17015
  merchant_id: this.merchantId,
16904
17016
  cart: ['currency'],
17017
+ vault: cart.subscription_delivery,
16905
17018
  },
16906
17019
  },
16907
17020
  ];
16908
17021
  }
16909
17022
 
17023
+ /** @returns {PayPal} */
16910
17024
  get paypal() {
16911
17025
  if (!window.paypal) {
16912
17026
  throw new LibraryNotLoadedError('PayPal');
@@ -16930,7 +17044,6 @@
16930
17044
  async createElements(cart) {
16931
17045
  const {
16932
17046
  elementId = 'paypal-button',
16933
- locale = 'en_US',
16934
17047
  style: {
16935
17048
  layout = 'horizontal',
16936
17049
  height = 45,
@@ -16939,15 +17052,16 @@
16939
17052
  label = 'paypal',
16940
17053
  tagline = false,
16941
17054
  } = {},
17055
+ require: { shipping: requireShipping = true } = {},
16942
17056
  } = this.params;
16943
17057
 
16944
17058
  this.setElementContainer(elementId);
16945
17059
 
16946
17060
  this._validateCart(cart);
16947
- await this.loadScripts(this.scripts);
17061
+ await this.loadScripts(this.getScripts(cart));
16948
17062
 
16949
- this.element = this.paypal.Buttons({
16950
- locale,
17063
+ /** @type {import('@paypal/paypal-js').PayPalButtonsComponentOptions} */
17064
+ const buttonsOptions = {
16951
17065
  style: {
16952
17066
  layout,
16953
17067
  height,
@@ -16956,11 +17070,27 @@
16956
17070
  label,
16957
17071
  tagline,
16958
17072
  },
17073
+ fundingSource: this.paypal.FUNDING.PAYPAL,
16959
17074
  createOrder: this._onCreateOrder.bind(this, cart),
16960
- onShippingChange: this._onShippingChange.bind(this),
16961
17075
  onApprove: this._onApprove.bind(this),
16962
17076
  onError: this.onError.bind(this),
16963
- });
17077
+ };
17078
+
17079
+ if (requireShipping) {
17080
+ buttonsOptions.onShippingAddressChange =
17081
+ this._onShippingAddressChange.bind(this);
17082
+
17083
+ buttonsOptions.onShippingOptionsChange =
17084
+ this._onShippingOptionsChange.bind(this);
17085
+ }
17086
+
17087
+ const component = this.paypal.Buttons(buttonsOptions);
17088
+
17089
+ if (!component.isEligible()) {
17090
+ throw new Error('PayPal button with provided options is not eligible.');
17091
+ }
17092
+
17093
+ this.element = component;
16964
17094
  }
16965
17095
 
16966
17096
  mountElements() {
@@ -16974,6 +17104,7 @@
16974
17104
  }
16975
17105
  }
16976
17106
 
17107
+ /** @param {Cart} cart */
16977
17108
  _validateCart(cart) {
16978
17109
  const hasSubscriptionProduct = Boolean(cart.subscription_delivery);
16979
17110
 
@@ -16983,27 +17114,35 @@
16983
17114
  );
16984
17115
  }
16985
17116
 
16986
- if (!(cart.capture_total > 0)) {
17117
+ if ((cart.capture_total || 0) <= 0) {
16987
17118
  throw new Error(
16988
17119
  'Invalid PayPal button amount. Value should be greater than zero.',
16989
17120
  );
16990
17121
  }
16991
17122
  }
16992
17123
 
17124
+ /**
17125
+ * @param {Cart} cart
17126
+ * @param {CreateOrderData} _data
17127
+ * @param {CreateOrderActions} _actions
17128
+ * @returns {Promise<string>}
17129
+ */
16993
17130
  async _onCreateOrder(cart, _data, _actions) {
16994
- const { require: { shipping: requireShipping = true } = {} } = this.params;
17131
+ const {
17132
+ locale = 'en-US',
17133
+ require: { shipping: requireShipping = true } = {},
17134
+ } = this.params;
17135
+
16995
17136
  const { capture_total, currency, subscription_delivery } = cart;
16996
17137
  const hasSubscriptionProduct = Boolean(subscription_delivery);
16997
17138
  const merchantId = this.merchantId;
16998
17139
  const returnUrl = this.returnUrl;
16999
- const orderData = {
17000
- application_context: {
17001
- shipping_preference: requireShipping ? 'GET_FROM_FILE' : 'NO_SHIPPING',
17002
- },
17003
- };
17140
+ /** @type {import('@paypal/paypal-js').CreateOrderRequestBody} */
17141
+ const orderData = {};
17142
+ /** @type {import('@paypal/paypal-js').PurchaseUnit} */
17004
17143
  const purchaseUnit = {
17005
17144
  amount: {
17006
- value: Number(capture_total.toFixed(2)),
17145
+ value: Number(capture_total).toFixed(2),
17007
17146
  currency_code: currency,
17008
17147
  },
17009
17148
  };
@@ -17011,29 +17150,44 @@
17011
17150
  if (merchantId) {
17012
17151
  // express checkout and ppcp
17013
17152
  orderData.intent = 'AUTHORIZE';
17153
+
17154
+ orderData.payment_source = {
17155
+ paypal: {
17156
+ experience_context: {
17157
+ locale,
17158
+ shipping_preference: requireShipping
17159
+ ? 'GET_FROM_FILE'
17160
+ : 'NO_SHIPPING',
17161
+ },
17162
+ },
17163
+ };
17164
+
17014
17165
  purchaseUnit.payee = {
17015
17166
  merchant_id: merchantId,
17016
17167
  };
17017
17168
 
17018
17169
  if (hasSubscriptionProduct) {
17019
- orderData.payment_source = {
17020
- paypal: {
17021
- attributes: {
17022
- vault: {
17023
- store_in_vault: 'ON_SUCCESS',
17024
- usage_type: 'MERCHANT',
17025
- },
17026
- },
17027
- experience_context: {
17028
- return_url: `${returnUrl}&redirect_status=succeeded`,
17029
- cancel_url: `${returnUrl}&redirect_status=canceled`,
17030
- },
17170
+ orderData.payment_source.paypal.attributes = {
17171
+ vault: {
17172
+ store_in_vault: 'ON_SUCCESS',
17173
+ usage_type: 'MERCHANT',
17031
17174
  },
17032
17175
  };
17176
+
17177
+ Object.assign(orderData.payment_source.paypal.experience_context, {
17178
+ return_url: `${returnUrl}&redirect_status=succeeded`,
17179
+ cancel_url: `${returnUrl}&redirect_status=canceled`,
17180
+ });
17033
17181
  }
17034
17182
  } else {
17035
17183
  // progressive checkout
17036
17184
  orderData.intent = 'CAPTURE';
17185
+
17186
+ orderData.application_context = {
17187
+ locale,
17188
+ shipping_preference: requireShipping ? 'GET_FROM_FILE' : 'NO_SHIPPING',
17189
+ };
17190
+
17037
17191
  purchaseUnit.payee = {
17038
17192
  email_address: this.method.store_owner_email,
17039
17193
  };
@@ -17049,44 +17203,37 @@
17049
17203
  return order.id;
17050
17204
  }
17051
17205
 
17052
- async _onShippingChange(data, actions) {
17206
+ /**
17207
+ * @param {OnShippingAddressChangeData} data
17208
+ * @param {OnShippingAddressChangeActions} actions
17209
+ */
17210
+ async _onShippingAddressChange(data, actions) {
17053
17211
  try {
17054
- const { orderID, shipping_address, selected_shipping_option } = data;
17055
- const updateData = {
17212
+ const { orderID, shippingAddress } = data;
17213
+
17214
+ const cart = await this.updateCart({
17056
17215
  shipping: {
17057
- state: shipping_address.state,
17058
- city: shipping_address.city,
17059
- zip: shipping_address.postal_code,
17060
- country: shipping_address.country_code,
17216
+ state: shippingAddress.state,
17217
+ city: shippingAddress.city,
17218
+ zip: shippingAddress.postalCode,
17219
+ country: shippingAddress.countryCode,
17061
17220
  },
17062
17221
  shipment_rating: null,
17063
- };
17064
-
17065
- if (selected_shipping_option) {
17066
- updateData.shipping.service = selected_shipping_option.id;
17067
- updateData.$taxes = true;
17068
- }
17222
+ });
17069
17223
 
17070
- const cart = await this.updateCart(updateData);
17071
- const shippingServices = get(cart, 'shipment_rating.services');
17224
+ const shippingServices = cart.shipment_rating?.services;
17072
17225
 
17073
- // can't fulfill shipping to selected address
17226
+ // Can't fulfill shipping to selected address
17074
17227
  if (isEmpty(shippingServices)) {
17075
17228
  return actions.reject();
17076
17229
  }
17077
17230
 
17078
- let selectedShippingService;
17079
-
17080
- if (selected_shipping_option) {
17081
- selectedShippingService = shippingServices.find(
17082
- (shippingService) =>
17083
- shippingService.id === selected_shipping_option.id,
17084
- );
17085
- }
17231
+ let selectedShippingService = cart.shipping?.service;
17086
17232
 
17087
17233
  // need to set first service for cart by default
17088
17234
  if (!selectedShippingService) {
17089
17235
  const [firstShippingService] = shippingServices;
17236
+ selectedShippingService = firstShippingService.id;
17090
17237
 
17091
17238
  await this.updateCart({
17092
17239
  shipping: {
@@ -17103,8 +17250,33 @@
17103
17250
  paypal_order_id: orderID,
17104
17251
  },
17105
17252
  });
17253
+ } catch (error) {
17254
+ this.onError(error);
17255
+
17256
+ return actions.reject();
17257
+ }
17258
+ }
17259
+
17260
+ /**
17261
+ * @param {OnShippingOptionsChangeData} data
17262
+ * @param {OnShippingOptionsChangeActions} actions
17263
+ */
17264
+ async _onShippingOptionsChange(data, actions) {
17265
+ try {
17266
+ const { orderID, selectedShippingOption } = data;
17267
+
17268
+ const cart = await this.updateCart({
17269
+ shipping: { service: selectedShippingOption.id },
17270
+ $taxes: true,
17271
+ });
17106
17272
 
17107
- return orderID;
17273
+ await this.updateIntent({
17274
+ gateway: 'paypal',
17275
+ intent: {
17276
+ cart_id: cart.id,
17277
+ paypal_order_id: orderID,
17278
+ },
17279
+ });
17108
17280
  } catch (error) {
17109
17281
  this.onError(error);
17110
17282
 
@@ -17112,14 +17284,17 @@
17112
17284
  }
17113
17285
  }
17114
17286
 
17287
+ /**
17288
+ * @param {OnApproveData} data
17289
+ * @param {OnApproveActions} actions
17290
+ */
17115
17291
  async _onApprove(data, actions) {
17116
- const { require: { shipping: requireShipping = true } = {} } = this.params;
17117
17292
  const order = await actions.order.get();
17118
17293
  const orderId = order.id;
17119
- const payer = order.payer;
17294
+ const payer = order.payment_source?.paypal || order.payer;
17120
17295
  const billing = payer.address;
17121
- const shipping = get(order, 'purchase_units[0].shipping');
17122
- const name = `${payer.name.given_name} ${payer.name.surname}`;
17296
+ const shipping = order.purchase_units?.[0]?.shipping;
17297
+ const name = `${payer.name?.given_name} ${payer.name?.surname}`;
17123
17298
 
17124
17299
  await this.updateCart({
17125
17300
  account: {
@@ -17131,31 +17306,35 @@
17131
17306
  order_id: orderId,
17132
17307
  },
17133
17308
  name,
17134
- ...this._mapAddress(billing),
17309
+ ...convertToSwellAddress$1(billing),
17135
17310
  },
17136
- ...(requireShipping && {
17311
+ ...(shipping?.address && {
17137
17312
  shipping: {
17138
17313
  first_name: payer.name.given_name,
17139
17314
  last_name: payer.name.surname,
17140
17315
  name: shipping.name.full_name,
17141
- ...this._mapAddress(shipping.address),
17316
+ ...convertToSwellAddress$1(shipping.address),
17142
17317
  },
17143
17318
  }),
17144
17319
  });
17145
17320
 
17146
17321
  this.onSuccess();
17147
17322
  }
17323
+ }
17148
17324
 
17149
- _mapAddress(address) {
17150
- return {
17151
- address1: address.address_line_1,
17152
- address2: address.address_line_2,
17153
- state: address.admin_area_1,
17154
- city: address.admin_area_2,
17155
- zip: address.postal_code,
17156
- country: address.country_code,
17157
- };
17158
- }
17325
+ /**
17326
+ * @param {ShippingAddress} address
17327
+ * @returns {Address}
17328
+ */
17329
+ function convertToSwellAddress$1(address) {
17330
+ return {
17331
+ address1: address.address_line_1,
17332
+ address2: address.address_line_2,
17333
+ state: address.admin_area_1,
17334
+ city: address.admin_area_2,
17335
+ zip: address.postal_code,
17336
+ country: address.country_code,
17337
+ };
17159
17338
  }
17160
17339
 
17161
17340
  class AmazonDirectPayment extends Payment {
@@ -17922,7 +18101,7 @@
17922
18101
  }
17923
18102
 
17924
18103
  async _vaultRequest(method, url, data) {
17925
- const response = await vaultRequest(method, url, data);
18104
+ const response = await vaultRequest(method, url, data, this.options);
17926
18105
 
17927
18106
  if (this.options.useCamelCase) {
17928
18107
  return toCamel(response);
@@ -18476,7 +18655,7 @@
18476
18655
  const api = {};
18477
18656
 
18478
18657
  Object.assign(api, {
18479
- version: '5.8.1',
18658
+ version: '5.9.0',
18480
18659
  options,
18481
18660
  request,
18482
18661
 
@@ -18506,8 +18685,6 @@
18506
18685
  options.getCart = opt.getCart;
18507
18686
  options.updateCart = opt.updateCart;
18508
18687
  options.headers = opt.headers || {};
18509
-
18510
- setOptions(options);
18511
18688
  },
18512
18689
 
18513
18690
  // Backward compatibility
@@ -18531,9 +18708,9 @@
18531
18708
  return api.request('delete', url, data);
18532
18709
  },
18533
18710
 
18534
- cache: cacheApi,
18711
+ cache: methods$d(options),
18535
18712
 
18536
- card: cardApi,
18713
+ card: methods$e(options),
18537
18714
 
18538
18715
  cart: methods$a(api, options),
18539
18716
 
@@ -18567,9 +18744,13 @@
18567
18744
 
18568
18745
  utils,
18569
18746
 
18570
- getCookie,
18747
+ getCookie(name) {
18748
+ return (options.getCookie || getCookie)(name);
18749
+ },
18571
18750
 
18572
- setCookie,
18751
+ setCookie(name, value, cookieOptions) {
18752
+ return (options.setCookie || setCookie)(name, value, cookieOptions);
18753
+ },
18573
18754
  });
18574
18755
 
18575
18756
  async function request(