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
package/dist/swell.cjs CHANGED
@@ -4493,8 +4493,6 @@ function isEmpty(value) {
4493
4493
 
4494
4494
  const LOADING_SCRIPTS = {};
4495
4495
 
4496
- let options = {};
4497
-
4498
4496
  function arrayMerge(target, source, options) {
4499
4497
  const destination = target.slice();
4500
4498
  source.forEach((item, index) => {
@@ -4532,14 +4530,6 @@ function merge(x, y, opt) {
4532
4530
  return deepmerge(x, y, opt);
4533
4531
  }
4534
4532
 
4535
- function setOptions(optns) {
4536
- options = optns;
4537
- }
4538
-
4539
- function getOptions() {
4540
- return options;
4541
- }
4542
-
4543
4533
  function isObject(val) {
4544
4534
  return val && typeof val === 'object' && !(val instanceof Array);
4545
4535
  }
@@ -4621,7 +4611,7 @@ function defaultMethods(api, uri, methods) {
4621
4611
  };
4622
4612
  }
4623
4613
 
4624
- async function vaultRequest(method, url, data) {
4614
+ async function vaultRequest(method, url, data, options) {
4625
4615
  const { vaultUrl, timeout, key } = options;
4626
4616
  const requestData = {
4627
4617
  $jsonp: {
@@ -4805,7 +4795,6 @@ const utils = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
4805
4795
  findIndex,
4806
4796
  get,
4807
4797
  getLocationParams,
4808
- getOptions,
4809
4798
  isEmpty,
4810
4799
  isEqual,
4811
4800
  isFunction,
@@ -4820,7 +4809,6 @@ const utils = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
4820
4809
  removeUrlParams,
4821
4810
  round: round$1,
4822
4811
  set,
4823
- setOptions,
4824
4812
  snakeCase,
4825
4813
  stringifyQuery,
4826
4814
  toCamel,
@@ -4835,171 +4823,173 @@ const utils = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
4835
4823
  vaultRequest
4836
4824
  }, Symbol.toStringTag, { value: 'Module' }));
4837
4825
 
4838
- const cardApi = {
4839
- async createToken(data) {
4840
- let error = null;
4841
- let code = null;
4842
- let param = null;
4843
- if (!data) {
4844
- error = 'Card details are missing in `swell.card.createToken(card)`';
4845
- param = '';
4846
- }
4847
- const card = toSnake(data);
4848
- if (!card.nonce) {
4849
- if (!this.validateNumber(card.number)) {
4850
- error = 'Card number appears to be invalid';
4851
- code = 'invalid_card_number';
4852
- param = 'number';
4826
+ function methods$e(options) {
4827
+ return {
4828
+ async createToken(data) {
4829
+ let error = null;
4830
+ let code = null;
4831
+ let param = null;
4832
+ if (!data) {
4833
+ error = 'Card details are missing in `swell.card.createToken(card)`';
4834
+ param = '';
4835
+ }
4836
+ const card = toSnake(data);
4837
+ if (!card.nonce) {
4838
+ if (!this.validateNumber(card.number)) {
4839
+ error = 'Card number appears to be invalid';
4840
+ code = 'invalid_card_number';
4841
+ param = 'number';
4842
+ }
4843
+ if (card.exp) {
4844
+ const exp = this.expiry(card.exp);
4845
+ card.exp_month = exp.month;
4846
+ card.exp_year = exp.year;
4847
+ }
4848
+ if (!this.validateExpiry(card.exp_month, card.exp_year)) {
4849
+ error = 'Card expiry appears to be invalid';
4850
+ code = 'invalid_card_expiry';
4851
+ param = 'exp_month';
4852
+ }
4853
+ if (!this.validateCVC(card.cvc)) {
4854
+ error = 'Card CVC code appears to be invalid';
4855
+ code = 'invalid_card_cvc';
4856
+ param = 'exp_cvc';
4857
+ }
4853
4858
  }
4854
- if (card.exp) {
4855
- const exp = this.expiry(card.exp);
4856
- card.exp_month = exp.month;
4857
- card.exp_year = exp.year;
4859
+
4860
+ if (error) {
4861
+ const err = new Error(error);
4862
+ err.code = code || 'invalid_card';
4863
+ err.status = 402;
4864
+ err.param = param;
4865
+ throw err;
4858
4866
  }
4859
- if (!this.validateExpiry(card.exp_month, card.exp_year)) {
4860
- error = 'Card expiry appears to be invalid';
4861
- code = 'invalid_card_expiry';
4862
- param = 'exp_month';
4867
+
4868
+ // Get a token from the vault
4869
+ const result = await vaultRequest('post', '/tokens', card, options);
4870
+ if (result.errors) {
4871
+ const param = Object.keys(result.errors)[0];
4872
+ const err = new Error(result.errors[param].message || 'Unknown error');
4873
+ err.code = 'vault_error';
4874
+ err.status = 402;
4875
+ err.param = param;
4876
+ throw err;
4863
4877
  }
4864
- if (!this.validateCVC(card.cvc)) {
4865
- error = 'Card CVC code appears to be invalid';
4866
- code = 'invalid_card_cvc';
4867
- param = 'exp_cvc';
4878
+ return result;
4879
+ },
4880
+
4881
+ expiry(value) {
4882
+ if (value && value.month && value.year) {
4883
+ return value;
4868
4884
  }
4869
- }
4870
4885
 
4871
- if (error) {
4872
- const err = new Error(error);
4873
- err.code = code || 'invalid_card';
4874
- err.status = 402;
4875
- err.param = param;
4876
- throw err;
4877
- }
4886
+ const parts = new String(value).split(/[\s/-]+/, 2);
4887
+ const month = parts[0];
4878
4888
 
4879
- // Get a token from the vault
4880
- const result = await vaultRequest('post', '/tokens', card);
4881
- if (result.errors) {
4882
- const param = Object.keys(result.errors)[0];
4883
- const err = new Error(result.errors[param].message || 'Unknown error');
4884
- err.code = 'vault_error';
4885
- err.status = 402;
4886
- err.param = param;
4887
- throw err;
4888
- }
4889
- return result;
4890
- },
4889
+ const currentYear = new Date().getUTCFullYear().toString();
4890
+ let strYear = parts[1];
4891
4891
 
4892
- expiry(value) {
4893
- if (value && value.month && value.year) {
4894
- return value;
4895
- }
4892
+ if (strYear.length < currentYear.length) {
4893
+ let fullYear =
4894
+ currentYear.slice(0, currentYear.length - strYear.length) + strYear;
4896
4895
 
4897
- const parts = new String(value).split(/[\s/-]+/, 2);
4898
- const month = parts[0];
4896
+ // If the expiration year is less than the current year,
4897
+ // then the expiration year is in the next century.
4898
+ if (fullYear < currentYear) {
4899
+ let year = Number(fullYear);
4900
+ year += 10 ** strYear.length;
4901
+ fullYear = year.toString();
4902
+ }
4899
4903
 
4900
- const currentYear = new Date().getUTCFullYear().toString();
4901
- let strYear = parts[1];
4904
+ strYear = fullYear;
4905
+ }
4902
4906
 
4903
- if (strYear.length < currentYear.length) {
4904
- let fullYear =
4905
- currentYear.slice(0, currentYear.length - strYear.length) + strYear;
4907
+ return {
4908
+ month: Number.parseInt(month, 10),
4909
+ year: Number.parseInt(strYear, 10),
4910
+ };
4911
+ },
4906
4912
 
4907
- // If the expiration year is less than the current year,
4908
- // then the expiration year is in the next century.
4909
- if (fullYear < currentYear) {
4910
- let year = Number(fullYear);
4911
- year += 10 ** strYear.length;
4912
- fullYear = year.toString();
4913
- }
4913
+ types() {
4914
+ let t = {};
4915
+ for (let e = 40; e <= 49; ++e) t[e] = 'Visa';
4916
+ for (let e = 50; e <= 59; ++e) t[e] = 'MasterCard';
4917
+ t[34] = t[37] = 'American Express';
4918
+ t[60] = t[62] = t[64] = t[65] = 'Discover';
4919
+ t[35] = 'JCB';
4920
+ t[30] = t[36] = t[38] = t[39] = 'Diners Club';
4921
+ return t;
4922
+ },
4914
4923
 
4915
- strYear = fullYear;
4916
- }
4924
+ type(num) {
4925
+ return this.types()[num.slice(0, 2)] || 'Unknown';
4926
+ },
4917
4927
 
4918
- return {
4919
- month: Number.parseInt(month, 10),
4920
- year: Number.parseInt(strYear, 10),
4921
- };
4922
- },
4923
-
4924
- types() {
4925
- let t = {};
4926
- for (let e = 40; e <= 49; ++e) t[e] = 'Visa';
4927
- for (let e = 50; e <= 59; ++e) t[e] = 'MasterCard';
4928
- t[34] = t[37] = 'American Express';
4929
- t[60] = t[62] = t[64] = t[65] = 'Discover';
4930
- t[35] = 'JCB';
4931
- t[30] = t[36] = t[38] = t[39] = 'Diners Club';
4932
- return t;
4933
- },
4934
-
4935
- type(num) {
4936
- return this.types()[num.slice(0, 2)] || 'Unknown';
4937
- },
4938
-
4939
- luhnCheck(num) {
4940
- const numbers = String(num);
4941
- let odd = false;
4942
- let sum = 0;
4943
-
4944
- for (let i = numbers.length - 1; i >= 0; --i) {
4945
- let digit = Number.parseInt(numbers[i], 10);
4946
-
4947
- if (odd) {
4948
- digit *= 2;
4949
-
4950
- if (digit > 9) {
4951
- digit -= 9;
4928
+ luhnCheck(num) {
4929
+ const numbers = String(num);
4930
+ let odd = false;
4931
+ let sum = 0;
4932
+
4933
+ for (let i = numbers.length - 1; i >= 0; --i) {
4934
+ let digit = Number.parseInt(numbers[i], 10);
4935
+
4936
+ if (odd) {
4937
+ digit *= 2;
4938
+
4939
+ if (digit > 9) {
4940
+ digit -= 9;
4941
+ }
4952
4942
  }
4953
- }
4954
4943
 
4955
- sum += digit;
4956
- odd = !odd;
4957
- }
4944
+ sum += digit;
4945
+ odd = !odd;
4946
+ }
4958
4947
 
4959
- return sum % 10 === 0;
4960
- },
4948
+ return sum % 10 === 0;
4949
+ },
4961
4950
 
4962
- validateNumber(num) {
4963
- num = String(num).replace(/\s+|-/g, '');
4951
+ validateNumber(num) {
4952
+ num = String(num).replace(/\s+|-/g, '');
4964
4953
 
4965
- return num.length >= 10 && num.length <= 16 && this.luhnCheck(num);
4966
- },
4954
+ return num.length >= 10 && num.length <= 16 && this.luhnCheck(num);
4955
+ },
4967
4956
 
4968
- validateExpiry(month, year) {
4969
- month = String(month).trim();
4970
- year = String(year).trim();
4957
+ validateExpiry(month, year) {
4958
+ month = String(month).trim();
4959
+ year = String(year).trim();
4971
4960
 
4972
- if (!/^\d+$/.test(month) || !/^\d+$/.test(year)) {
4973
- return false;
4974
- }
4961
+ if (!/^\d+$/.test(month) || !/^\d+$/.test(year)) {
4962
+ return false;
4963
+ }
4975
4964
 
4976
- const numMonth = Number.parseInt(month, 10);
4965
+ const numMonth = Number.parseInt(month, 10);
4977
4966
 
4978
- if (numMonth <= 0 || numMonth > 12) {
4979
- return false;
4980
- }
4967
+ if (numMonth <= 0 || numMonth > 12) {
4968
+ return false;
4969
+ }
4981
4970
 
4982
- const date = new Date(year, month);
4983
- date.setMonth(date.getMonth() - 1);
4984
- date.setMonth(date.getMonth() + 1, 1);
4971
+ const date = new Date(year, month);
4972
+ date.setMonth(date.getMonth() - 1);
4973
+ date.setMonth(date.getMonth() + 1, 1);
4985
4974
 
4986
- const diff = date.getTime() - Date.now();
4975
+ const diff = date.getTime() - Date.now();
4987
4976
 
4988
- // The card has expired
4989
- if (diff < 0) {
4990
- return false;
4991
- }
4977
+ // The card has expired
4978
+ if (diff < 0) {
4979
+ return false;
4980
+ }
4992
4981
 
4993
- // The card's validity period must not exceed 50 years from the current time.
4994
- return Math.round(diff / 31_557_600_000) < 50;
4995
- },
4982
+ // The card's validity period must not exceed 50 years from the current time.
4983
+ return Math.round(diff / 31_557_600_000) < 50;
4984
+ },
4996
4985
 
4997
- validateCVC(val) {
4998
- val = String(val).trim();
4986
+ validateCVC(val) {
4987
+ val = String(val).trim();
4999
4988
 
5000
- return /^\d+$/.test(val) && val.length >= 3 && val.length <= 4;
5001
- },
5002
- };
4989
+ return /^\d+$/.test(val) && val.length >= 3 && val.length <= 4;
4990
+ },
4991
+ };
4992
+ }
5003
4993
 
5004
4994
  const COOKIE_MAX_AGE = 604800; // 1 week
5005
4995
 
@@ -5050,191 +5040,191 @@ function setCookie(name, value, options = {}) {
5050
5040
 
5051
5041
  const RECORD_TIMEOUT = 5000;
5052
5042
 
5053
- let VALUES = {
5054
- /*
5055
- [model]: {
5056
- [id]: {
5057
- data,
5058
- record,
5059
- recordTimer,
5060
- presets,
5043
+ function methods$d(opt) {
5044
+ let VALUES = {
5045
+ /*
5046
+ [model]: {
5047
+ [id]: {
5048
+ data,
5049
+ record,
5050
+ recordTimer,
5051
+ presets,
5052
+ }
5061
5053
  }
5062
- }
5063
- */
5064
- };
5065
-
5066
- const cacheApi = {
5067
- options: {
5068
- enabled: true,
5069
- debug: false,
5070
- },
5054
+ */
5055
+ };
5071
5056
 
5072
- debug(...args) {
5073
- if (this.options.debug) {
5074
- console.log(...args);
5075
- }
5076
- },
5057
+ return {
5058
+ options: {
5059
+ enabled: true,
5060
+ debug: false,
5061
+ },
5077
5062
 
5078
- values({ model, id }, setValues = undefined) {
5079
- this.debug('cache.values', ...arguments);
5080
- if (setValues !== undefined) {
5081
- for (let key in setValues) {
5082
- set(VALUES, `${model}.${id}.${key}`, setValues[key]);
5063
+ debug(...args) {
5064
+ if (this.options.debug) {
5065
+ console.log(...args);
5083
5066
  }
5084
- return;
5085
- }
5086
- return get(VALUES, `${model}.${id}`, {});
5087
- },
5067
+ },
5088
5068
 
5089
- preset(details) {
5090
- this.debug('cache.preset', ...arguments);
5091
- const { presets = [] } = this.values(details);
5092
- presets.push(details);
5093
- this.values(details, { presets });
5094
- },
5069
+ values({ model, id }, setValues = undefined) {
5070
+ this.debug('cache.values', ...arguments);
5071
+ if (setValues !== undefined) {
5072
+ for (let key in setValues) {
5073
+ set(VALUES, `${model}.${id}.${key}`, setValues[key]);
5074
+ }
5075
+ return;
5076
+ }
5077
+ return get(VALUES, `${model}.${id}`, {});
5078
+ },
5095
5079
 
5096
- set(details) {
5097
- this.debug('cache.set', ...arguments);
5098
- let { model, id, path, value } = details;
5099
- let { data = {}, record } = this.values(details);
5080
+ preset(details) {
5081
+ this.debug('cache.preset', ...arguments);
5082
+ const { presets = [] } = this.values(details);
5083
+ presets.push(details);
5084
+ this.values(details, { presets });
5085
+ },
5100
5086
 
5101
- if (id === null) {
5102
- return;
5103
- }
5087
+ set(details) {
5088
+ this.debug('cache.set', ...arguments);
5089
+ let { model, id, path, value } = details;
5090
+ let { data = {}, record } = this.values(details);
5104
5091
 
5105
- if (record === undefined) {
5106
- return this.preset(details);
5107
- }
5092
+ if (id === null) {
5093
+ return;
5094
+ }
5108
5095
 
5109
- data = merge(record || {}, data);
5096
+ if (record === undefined) {
5097
+ return this.preset(details);
5098
+ }
5110
5099
 
5111
- const { useCamelCase } = getOptions();
5112
- if (useCamelCase && value && typeof value === 'object') {
5113
- value = toCamel(value);
5114
- }
5100
+ data = merge(record || {}, data);
5115
5101
 
5116
- if (path || value instanceof Array) {
5117
- let upData = { ...(data || {}) };
5118
- let upPath = useCamelCase ? toCamelPath(path) : path;
5119
- set(upData, upPath || '', value);
5120
- data = upData;
5121
- } else if (value && typeof value === 'object') {
5122
- data = data || {};
5123
- data = merge(data, value);
5124
- } else {
5125
- data = value;
5126
- }
5102
+ const { useCamelCase } = opt;
5103
+ if (useCamelCase && value && typeof value === 'object') {
5104
+ value = toCamel(value);
5105
+ }
5106
+
5107
+ if (path || value instanceof Array) {
5108
+ let upData = { ...(data || {}) };
5109
+ let upPath = useCamelCase ? toCamelPath(path) : path;
5110
+ set(upData, upPath || '', value);
5111
+ data = upData;
5112
+ } else if (value && typeof value === 'object') {
5113
+ data = data || {};
5114
+ data = merge(data, value);
5115
+ } else {
5116
+ data = value;
5117
+ }
5127
5118
 
5128
- this.values(details, { data });
5119
+ this.values(details, { data });
5129
5120
 
5130
- try {
5131
- // Make sure values have clean refs
5132
- const cache = VALUES[model][id];
5133
- if (cache !== undefined) {
5134
- if (cache.data !== undefined) {
5135
- cache.data = JSON.parse(JSON.stringify(cache.data));
5136
- }
5137
- if (cache.record !== undefined) {
5138
- cache.record = JSON.parse(JSON.stringify(cache.record));
5121
+ try {
5122
+ // Make sure values have clean refs
5123
+ const cache = VALUES[model][id];
5124
+ if (cache !== undefined) {
5125
+ if (cache.data !== undefined) {
5126
+ cache.data = JSON.parse(JSON.stringify(cache.data));
5127
+ }
5128
+ if (cache.record !== undefined) {
5129
+ cache.record = JSON.parse(JSON.stringify(cache.record));
5130
+ }
5139
5131
  }
5132
+ } catch (err) {
5133
+ // noop
5140
5134
  }
5141
- } catch (err) {
5142
- // noop
5143
- }
5144
- },
5135
+ },
5145
5136
 
5146
- get(model, id) {
5147
- this.debug('cache.get', ...arguments);
5148
- const { data, recordTimer } = this.values({ model, id });
5149
- this.debug('cache.get:data+recordTimer', ...arguments);
5150
- if (recordTimer) {
5151
- return data;
5152
- }
5153
- },
5137
+ get(model, id) {
5138
+ this.debug('cache.get', ...arguments);
5139
+ const { data, recordTimer } = this.values({ model, id });
5140
+ this.debug('cache.get:data+recordTimer', ...arguments);
5141
+ if (recordTimer) {
5142
+ return data;
5143
+ }
5144
+ },
5154
5145
 
5155
- setRecord(record, details) {
5156
- this.debug('cache.setRecord', ...arguments);
5157
- let { recordTimer, presets } = this.values(details);
5146
+ setRecord(record, details) {
5147
+ this.debug('cache.setRecord', ...arguments);
5148
+ let { recordTimer, presets } = this.values(details);
5158
5149
 
5159
- if (recordTimer) {
5160
- clearTimeout(recordTimer);
5161
- }
5150
+ if (recordTimer) {
5151
+ clearTimeout(recordTimer);
5152
+ }
5162
5153
 
5163
- recordTimer = setTimeout(() => {
5164
- this.values(details, { record: undefined, recordTimer: undefined });
5165
- }, RECORD_TIMEOUT);
5154
+ recordTimer = setTimeout(() => {
5155
+ this.values(details, { record: undefined, recordTimer: undefined });
5156
+ }, RECORD_TIMEOUT);
5166
5157
 
5167
- // Record has to be null at minimum, not undefined
5168
- this.values(details, {
5169
- record: record !== undefined ? record : null,
5170
- recordTimer,
5171
- });
5158
+ // Record has to be null at minimum, not undefined
5159
+ this.values(details, {
5160
+ record: record !== undefined ? record : null,
5161
+ recordTimer,
5162
+ });
5172
5163
 
5173
- if (presets) {
5174
- for (let preset of presets) {
5175
- this.set(preset);
5164
+ if (presets) {
5165
+ for (let preset of presets) {
5166
+ this.set(preset);
5167
+ }
5168
+ this.values(details, { presets: undefined });
5176
5169
  }
5177
- this.values(details, { presets: undefined });
5178
- }
5179
5170
 
5180
- const result = this.get(details.model, details.id);
5171
+ const result = this.get(details.model, details.id);
5181
5172
 
5182
- return result !== undefined ? result : record;
5183
- },
5173
+ return result !== undefined ? result : record;
5174
+ },
5184
5175
 
5185
- async getFetch(model, id, fetch) {
5186
- if (this.options.enabled) {
5187
- this.debug('cache.getFetch', ...arguments);
5188
- const value = this.get(model, id);
5176
+ async getFetch(model, id, fetch) {
5177
+ if (this.options.enabled) {
5178
+ this.debug('cache.getFetch', ...arguments);
5179
+ const value = this.get(model, id);
5189
5180
 
5190
- if (value !== undefined) {
5191
- return value;
5181
+ if (value !== undefined) {
5182
+ return value;
5183
+ }
5192
5184
  }
5193
- }
5194
5185
 
5195
- const record = await fetch();
5196
- return this.setRecord(record, { model, id });
5197
- },
5186
+ const record = await fetch();
5187
+ return this.setRecord(record, { model, id });
5188
+ },
5198
5189
 
5199
- clear(model = undefined, id = undefined) {
5200
- this.debug('cache.clear', ...arguments);
5201
- if (model) {
5202
- if (id) {
5203
- set(VALUES, `${model}.${id}`, undefined);
5190
+ clear(model = undefined, id = undefined) {
5191
+ this.debug('cache.clear', ...arguments);
5192
+ if (model) {
5193
+ if (id) {
5194
+ set(VALUES, `${model}.${id}`, undefined);
5195
+ } else {
5196
+ set(VALUES, model, undefined);
5197
+ }
5204
5198
  } else {
5205
- set(VALUES, model, undefined);
5199
+ VALUES = {};
5206
5200
  }
5207
- } else {
5208
- VALUES = {};
5209
- }
5210
- },
5211
- };
5201
+ },
5202
+ };
5203
+ }
5212
5204
 
5213
5205
  function methods$c(api) {
5214
5206
  const { get, list } = defaultMethods(api, '/attributes', ['list', 'get']);
5215
5207
 
5216
5208
  return {
5217
5209
  get: (id, ...args) => {
5218
- return cacheApi.getFetch('attributes', id, () => get(id, ...args));
5210
+ return api.cache.getFetch('attributes', id, () => get(id, ...args));
5219
5211
  },
5220
5212
 
5221
5213
  list,
5222
5214
  };
5223
5215
  }
5224
5216
 
5225
- let OPTIONS;
5226
-
5227
5217
  function methods$b(api, opt) {
5228
- OPTIONS = opt;
5229
5218
  const { get, list } = defaultMethods(api, '/products', ['list', 'get']);
5230
5219
  return {
5231
5220
  get: (id, ...args) => {
5232
- return cacheApi.getFetch('products', id, () => get(id, ...args));
5221
+ return api.cache.getFetch('products', id, () => get(id, ...args));
5233
5222
  },
5234
5223
 
5235
5224
  list,
5236
5225
 
5237
- variation: calculateVariation,
5226
+ variation: (input, options, purchaseOption) =>
5227
+ calculateVariation(input, options, purchaseOption, opt),
5238
5228
 
5239
5229
  categories: getCategories,
5240
5230
 
@@ -5314,8 +5304,8 @@ function findVariantWithOptionValueIds(product, ids) {
5314
5304
  return null;
5315
5305
  }
5316
5306
 
5317
- function calculateVariation(input, options, purchaseOption) {
5318
- const product = OPTIONS.useCamelCase ? toSnake(input) : input;
5307
+ function calculateVariation(input, options, purchaseOption, opt) {
5308
+ const product = opt.useCamelCase ? toSnake(input) : input;
5319
5309
  const purchaseOp = findPurchaseOption(product, purchaseOption);
5320
5310
  const variation = {
5321
5311
  ...product,
@@ -5378,7 +5368,7 @@ function calculateVariation(input, options, purchaseOption) {
5378
5368
  if (variation.orig_price === undefined) {
5379
5369
  delete variation.orig_price;
5380
5370
  }
5381
- return OPTIONS.useCamelCase ? toCamel(variation) : variation;
5371
+ return opt.useCamelCase ? toCamel(variation) : variation;
5382
5372
  }
5383
5373
 
5384
5374
  function findPurchaseOption(product, purchaseOption) {
@@ -5433,8 +5423,7 @@ function findPurchaseOption(product, purchaseOption) {
5433
5423
  }
5434
5424
 
5435
5425
  async function getFilterableAttributeFilters(api, products, options) {
5436
- const { results: filterableAttributes } = await methods$c(
5437
- api).list({
5426
+ const { results: filterableAttributes } = await methods$c(api).list({
5438
5427
  filterable: true,
5439
5428
  });
5440
5429
 
@@ -6041,19 +6030,29 @@ class AppPaymentComponent extends AppComponent {
6041
6030
  }
6042
6031
 
6043
6032
  #getIntent(data) {
6044
- return vaultRequest('GET', '/intent', {
6045
- gateway: this.#gateway,
6046
- account_id: this.#accountId,
6047
- intent: data,
6048
- });
6033
+ return vaultRequest(
6034
+ 'GET',
6035
+ '/intent',
6036
+ {
6037
+ gateway: this.#gateway,
6038
+ account_id: this.#accountId,
6039
+ intent: data,
6040
+ },
6041
+ this.options,
6042
+ );
6049
6043
  }
6050
6044
 
6051
6045
  #createIntent(data) {
6052
- return vaultRequest('POST', '/intent', {
6053
- gateway: this.#gateway,
6054
- account_id: this.#accountId,
6055
- intent: data,
6056
- });
6046
+ return vaultRequest(
6047
+ 'POST',
6048
+ '/intent',
6049
+ {
6050
+ gateway: this.#gateway,
6051
+ account_id: this.#accountId,
6052
+ intent: data,
6053
+ },
6054
+ this.options,
6055
+ );
6057
6056
  }
6058
6057
  }
6059
6058
 
@@ -6208,7 +6207,7 @@ function methods$8(api) {
6208
6207
 
6209
6208
  return {
6210
6209
  get: (id, ...args) => {
6211
- return cacheApi.getFetch('categories', id, () => get(id, ...args));
6210
+ return api.cache.getFetch('categories', id, () => get(id, ...args));
6212
6211
  },
6213
6212
 
6214
6213
  list,
@@ -6219,7 +6218,7 @@ function methods$7(api) {
6219
6218
  const { get, list } = defaultMethods(api, '/subscriptions', ['list', 'get']);
6220
6219
  return {
6221
6220
  get: (id, ...args) => {
6222
- return cacheApi.getFetch('subscriptions', id, () => get(id, ...args));
6221
+ return api.cache.getFetch('subscriptions', id, () => get(id, ...args));
6223
6222
  },
6224
6223
 
6225
6224
  list,
@@ -6284,7 +6283,7 @@ function methods$6(api) {
6284
6283
  const { get, list } = defaultMethods(api, '/invoices', ['list', 'get']);
6285
6284
  return {
6286
6285
  get: (id, ...args) => {
6287
- return cacheApi.getFetch('invoices', id, () => get(id, ...args));
6286
+ return api.cache.getFetch('invoices', id, () => get(id, ...args));
6288
6287
  },
6289
6288
 
6290
6289
  list,
@@ -6294,7 +6293,7 @@ function methods$6(api) {
6294
6293
  function methods$5(api, opt) {
6295
6294
  return {
6296
6295
  get: (type, id, query) => {
6297
- return cacheApi.getFetch(`content_${type}`, id, () =>
6296
+ return api.cache.getFetch(`content_${type}`, id, () =>
6298
6297
  api.request('get', `/content/${type}`, id, {
6299
6298
  $preview: opt.previewContent,
6300
6299
  ...(query || {}),
@@ -6665,13 +6664,18 @@ async function loadStripe() {
6665
6664
 
6666
6665
  async function loadPaypal(params) {
6667
6666
  if (!window.paypal) {
6668
- const { currency, client_id, merchant_id } = params;
6667
+ const { vault, currency, client_id, merchant_id } = params;
6668
+
6669
6669
  const paypalParams = {
6670
6670
  currency,
6671
6671
  'client-id': client_id,
6672
6672
  commit: false,
6673
6673
  };
6674
6674
 
6675
+ if (vault) {
6676
+ paypalParams.vault = vault;
6677
+ }
6678
+
6675
6679
  if (merchant_id) {
6676
6680
  // paypal express and ppcp onboarded
6677
6681
  paypalParams['merchant-id'] = merchant_id;
@@ -7036,7 +7040,7 @@ class Payment {
7036
7040
  * @returns {Promise<object>}
7037
7041
  */
7038
7042
  async createIntent(data) {
7039
- return vaultRequest('post', '/intent', data);
7043
+ return vaultRequest('post', '/intent', data, this.options);
7040
7044
  }
7041
7045
 
7042
7046
  /**
@@ -7046,7 +7050,7 @@ class Payment {
7046
7050
  * @returns {Promise<object>}
7047
7051
  */
7048
7052
  async updateIntent(data) {
7049
- return vaultRequest('put', '/intent', data);
7053
+ return vaultRequest('put', '/intent', data, this.options);
7050
7054
  }
7051
7055
 
7052
7056
  /**
@@ -7056,7 +7060,7 @@ class Payment {
7056
7060
  * @returns {Promise<object>}
7057
7061
  */
7058
7062
  async authorizeGateway(data) {
7059
- return vaultRequest('post', '/authorization', data);
7063
+ return vaultRequest('post', '/authorization', data, this.options);
7060
7064
  }
7061
7065
 
7062
7066
  /**
@@ -8798,7 +8802,7 @@ async function onPaymentDataChanged(intermediatePaymentData) {
8798
8802
 
8799
8803
  // Update cart with new shipping address and force tax recalculation
8800
8804
  let cart = await this.updateCart({
8801
- shipping: convertToSwellAddress$2(
8805
+ shipping: convertToSwellAddress$3(
8802
8806
  intermediatePaymentData.shippingAddress,
8803
8807
  ),
8804
8808
  });
@@ -9064,7 +9068,7 @@ function getOfferInfo(cart) {
9064
9068
  * @param {google.payments.api.Address} address
9065
9069
  * @returns {Address}
9066
9070
  */
9067
- function convertToSwellAddress$2(address) {
9071
+ function convertToSwellAddress$3(address) {
9068
9072
  return {
9069
9073
  name: address.name,
9070
9074
  address1: address.address1,
@@ -9328,11 +9332,11 @@ class BraintreeGooglePayment extends Payment {
9328
9332
  nonce,
9329
9333
  gateway: 'braintree',
9330
9334
  },
9331
- ...convertToSwellAddress$2(billingAddress),
9335
+ ...convertToSwellAddress$3(billingAddress),
9332
9336
  },
9333
9337
  ...(shippingAddress && {
9334
9338
  shipping: {
9335
- ...convertToSwellAddress$2(shippingAddress),
9339
+ ...convertToSwellAddress$3(shippingAddress),
9336
9340
  service: shippingOptionData?.id || undefined,
9337
9341
  },
9338
9342
  }),
@@ -9340,7 +9344,7 @@ class BraintreeGooglePayment extends Payment {
9340
9344
 
9341
9345
  if (cart.subscription_delivery) {
9342
9346
  try {
9343
- const card = await cardApi.createToken({
9347
+ const card = await this.api.card.createToken({
9344
9348
  gateway: 'braintree',
9345
9349
  account_id: cart.account_id,
9346
9350
  nonce,
@@ -9369,6 +9373,7 @@ class BraintreeGooglePayment extends Payment {
9369
9373
  /** @typedef {import('./payment').default} Payment */
9370
9374
  /** @typedef {import('../../types').Cart} Cart */
9371
9375
  /** @typedef {import('../../types').Address} Address */
9376
+ /** @typedef {import('../../types').CartItemBillingSchedule} CartItemBillingSchedule */
9372
9377
 
9373
9378
  /**
9374
9379
  * @this {Payment}
@@ -9380,7 +9385,7 @@ async function onShippingAddressChange(shippingContact) {
9380
9385
  // Update cart with Apple Pay shipping address to get shipping options and tax
9381
9386
  // This happens immediately when the sheet opens with the default address
9382
9387
  const cart = await this.updateCart({
9383
- shipping: convertToSwellAddress$1(shippingContact),
9388
+ shipping: convertToSwellAddress$2(shippingContact),
9384
9389
  });
9385
9390
 
9386
9391
  if (!cart.shipment_rating?.services?.length) {
@@ -9669,7 +9674,7 @@ function getShippingMethods(cart) {
9669
9674
  * @param {ApplePayJS.ApplePayPaymentContact} [address]
9670
9675
  * @returns {Address}
9671
9676
  */
9672
- function convertToSwellAddress$1(address = {}) {
9677
+ function convertToSwellAddress$2(address = {}) {
9673
9678
  return {
9674
9679
  first_name: address.givenName,
9675
9680
  last_name: address.familyName,
@@ -9712,6 +9717,99 @@ function getRequiredContactFields(params) {
9712
9717
  return { requiredBillingContactFields, requiredShippingContactFields };
9713
9718
  }
9714
9719
 
9720
+ /**
9721
+ * @param {CartItemBillingSchedule} schedule
9722
+ * @returns {{ intervalUnit: ApplePayJS.ApplePayRecurringPaymentDateUnit, intervalCount: number }}
9723
+ */
9724
+ function convertSwellScheduleToAppleRecurringInterval(schedule) {
9725
+ let intervalCount = schedule.interval_count || 1;
9726
+ let intervalUnit = 'day';
9727
+
9728
+ switch (schedule.interval) {
9729
+ case 'daily':
9730
+ intervalUnit = 'day';
9731
+ break;
9732
+
9733
+ case 'weekly':
9734
+ intervalUnit = 'day';
9735
+ intervalCount *= 7;
9736
+ break;
9737
+
9738
+ case 'monthly':
9739
+ intervalUnit = 'month';
9740
+ break;
9741
+
9742
+ case 'yearly':
9743
+ intervalUnit = 'year';
9744
+ break;
9745
+ }
9746
+
9747
+ return { intervalUnit, intervalCount };
9748
+ }
9749
+
9750
+ /**
9751
+ * @param {Cart} cart
9752
+ * @param {string} managementUrl
9753
+ * @returns {ApplePayJS.ApplePayRecurringPaymentRequest | undefined}
9754
+ */
9755
+ function getRecurringPaymentRequest(cart, managementUrl) {
9756
+ if (!cart.subscription_delivery) {
9757
+ return undefined;
9758
+ }
9759
+
9760
+ const item = cart.items.find(
9761
+ (item) =>
9762
+ item.purchase_option?.type === 'subscription' &&
9763
+ item.purchase_option.billing_schedule,
9764
+ );
9765
+
9766
+ if (item === undefined) {
9767
+ return undefined;
9768
+ }
9769
+
9770
+ const { intervalUnit, intervalCount } =
9771
+ convertSwellScheduleToAppleRecurringInterval(
9772
+ item.purchase_option.billing_schedule,
9773
+ );
9774
+
9775
+ /** @type {ApplePayJS.ApplePayRecurringPaymentRequest} */
9776
+ const recurringPaymentRequest = {
9777
+ paymentDescription:
9778
+ item.purchase_option.plan_description ||
9779
+ item.purchase_option.plan_name ||
9780
+ item.product_name ||
9781
+ item.product?.name,
9782
+ regularBilling: {
9783
+ type: 'final',
9784
+ label: item.purchase_option.plan_name || 'Subscription',
9785
+ // Calculate the subscription price manually if a trial period is specified.
9786
+ // However, discounts are not included in the calculation due to the difficulty of taking into account all scenarios.
9787
+ amount: (item.purchase_option.billing_schedule.trial_days
9788
+ ? (item.price || 0) * (item.quantity || 1)
9789
+ : item.price_total
9790
+ ).toFixed(2),
9791
+ paymentTiming: 'recurring',
9792
+ recurringPaymentIntervalUnit: intervalUnit,
9793
+ recurringPaymentIntervalCount: intervalCount,
9794
+ },
9795
+ trialBilling: item.purchase_option.billing_schedule.trial_days
9796
+ ? {
9797
+ type: 'final',
9798
+ label: 'Trial',
9799
+ // When a trial period is set, price_total is 0 (usually)
9800
+ amount: Number(item.price_total || 0).toFixed(2),
9801
+ paymentTiming: 'recurring',
9802
+ recurringPaymentIntervalUnit: 'day',
9803
+ recurringPaymentIntervalCount:
9804
+ item.purchase_option.billing_schedule.trial_days,
9805
+ }
9806
+ : undefined,
9807
+ managementURL: managementUrl,
9808
+ };
9809
+
9810
+ return recurringPaymentRequest;
9811
+ }
9812
+
9715
9813
  /** @typedef {import('../../../types').Cart} Cart */
9716
9814
 
9717
9815
  const VERSION$1 = 14;
@@ -9914,16 +10012,16 @@ class BraintreeApplePayment extends Payment {
9914
10012
  nonce: payload.nonce,
9915
10013
  gateway: 'braintree',
9916
10014
  },
9917
- ...convertToSwellAddress$1(billingContact),
10015
+ ...convertToSwellAddress$2(billingContact),
9918
10016
  },
9919
10017
  ...(shippingContact && {
9920
- shipping: convertToSwellAddress$1(shippingContact),
10018
+ shipping: convertToSwellAddress$2(shippingContact),
9921
10019
  }),
9922
10020
  });
9923
10021
 
9924
10022
  if (cart.subscription_delivery) {
9925
10023
  try {
9926
- const card = await cardApi.createToken({
10024
+ const card = await this.api.card.createToken({
9927
10025
  gateway: 'braintree',
9928
10026
  account_id: cart.account_id,
9929
10027
  nonce: payload.nonce,
@@ -10123,7 +10221,7 @@ class AbstractGooglePayment extends Payment {
10123
10221
  * @returns {Promise<object>}
10124
10222
  */
10125
10223
  // eslint-disable-next-line no-unused-vars
10126
- async preparePaymentDataForCartUpdate(paymentData) {
10224
+ async processPaymentData(paymentData) {
10127
10225
  throw new Error('Implement this!');
10128
10226
  }
10129
10227
 
@@ -10145,9 +10243,7 @@ class AbstractGooglePayment extends Payment {
10145
10243
  throw new Error('Google Pay token is missing');
10146
10244
  }
10147
10245
 
10148
- await this.preparePaymentDataForCartUpdate(paymentData).then((data) =>
10149
- this.updateCart(data),
10150
- );
10246
+ await this.processPaymentData(paymentData);
10151
10247
 
10152
10248
  this.onSuccess();
10153
10249
  }
@@ -10270,7 +10366,7 @@ class AuthorizeNetGooglePayment extends AbstractGooglePayment {
10270
10366
  * @param {google.payments.api.PaymentData} paymentData
10271
10367
  * @returns {Promise<object>}
10272
10368
  */
10273
- async preparePaymentDataForCartUpdate(paymentData) {
10369
+ async processPaymentData(paymentData) {
10274
10370
  const { email, shippingAddress, shippingOptionData, paymentMethodData } =
10275
10371
  paymentData;
10276
10372
 
@@ -10279,7 +10375,7 @@ class AuthorizeNetGooglePayment extends AbstractGooglePayment {
10279
10375
  tokenizationData: { token },
10280
10376
  } = paymentMethodData;
10281
10377
 
10282
- return {
10378
+ await this.updateCart({
10283
10379
  account: { email },
10284
10380
  billing: {
10285
10381
  method: 'google',
@@ -10289,15 +10385,15 @@ class AuthorizeNetGooglePayment extends AbstractGooglePayment {
10289
10385
  gateway: 'authorizenet',
10290
10386
  token: base64Encode(token),
10291
10387
  },
10292
- ...convertToSwellAddress$2(billingAddress),
10388
+ ...convertToSwellAddress$3(billingAddress),
10293
10389
  },
10294
10390
  ...(shippingAddress && {
10295
10391
  shipping: {
10296
- ...convertToSwellAddress$2(shippingAddress),
10392
+ ...convertToSwellAddress$3(shippingAddress),
10297
10393
  service: shippingOptionData?.id || undefined,
10298
10394
  },
10299
10395
  }),
10300
- };
10396
+ });
10301
10397
  }
10302
10398
  }
10303
10399
 
@@ -10412,6 +10508,10 @@ class AbstractApplePayment extends Payment {
10412
10508
  requiredShippingContactFields,
10413
10509
  requiredBillingContactFields,
10414
10510
  supportsCouponCode: true,
10511
+ recurringPaymentRequest: getRecurringPaymentRequest(
10512
+ cart,
10513
+ this.params.managementUrl,
10514
+ ),
10415
10515
  lineItems: getLineItems(cart),
10416
10516
  };
10417
10517
  }
@@ -10434,7 +10534,7 @@ class AbstractApplePayment extends Payment {
10434
10534
  * @returns {Promise<object>}
10435
10535
  */
10436
10536
  // eslint-disable-next-line no-unused-vars
10437
- async preparePaymentDataForCartUpdate(event) {
10537
+ async processPaymentData(event) {
10438
10538
  throw new Error('Implement this!');
10439
10539
  }
10440
10540
 
@@ -10492,9 +10592,7 @@ class AbstractApplePayment extends Payment {
10492
10592
  //
10493
10593
  // We store the payment token but DO NOT process the order yet.
10494
10594
  // The user must manually click "Place Order" to complete the transaction.
10495
- await this.preparePaymentDataForCartUpdate(event).then((data) =>
10496
- this.updateCart(data),
10497
- );
10595
+ await this.processPaymentData(event);
10498
10596
 
10499
10597
  // Complete Apple Pay session successfully
10500
10598
  // This closes the Apple Pay sheet and shows success to the user
@@ -10630,12 +10728,12 @@ class AuthorizeNetApplePayment extends AbstractApplePayment {
10630
10728
  * @param {ApplePayJS.ApplePayPaymentAuthorizedEvent} event
10631
10729
  * @returns {Promise<object>}
10632
10730
  */
10633
- async preparePaymentDataForCartUpdate(event) {
10731
+ async processPaymentData(event) {
10634
10732
  const {
10635
10733
  payment: { token, shippingContact, billingContact },
10636
10734
  } = event;
10637
10735
 
10638
- return {
10736
+ return this.updateCart({
10639
10737
  account: {
10640
10738
  email: shippingContact?.emailAddress || billingContact?.emailAddress,
10641
10739
  },
@@ -10647,12 +10745,12 @@ class AuthorizeNetApplePayment extends AbstractApplePayment {
10647
10745
  gateway: 'authorizenet',
10648
10746
  token: base64Encode(JSON.stringify(token.paymentData)),
10649
10747
  },
10650
- ...convertToSwellAddress$1(billingContact),
10748
+ ...convertToSwellAddress$2(billingContact),
10651
10749
  },
10652
10750
  ...(shippingContact && {
10653
- shipping: convertToSwellAddress$1(shippingContact),
10751
+ shipping: convertToSwellAddress$2(shippingContact),
10654
10752
  }),
10655
- };
10753
+ });
10656
10754
  }
10657
10755
  }
10658
10756
 
@@ -10829,7 +10927,7 @@ class ConvesioCardPayment extends Payment {
10829
10927
  ''
10830
10928
  ).replace(/[^0-9]+/g, '');
10831
10929
 
10832
- const cardExpiry = cardApi.expiry(
10930
+ const cardExpiry = this.api.card.expiry(
10833
10931
  this.params.exp ||
10834
10932
  document.getElementById(
10835
10933
  this.params.cardExpiry?.elementId || 'cardExpiry-element',
@@ -10853,7 +10951,7 @@ class ConvesioCardPayment extends Payment {
10853
10951
  ''
10854
10952
  ).trim();
10855
10953
 
10856
- const cardBrand = cardApi.type(cardNumber).toLowerCase();
10954
+ const cardBrand = this.api.card.type(cardNumber).toLowerCase();
10857
10955
 
10858
10956
  const payment = await createConvesioCardPaymentToken(this.method, {
10859
10957
  paymentMethod: {
@@ -11020,7 +11118,7 @@ class ConvesioPayApplePayment extends AbstractApplePayment {
11020
11118
  * @param {ApplePayJS.ApplePayPaymentAuthorizedEvent} event
11021
11119
  * @returns {Promise<object>}
11022
11120
  */
11023
- async preparePaymentDataForCartUpdate(event) {
11121
+ async processPaymentData(event) {
11024
11122
  const {
11025
11123
  payment: { token, shippingContact, billingContact },
11026
11124
  } = event;
@@ -11044,7 +11142,7 @@ class ConvesioPayApplePayment extends AbstractApplePayment {
11044
11142
  },
11045
11143
  );
11046
11144
 
11047
- return {
11145
+ return this.updateCart({
11048
11146
  account: {
11049
11147
  email: shippingContact?.emailAddress || billingContact?.emailAddress,
11050
11148
  },
@@ -11059,12 +11157,12 @@ class ConvesioPayApplePayment extends AbstractApplePayment {
11059
11157
  convesiopay: {
11060
11158
  return_url: this.params.returnUrl,
11061
11159
  },
11062
- ...convertToSwellAddress$1(billingContact),
11160
+ ...convertToSwellAddress$2(billingContact),
11063
11161
  },
11064
11162
  ...(shippingContact && {
11065
- shipping: convertToSwellAddress$1(shippingContact),
11163
+ shipping: convertToSwellAddress$2(shippingContact),
11066
11164
  }),
11067
- };
11165
+ });
11068
11166
  }
11069
11167
  }
11070
11168
 
@@ -11190,7 +11288,7 @@ class ConvesioPayGooglePayment extends AbstractGooglePayment {
11190
11288
  * @param {google.payments.api.PaymentData} paymentData
11191
11289
  * @returns {Promise<object>}
11192
11290
  */
11193
- async preparePaymentDataForCartUpdate(paymentData) {
11291
+ async processPaymentData(paymentData) {
11194
11292
  const { email, shippingAddress, shippingOptionData, paymentMethodData } =
11195
11293
  paymentData;
11196
11294
 
@@ -11218,7 +11316,7 @@ class ConvesioPayGooglePayment extends AbstractGooglePayment {
11218
11316
  },
11219
11317
  );
11220
11318
 
11221
- return {
11319
+ return this.updateCart({
11222
11320
  account: { email },
11223
11321
  billing: {
11224
11322
  method: 'google',
@@ -11231,15 +11329,15 @@ class ConvesioPayGooglePayment extends AbstractGooglePayment {
11231
11329
  convesiopay: {
11232
11330
  return_url: this.params.returnUrl,
11233
11331
  },
11234
- ...convertToSwellAddress$2(billingAddress),
11332
+ ...convertToSwellAddress$3(billingAddress),
11235
11333
  },
11236
11334
  ...(shippingAddress && {
11237
11335
  shipping: {
11238
- ...convertToSwellAddress$2(shippingAddress),
11336
+ ...convertToSwellAddress$3(shippingAddress),
11239
11337
  service: shippingOptionData?.id || undefined,
11240
11338
  },
11241
11339
  }),
11242
- };
11340
+ });
11243
11341
  }
11244
11342
  }
11245
11343
 
@@ -11442,12 +11540,26 @@ function getKlarnaSessionData(cart) {
11442
11540
  };
11443
11541
  }
11444
11542
 
11543
+ /** @typedef {import('@paypal/paypal-js').PayPalNamespace} PayPal */
11544
+ /** @typedef {import('@paypal/paypal-js').ShippingAddress} ShippingAddress */
11545
+ /** @typedef {import('@paypal/paypal-js').CreateOrderData} CreateOrderData */
11546
+ /** @typedef {import('@paypal/paypal-js').CreateOrderActions} CreateOrderActions */
11547
+ /** @typedef {import('@paypal/paypal-js').OnShippingAddressChangeData} OnShippingAddressChangeData */
11548
+ /** @typedef {import('@paypal/paypal-js').OnShippingAddressChangeActions} OnShippingAddressChangeActions */
11549
+ /** @typedef {import('@paypal/paypal-js').OnShippingOptionsChangeData} OnShippingOptionsChangeData */
11550
+ /** @typedef {import('@paypal/paypal-js').OnShippingOptionsChangeActions} OnShippingOptionsChangeActions */
11551
+ /** @typedef {import('@paypal/paypal-js').OnApproveData} OnApproveData */
11552
+ /** @typedef {import('@paypal/paypal-js').OnApproveActions} OnApproveActions */
11553
+ /** @typedef {import('../../../types').Cart} Cart */
11554
+ /** @typedef {import('../../../types').Address} Address */
11555
+
11445
11556
  class PaypalDirectPayment extends Payment {
11446
11557
  constructor(api, options, params, methods) {
11447
11558
  super(api, options, params, methods.paypal);
11448
11559
  }
11449
11560
 
11450
- get scripts() {
11561
+ /** @param {Cart} cart */
11562
+ getScripts(cart) {
11451
11563
  const { client_id } = this.method;
11452
11564
 
11453
11565
  return [
@@ -11457,11 +11569,13 @@ class PaypalDirectPayment extends Payment {
11457
11569
  client_id,
11458
11570
  merchant_id: this.merchantId,
11459
11571
  cart: ['currency'],
11572
+ vault: cart.subscription_delivery,
11460
11573
  },
11461
11574
  },
11462
11575
  ];
11463
11576
  }
11464
11577
 
11578
+ /** @returns {PayPal} */
11465
11579
  get paypal() {
11466
11580
  if (!window.paypal) {
11467
11581
  throw new LibraryNotLoadedError('PayPal');
@@ -11485,7 +11599,6 @@ class PaypalDirectPayment extends Payment {
11485
11599
  async createElements(cart) {
11486
11600
  const {
11487
11601
  elementId = 'paypal-button',
11488
- locale = 'en_US',
11489
11602
  style: {
11490
11603
  layout = 'horizontal',
11491
11604
  height = 45,
@@ -11494,15 +11607,16 @@ class PaypalDirectPayment extends Payment {
11494
11607
  label = 'paypal',
11495
11608
  tagline = false,
11496
11609
  } = {},
11610
+ require: { shipping: requireShipping = true } = {},
11497
11611
  } = this.params;
11498
11612
 
11499
11613
  this.setElementContainer(elementId);
11500
11614
 
11501
11615
  this._validateCart(cart);
11502
- await this.loadScripts(this.scripts);
11616
+ await this.loadScripts(this.getScripts(cart));
11503
11617
 
11504
- this.element = this.paypal.Buttons({
11505
- locale,
11618
+ /** @type {import('@paypal/paypal-js').PayPalButtonsComponentOptions} */
11619
+ const buttonsOptions = {
11506
11620
  style: {
11507
11621
  layout,
11508
11622
  height,
@@ -11511,11 +11625,27 @@ class PaypalDirectPayment extends Payment {
11511
11625
  label,
11512
11626
  tagline,
11513
11627
  },
11628
+ fundingSource: this.paypal.FUNDING.PAYPAL,
11514
11629
  createOrder: this._onCreateOrder.bind(this, cart),
11515
- onShippingChange: this._onShippingChange.bind(this),
11516
11630
  onApprove: this._onApprove.bind(this),
11517
11631
  onError: this.onError.bind(this),
11518
- });
11632
+ };
11633
+
11634
+ if (requireShipping) {
11635
+ buttonsOptions.onShippingAddressChange =
11636
+ this._onShippingAddressChange.bind(this);
11637
+
11638
+ buttonsOptions.onShippingOptionsChange =
11639
+ this._onShippingOptionsChange.bind(this);
11640
+ }
11641
+
11642
+ const component = this.paypal.Buttons(buttonsOptions);
11643
+
11644
+ if (!component.isEligible()) {
11645
+ throw new Error('PayPal button with provided options is not eligible.');
11646
+ }
11647
+
11648
+ this.element = component;
11519
11649
  }
11520
11650
 
11521
11651
  mountElements() {
@@ -11529,6 +11659,7 @@ class PaypalDirectPayment extends Payment {
11529
11659
  }
11530
11660
  }
11531
11661
 
11662
+ /** @param {Cart} cart */
11532
11663
  _validateCart(cart) {
11533
11664
  const hasSubscriptionProduct = Boolean(cart.subscription_delivery);
11534
11665
 
@@ -11538,27 +11669,35 @@ class PaypalDirectPayment extends Payment {
11538
11669
  );
11539
11670
  }
11540
11671
 
11541
- if (!(cart.capture_total > 0)) {
11672
+ if ((cart.capture_total || 0) <= 0) {
11542
11673
  throw new Error(
11543
11674
  'Invalid PayPal button amount. Value should be greater than zero.',
11544
11675
  );
11545
11676
  }
11546
11677
  }
11547
11678
 
11679
+ /**
11680
+ * @param {Cart} cart
11681
+ * @param {CreateOrderData} _data
11682
+ * @param {CreateOrderActions} _actions
11683
+ * @returns {Promise<string>}
11684
+ */
11548
11685
  async _onCreateOrder(cart, _data, _actions) {
11549
- const { require: { shipping: requireShipping = true } = {} } = this.params;
11686
+ const {
11687
+ locale = 'en-US',
11688
+ require: { shipping: requireShipping = true } = {},
11689
+ } = this.params;
11690
+
11550
11691
  const { capture_total, currency, subscription_delivery } = cart;
11551
11692
  const hasSubscriptionProduct = Boolean(subscription_delivery);
11552
11693
  const merchantId = this.merchantId;
11553
11694
  const returnUrl = this.returnUrl;
11554
- const orderData = {
11555
- application_context: {
11556
- shipping_preference: requireShipping ? 'GET_FROM_FILE' : 'NO_SHIPPING',
11557
- },
11558
- };
11695
+ /** @type {import('@paypal/paypal-js').CreateOrderRequestBody} */
11696
+ const orderData = {};
11697
+ /** @type {import('@paypal/paypal-js').PurchaseUnit} */
11559
11698
  const purchaseUnit = {
11560
11699
  amount: {
11561
- value: Number(capture_total.toFixed(2)),
11700
+ value: Number(capture_total).toFixed(2),
11562
11701
  currency_code: currency,
11563
11702
  },
11564
11703
  };
@@ -11566,29 +11705,44 @@ class PaypalDirectPayment extends Payment {
11566
11705
  if (merchantId) {
11567
11706
  // express checkout and ppcp
11568
11707
  orderData.intent = 'AUTHORIZE';
11708
+
11709
+ orderData.payment_source = {
11710
+ paypal: {
11711
+ experience_context: {
11712
+ locale,
11713
+ shipping_preference: requireShipping
11714
+ ? 'GET_FROM_FILE'
11715
+ : 'NO_SHIPPING',
11716
+ },
11717
+ },
11718
+ };
11719
+
11569
11720
  purchaseUnit.payee = {
11570
11721
  merchant_id: merchantId,
11571
11722
  };
11572
11723
 
11573
11724
  if (hasSubscriptionProduct) {
11574
- orderData.payment_source = {
11575
- paypal: {
11576
- attributes: {
11577
- vault: {
11578
- store_in_vault: 'ON_SUCCESS',
11579
- usage_type: 'MERCHANT',
11580
- },
11581
- },
11582
- experience_context: {
11583
- return_url: `${returnUrl}&redirect_status=succeeded`,
11584
- cancel_url: `${returnUrl}&redirect_status=canceled`,
11585
- },
11725
+ orderData.payment_source.paypal.attributes = {
11726
+ vault: {
11727
+ store_in_vault: 'ON_SUCCESS',
11728
+ usage_type: 'MERCHANT',
11586
11729
  },
11587
11730
  };
11731
+
11732
+ Object.assign(orderData.payment_source.paypal.experience_context, {
11733
+ return_url: `${returnUrl}&redirect_status=succeeded`,
11734
+ cancel_url: `${returnUrl}&redirect_status=canceled`,
11735
+ });
11588
11736
  }
11589
11737
  } else {
11590
11738
  // progressive checkout
11591
11739
  orderData.intent = 'CAPTURE';
11740
+
11741
+ orderData.application_context = {
11742
+ locale,
11743
+ shipping_preference: requireShipping ? 'GET_FROM_FILE' : 'NO_SHIPPING',
11744
+ };
11745
+
11592
11746
  purchaseUnit.payee = {
11593
11747
  email_address: this.method.store_owner_email,
11594
11748
  };
@@ -11604,44 +11758,37 @@ class PaypalDirectPayment extends Payment {
11604
11758
  return order.id;
11605
11759
  }
11606
11760
 
11607
- async _onShippingChange(data, actions) {
11761
+ /**
11762
+ * @param {OnShippingAddressChangeData} data
11763
+ * @param {OnShippingAddressChangeActions} actions
11764
+ */
11765
+ async _onShippingAddressChange(data, actions) {
11608
11766
  try {
11609
- const { orderID, shipping_address, selected_shipping_option } = data;
11610
- const updateData = {
11767
+ const { orderID, shippingAddress } = data;
11768
+
11769
+ const cart = await this.updateCart({
11611
11770
  shipping: {
11612
- state: shipping_address.state,
11613
- city: shipping_address.city,
11614
- zip: shipping_address.postal_code,
11615
- country: shipping_address.country_code,
11771
+ state: shippingAddress.state,
11772
+ city: shippingAddress.city,
11773
+ zip: shippingAddress.postalCode,
11774
+ country: shippingAddress.countryCode,
11616
11775
  },
11617
11776
  shipment_rating: null,
11618
- };
11619
-
11620
- if (selected_shipping_option) {
11621
- updateData.shipping.service = selected_shipping_option.id;
11622
- updateData.$taxes = true;
11623
- }
11777
+ });
11624
11778
 
11625
- const cart = await this.updateCart(updateData);
11626
- const shippingServices = get(cart, 'shipment_rating.services');
11779
+ const shippingServices = cart.shipment_rating?.services;
11627
11780
 
11628
- // can't fulfill shipping to selected address
11781
+ // Can't fulfill shipping to selected address
11629
11782
  if (isEmpty(shippingServices)) {
11630
11783
  return actions.reject();
11631
11784
  }
11632
11785
 
11633
- let selectedShippingService;
11634
-
11635
- if (selected_shipping_option) {
11636
- selectedShippingService = shippingServices.find(
11637
- (shippingService) =>
11638
- shippingService.id === selected_shipping_option.id,
11639
- );
11640
- }
11786
+ let selectedShippingService = cart.shipping?.service;
11641
11787
 
11642
11788
  // need to set first service for cart by default
11643
11789
  if (!selectedShippingService) {
11644
11790
  const [firstShippingService] = shippingServices;
11791
+ selectedShippingService = firstShippingService.id;
11645
11792
 
11646
11793
  await this.updateCart({
11647
11794
  shipping: {
@@ -11658,8 +11805,33 @@ class PaypalDirectPayment extends Payment {
11658
11805
  paypal_order_id: orderID,
11659
11806
  },
11660
11807
  });
11808
+ } catch (error) {
11809
+ this.onError(error);
11810
+
11811
+ return actions.reject();
11812
+ }
11813
+ }
11814
+
11815
+ /**
11816
+ * @param {OnShippingOptionsChangeData} data
11817
+ * @param {OnShippingOptionsChangeActions} actions
11818
+ */
11819
+ async _onShippingOptionsChange(data, actions) {
11820
+ try {
11821
+ const { orderID, selectedShippingOption } = data;
11822
+
11823
+ const cart = await this.updateCart({
11824
+ shipping: { service: selectedShippingOption.id },
11825
+ $taxes: true,
11826
+ });
11661
11827
 
11662
- return orderID;
11828
+ await this.updateIntent({
11829
+ gateway: 'paypal',
11830
+ intent: {
11831
+ cart_id: cart.id,
11832
+ paypal_order_id: orderID,
11833
+ },
11834
+ });
11663
11835
  } catch (error) {
11664
11836
  this.onError(error);
11665
11837
 
@@ -11667,14 +11839,17 @@ class PaypalDirectPayment extends Payment {
11667
11839
  }
11668
11840
  }
11669
11841
 
11842
+ /**
11843
+ * @param {OnApproveData} data
11844
+ * @param {OnApproveActions} actions
11845
+ */
11670
11846
  async _onApprove(data, actions) {
11671
- const { require: { shipping: requireShipping = true } = {} } = this.params;
11672
11847
  const order = await actions.order.get();
11673
11848
  const orderId = order.id;
11674
- const payer = order.payer;
11849
+ const payer = order.payment_source?.paypal || order.payer;
11675
11850
  const billing = payer.address;
11676
- const shipping = get(order, 'purchase_units[0].shipping');
11677
- const name = `${payer.name.given_name} ${payer.name.surname}`;
11851
+ const shipping = order.purchase_units?.[0]?.shipping;
11852
+ const name = `${payer.name?.given_name} ${payer.name?.surname}`;
11678
11853
 
11679
11854
  await this.updateCart({
11680
11855
  account: {
@@ -11686,31 +11861,35 @@ class PaypalDirectPayment extends Payment {
11686
11861
  order_id: orderId,
11687
11862
  },
11688
11863
  name,
11689
- ...this._mapAddress(billing),
11864
+ ...convertToSwellAddress$1(billing),
11690
11865
  },
11691
- ...(requireShipping && {
11866
+ ...(shipping?.address && {
11692
11867
  shipping: {
11693
11868
  first_name: payer.name.given_name,
11694
11869
  last_name: payer.name.surname,
11695
11870
  name: shipping.name.full_name,
11696
- ...this._mapAddress(shipping.address),
11871
+ ...convertToSwellAddress$1(shipping.address),
11697
11872
  },
11698
11873
  }),
11699
11874
  });
11700
11875
 
11701
11876
  this.onSuccess();
11702
11877
  }
11878
+ }
11703
11879
 
11704
- _mapAddress(address) {
11705
- return {
11706
- address1: address.address_line_1,
11707
- address2: address.address_line_2,
11708
- state: address.admin_area_1,
11709
- city: address.admin_area_2,
11710
- zip: address.postal_code,
11711
- country: address.country_code,
11712
- };
11713
- }
11880
+ /**
11881
+ * @param {ShippingAddress} address
11882
+ * @returns {Address}
11883
+ */
11884
+ function convertToSwellAddress$1(address) {
11885
+ return {
11886
+ address1: address.address_line_1,
11887
+ address2: address.address_line_2,
11888
+ state: address.admin_area_1,
11889
+ city: address.admin_area_2,
11890
+ zip: address.postal_code,
11891
+ country: address.country_code,
11892
+ };
11714
11893
  }
11715
11894
 
11716
11895
  class AmazonDirectPayment extends Payment {
@@ -12477,7 +12656,7 @@ class PaymentController {
12477
12656
  }
12478
12657
 
12479
12658
  async _vaultRequest(method, url, data) {
12480
- const response = await vaultRequest(method, url, data);
12659
+ const response = await vaultRequest(method, url, data, this.options);
12481
12660
 
12482
12661
  if (this.options.useCamelCase) {
12483
12662
  return toCamel(response);
@@ -13031,7 +13210,7 @@ function swell(initStore = undefined, initKey, initOptions = {}) {
13031
13210
  const api = {};
13032
13211
 
13033
13212
  Object.assign(api, {
13034
- version: '5.8.1',
13213
+ version: '5.9.0',
13035
13214
  options,
13036
13215
  request,
13037
13216
 
@@ -13061,8 +13240,6 @@ function swell(initStore = undefined, initKey, initOptions = {}) {
13061
13240
  options.getCart = opt.getCart;
13062
13241
  options.updateCart = opt.updateCart;
13063
13242
  options.headers = opt.headers || {};
13064
-
13065
- setOptions(options);
13066
13243
  },
13067
13244
 
13068
13245
  // Backward compatibility
@@ -13086,9 +13263,9 @@ function swell(initStore = undefined, initKey, initOptions = {}) {
13086
13263
  return api.request('delete', url, data);
13087
13264
  },
13088
13265
 
13089
- cache: cacheApi,
13266
+ cache: methods$d(options),
13090
13267
 
13091
- card: cardApi,
13268
+ card: methods$e(options),
13092
13269
 
13093
13270
  cart: methods$a(api, options),
13094
13271
 
@@ -13122,9 +13299,13 @@ function swell(initStore = undefined, initKey, initOptions = {}) {
13122
13299
 
13123
13300
  utils,
13124
13301
 
13125
- getCookie,
13302
+ getCookie(name) {
13303
+ return (options.getCookie || getCookie)(name);
13304
+ },
13126
13305
 
13127
- setCookie,
13306
+ setCookie(name, value, cookieOptions) {
13307
+ return (options.setCookie || setCookie)(name, value, cookieOptions);
13308
+ },
13128
13309
  });
13129
13310
 
13130
13311
  async function request(