@rebilly/instruments 2.0.0-beta → 3.0.1-beta.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 (197) hide show
  1. package/dist/events/index.js +2 -1
  2. package/dist/functions/mount/fetch-data.js +187 -0
  3. package/dist/functions/mount/fetch-data.spec.js +189 -0
  4. package/dist/functions/mount/index.js +132 -164
  5. package/dist/functions/mount/mount.spec.js +2 -4
  6. package/dist/functions/mount/setup-element.js +40 -0
  7. package/dist/functions/mount/setup-framepay-theme.js +95 -0
  8. package/dist/functions/mount/setup-framepay.js +5 -1
  9. package/dist/functions/mount/setup-i18n.js +33 -0
  10. package/dist/functions/mount/setup-options.js +68 -47
  11. package/dist/functions/mount/setup-options.spec.js +66 -0
  12. package/dist/functions/mount/setup-storefront.js +6 -4
  13. package/dist/functions/mount/setup-styles.js +4 -2
  14. package/dist/functions/purchase.js +129 -24
  15. package/dist/functions/purchase.spec.js +13 -10
  16. package/dist/functions/setup.js +85 -0
  17. package/dist/functions/setup.spec.js +87 -0
  18. package/dist/functions/show.js +8 -4
  19. package/dist/functions/show.spec.js +9 -5
  20. package/dist/functions/update.js +39 -24
  21. package/dist/functions/update.spec.js +0 -4
  22. package/dist/i18n/en.json +5 -2
  23. package/dist/i18n/es.json +4 -1
  24. package/dist/index.js +17 -3
  25. package/dist/index.spec.js +3 -16
  26. package/dist/loader/index.js +4 -3
  27. package/dist/storefront/index.js +33 -0
  28. package/dist/storefront/invoices.js +27 -0
  29. package/dist/storefront/models/base-model.js +18 -0
  30. package/dist/storefront/models/invoice-model.js +14 -0
  31. package/dist/storefront/models/plan-model.js +4 -35
  32. package/dist/storefront/models/product-model.js +4 -23
  33. package/dist/storefront/models/summary-model.js +12 -25
  34. package/dist/storefront/models/transaction-model.js +31 -0
  35. package/dist/storefront/payment-instruments.js +47 -0
  36. package/dist/storefront/payment-instruments.spec.js +55 -0
  37. package/dist/storefront/plans.js +10 -18
  38. package/dist/storefront/plans.spec.js +3 -13
  39. package/dist/storefront/products.js +10 -13
  40. package/dist/storefront/products.spec.js +12 -19
  41. package/dist/storefront/purchase.js +23 -12
  42. package/dist/storefront/purchase.spec.js +1 -20
  43. package/dist/storefront/ready-to-pay.js +18 -15
  44. package/dist/storefront/ready-to-pay.spec.js +2 -12
  45. package/dist/storefront/summary.js +21 -17
  46. package/dist/storefront/summary.spec.js +4 -15
  47. package/dist/storefront/transactions.js +27 -0
  48. package/dist/style/base/__snapshots__/theme.spec.js.snap +188 -45
  49. package/dist/style/base/default-theme.js +699 -0
  50. package/dist/style/base/index.js +48 -16
  51. package/dist/style/base/theme.js +16 -48
  52. package/dist/style/base/theme.spec.js +4 -15
  53. package/dist/style/components/address.js +3 -3
  54. package/dist/style/components/button.js +32 -22
  55. package/dist/style/components/divider.js +9 -9
  56. package/dist/style/components/forms/checkbox.js +12 -9
  57. package/dist/style/components/forms/field.js +18 -6
  58. package/dist/style/components/forms/form.js +2 -2
  59. package/dist/style/components/forms/input.js +54 -13
  60. package/dist/style/components/forms/label.js +39 -18
  61. package/dist/style/components/forms/select.js +54 -22
  62. package/dist/style/components/forms/validation.js +53 -6
  63. package/dist/style/components/icons.js +4 -4
  64. package/dist/style/components/loader.js +5 -3
  65. package/dist/style/components/methods.js +18 -15
  66. package/dist/style/components/overlay.js +5 -5
  67. package/dist/style/helpers/index.js +46 -46
  68. package/dist/style/index.js +3 -1
  69. package/dist/style/payment-instruments/payment-card.js +4 -4
  70. package/dist/style/utils/border.js +47 -0
  71. package/dist/style/utils/color-values.js +39 -3
  72. package/dist/style/utils/remove-empty-null.js +20 -0
  73. package/dist/style/vendor/framepay.js +11 -8
  74. package/dist/style/vendor/postmate.js +2 -2
  75. package/dist/style/views/confirmation.js +13 -13
  76. package/dist/style/views/method-selector.js +2 -2
  77. package/dist/style/views/modal.js +6 -6
  78. package/dist/style/views/result.js +4 -4
  79. package/dist/style/views/summary.js +26 -22
  80. package/dist/views/__snapshots__/summary.spec.js.snap +77 -119
  81. package/dist/views/common/iframe/base-iframe.js +2 -0
  82. package/dist/views/common/iframe/modal-iframe.js +50 -4
  83. package/dist/views/confirmation.js +19 -8
  84. package/dist/views/method-selector/generate-digital-wallet.js +12 -3
  85. package/dist/views/method-selector/generate-digital-wallet.spec.js +11 -0
  86. package/dist/views/method-selector/get-payment-methods.js +13 -2
  87. package/dist/views/method-selector/get-payment-methods.spec.js +21 -19
  88. package/dist/views/method-selector/index.js +23 -34
  89. package/dist/views/method-selector/method-selector.spec.js +50 -55
  90. package/dist/views/method-selector/mount-methods.js +5 -8
  91. package/dist/views/modal.js +8 -2
  92. package/dist/views/result.js +3 -4
  93. package/dist/views/summary.js +156 -97
  94. package/dist/views/summary.spec.js +53 -58
  95. package/package.json +4 -2
  96. package/src/events/index.js +2 -1
  97. package/src/functions/mount/fetch-data.js +152 -0
  98. package/src/functions/mount/fetch-data.spec.js +238 -0
  99. package/src/functions/mount/index.js +101 -158
  100. package/src/functions/mount/mount.spec.js +3 -5
  101. package/src/functions/mount/setup-element.js +26 -0
  102. package/src/functions/mount/setup-framepay-theme.js +82 -0
  103. package/src/functions/mount/setup-framepay.js +5 -1
  104. package/src/functions/mount/setup-i18n.js +19 -0
  105. package/src/functions/mount/setup-options.js +78 -48
  106. package/src/functions/mount/setup-options.spec.js +60 -0
  107. package/src/functions/mount/setup-storefront.js +6 -4
  108. package/src/functions/mount/setup-styles.js +4 -2
  109. package/src/functions/on.spec.js +1 -1
  110. package/src/functions/purchase.js +99 -23
  111. package/src/functions/purchase.spec.js +10 -10
  112. package/src/functions/setup.js +48 -0
  113. package/src/functions/setup.spec.js +98 -0
  114. package/src/functions/show.js +2 -4
  115. package/src/functions/show.spec.js +3 -4
  116. package/src/functions/update.js +40 -25
  117. package/src/functions/update.spec.js +0 -4
  118. package/src/i18n/en.json +5 -2
  119. package/src/i18n/es.json +4 -1
  120. package/src/index.js +9 -3
  121. package/src/index.spec.js +3 -21
  122. package/src/loader/index.js +3 -3
  123. package/src/storefront/index.js +28 -0
  124. package/src/storefront/invoices.js +11 -0
  125. package/src/storefront/models/base-model.js +10 -0
  126. package/src/storefront/models/invoice-model.js +3 -0
  127. package/src/storefront/models/plan-model.js +3 -35
  128. package/src/storefront/models/product-model.js +3 -23
  129. package/src/storefront/models/summary-model.js +12 -19
  130. package/src/storefront/models/transaction-model.js +19 -0
  131. package/src/storefront/payment-instruments.js +30 -0
  132. package/src/storefront/payment-instruments.spec.js +69 -0
  133. package/src/storefront/plans.js +6 -17
  134. package/src/storefront/plans.spec.js +4 -11
  135. package/src/storefront/products.js +8 -16
  136. package/src/storefront/products.spec.js +16 -22
  137. package/src/storefront/purchase.js +14 -16
  138. package/src/storefront/purchase.spec.js +2 -14
  139. package/src/storefront/ready-to-pay.js +13 -16
  140. package/src/storefront/ready-to-pay.spec.js +3 -10
  141. package/src/storefront/summary.js +19 -17
  142. package/src/storefront/summary.spec.js +5 -12
  143. package/src/storefront/transactions.js +11 -0
  144. package/src/style/base/__snapshots__/theme.spec.js.snap +188 -45
  145. package/src/style/base/default-theme.js +674 -0
  146. package/src/style/base/index.js +48 -16
  147. package/src/style/base/theme.js +17 -47
  148. package/src/style/base/theme.spec.js +4 -16
  149. package/src/style/components/address.js +3 -3
  150. package/src/style/components/button.js +32 -24
  151. package/src/style/components/divider.js +9 -9
  152. package/src/style/components/forms/checkbox.js +11 -11
  153. package/src/style/components/forms/field.js +18 -6
  154. package/src/style/components/forms/form.js +2 -2
  155. package/src/style/components/forms/input.js +54 -13
  156. package/src/style/components/forms/label.js +39 -18
  157. package/src/style/components/forms/select.js +54 -22
  158. package/src/style/components/forms/validation.js +53 -6
  159. package/src/style/components/icons.js +4 -4
  160. package/src/style/components/loader.js +4 -5
  161. package/src/style/components/methods.js +18 -15
  162. package/src/style/components/overlay.js +5 -5
  163. package/src/style/helpers/index.js +46 -46
  164. package/src/style/index.js +2 -1
  165. package/src/style/payment-instruments/payment-card.js +4 -4
  166. package/src/style/utils/border.js +34 -0
  167. package/src/style/utils/color-values.js +27 -1
  168. package/src/style/utils/remove-empty-null.js +10 -0
  169. package/src/style/vendor/framepay.js +11 -8
  170. package/src/style/vendor/postmate.js +2 -2
  171. package/src/style/views/confirmation.js +13 -13
  172. package/src/style/views/method-selector.js +2 -2
  173. package/src/style/views/modal.js +6 -6
  174. package/src/style/views/result.js +4 -4
  175. package/src/style/views/summary.js +26 -22
  176. package/src/views/__snapshots__/summary.spec.js.snap +77 -119
  177. package/src/views/common/iframe/base-iframe.js +2 -0
  178. package/src/views/common/iframe/modal-iframe.js +45 -3
  179. package/src/views/confirmation.js +15 -5
  180. package/src/views/method-selector/generate-digital-wallet.js +10 -3
  181. package/src/views/method-selector/generate-digital-wallet.spec.js +10 -0
  182. package/src/views/method-selector/get-payment-methods.js +7 -2
  183. package/src/views/method-selector/get-payment-methods.spec.js +26 -23
  184. package/src/views/method-selector/index.js +21 -28
  185. package/src/views/method-selector/method-selector.spec.js +49 -64
  186. package/src/views/method-selector/mount-methods.js +5 -8
  187. package/src/views/modal.js +6 -2
  188. package/src/views/result.js +4 -3
  189. package/src/views/summary.js +161 -117
  190. package/src/views/summary.spec.js +60 -75
  191. package/tests/mocks/rebilly-instruments-mock.js +37 -7
  192. package/tests/mocks/storefront-api-mock.js +8 -0
  193. package/tests/mocks/storefront-mock.js +17 -0
  194. package/dist/functions/mount/fetch-summary-data.js +0 -46
  195. package/dist/functions/mount/fetch-summary-data.spec.js +0 -43
  196. package/src/functions/mount/fetch-summary-data.js +0 -29
  197. package/src/functions/mount/fetch-summary-data.spec.js +0 -40
@@ -15,13 +15,55 @@ export class ModalIframe extends BaseIframe {
15
15
  dispatchRebillyInsturmentEventHandler(this);
16
16
  resizeComponentHandler(this);
17
17
  changeIframeSrcHandler(this);
18
- this.component.on(`${this.name}-close`, (...args) => {
19
- close(...args);
20
- });
21
18
  stopLoaderHandler(this, {
22
19
  loader,
23
20
  section: 'modal',
24
21
  id: 'modal-content'
25
22
  });
23
+
24
+ // Close modal via postmate
25
+ this.component.on(`${this.name}-close`, (...args) => {
26
+ close(...args);
27
+ });
28
+
29
+ // Close modal via postMessage (specifically during approal url flow)
30
+ window.addEventListener('message', async (event) => {
31
+ if(event.data === 'rebilly-instruments-approval-url-close') {
32
+ if (this.state.options.transactionType === 'purchase') {
33
+ this.state.storefront.setSessionToken(this.state.data.token);
34
+
35
+ const [
36
+ {fields: transaction},
37
+ {fields: invoice}
38
+ ] = await Promise.all([
39
+ this.state.storefront.transactions.get({id: this.state.data.transaction.id}),
40
+ this.state.data.invoice?.id
41
+ ? this.state.storefront.invoices.get({id: this.state.data.invoice.id})
42
+ : {fields: null}
43
+ ]);
44
+
45
+ const updatedPurchase = {
46
+ orderId: this.state.data.orderId,
47
+ token: this.state.data.token,
48
+ transaction,
49
+ };
50
+ if (invoice) {
51
+ updatedPurchase.invoice = invoice;
52
+ }
53
+ close(updatedPurchase);
54
+ } else if (this.state.options.transactionType === 'setup') {
55
+ this.state.storefront.setSessionToken(this.state.data.instrument.token);
56
+ const {
57
+ fields: transaction
58
+ } = await this.state.storefront.transactions.get({id: this.state.data.transaction.id});
59
+ close({
60
+ transaction,
61
+ instrument: this.state.data.instrument
62
+ });
63
+ } else {
64
+ close();
65
+ }
66
+ }
67
+ }, false);
26
68
  }
27
69
  }
@@ -1,4 +1,5 @@
1
1
  import { purchase } from '../functions/purchase';
2
+ import { setup } from '../functions/setup';
2
3
  import { ViewIframe } from './common/iframe';
3
4
  import { replaceContent } from './common/render-utilities';
4
5
  import { updateMethodSelector } from './method-selector';
@@ -7,8 +8,11 @@ import { updateSummary } from './summary';
7
8
  export const baseConfirmationHTML =
8
9
  '<div class="rebilly-instruments-confirmation"></div>';
9
10
 
10
- export async function mountConfirmation({ instrument, mainStyle, state }) {
11
- if (instrument.billingAddress && state.summary) {
11
+ export async function mountConfirmation({ payload: instrument, state }) {
12
+ if (
13
+ (instrument.billingAddress && state.summary) &&
14
+ state.data.isPurchase
15
+ ) {
12
16
  updateSummary({ state, instrument });
13
17
  }
14
18
 
@@ -22,7 +26,7 @@ export async function mountConfirmation({ instrument, mainStyle, state }) {
22
26
 
23
27
  const model = {
24
28
  options: state.options,
25
- mainStyle,
29
+ mainStyle: state.mainStyle,
26
30
  instrument
27
31
  };
28
32
  const name = 'rebilly-instruments-confirmation';
@@ -40,6 +44,10 @@ export async function mountConfirmation({ instrument, mainStyle, state }) {
40
44
  purchase({ state, payload: confirmedInstrument });
41
45
  });
42
46
 
47
+ iframe.component.on(`${name}-confirm-setup`, (confirmedInstrument) => {
48
+ setup({ state, payload: confirmedInstrument });
49
+ });
50
+
43
51
  iframe.component.on('choose-another-method', () => {
44
52
  state.iframeComponents = state.iframeComponents.filter((item) => {
45
53
  if (item.name === iframe.name) {
@@ -48,8 +56,10 @@ export async function mountConfirmation({ instrument, mainStyle, state }) {
48
56
  }
49
57
  return true;
50
58
  });
51
- updateSummary({ state });
52
- updateMethodSelector({ state, mainStyle });
59
+ if (state.data.isPurchase) {
60
+ updateSummary({ state });
61
+ }
62
+ updateMethodSelector({ state, mainStyle: state.mainStyle });
53
63
  });
54
64
 
55
65
  state.iframeComponents.push(iframe);
@@ -1,17 +1,24 @@
1
1
  import { getMethodData } from './get-method-data';
2
2
 
3
- export function generateDigitalWallet({ state, summary, EXPRESS_METHODS }) {
3
+ export function generateDigitalWallet({ state, EXPRESS_METHODS }) {
4
4
  const output = {};
5
5
 
6
6
  const { paymentInstruments } = state.options;
7
7
 
8
8
  const transactionData = {
9
- amount: summary.total,
10
- currency: summary.currency,
11
9
  countryCode: state.options.countryCode,
12
10
  label: state.options.websiteId
13
11
  }
14
12
 
13
+ if (state.data?.amountAndCurrency) {
14
+ const {
15
+ amount,
16
+ currency
17
+ } = state.data.amountAndCurrency;
18
+ transactionData.amount = amount;
19
+ transactionData.currency = currency;
20
+ }
21
+
15
22
  EXPRESS_METHODS.forEach(method => {
16
23
  const { METHOD_TYPE } = getMethodData(method);
17
24
 
@@ -1,11 +1,21 @@
1
1
  import { generateDigitalWallet } from './generate-digital-wallet';
2
2
  import ReadyToPayModel from '@/storefront/models/ready-to-pay-model';
3
3
  import SummaryModel from '@/storefront/models/summary-model';
4
+ import { DataInstance } from '../../functions/mount/fetch-data';
4
5
 
5
6
  describe('generateDigitalWallet', () => {
6
7
  class TestInstance {
7
8
  constructor({ options = {} } = {}) {
8
9
  this.options = options;
10
+ this.data = new DataInstance({
11
+ state: {
12
+ options
13
+ },
14
+ previewPurchase: {
15
+ total: 1,
16
+ currency: 'USD'
17
+ }
18
+ });
9
19
  }
10
20
  }
11
21
 
@@ -17,13 +17,13 @@ const isSupportedMethod = ({ method }) => {
17
17
  };
18
18
 
19
19
  // TODO: just loader is used. We could simplify signature
20
- export function getPaymentMethods({ methods, state }) {
20
+ export function getPaymentMethods({ state }) {
21
21
  const result = {
22
22
  EXPRESS_METHODS: [],
23
23
  METHODS: []
24
24
  };
25
25
 
26
- methods.forEach((method) => {
26
+ state.data.readyToPay.forEach((method) => {
27
27
  if (isExpressMethod(method)) {
28
28
  const { METHOD_TYPE } = getMethodData(method);
29
29
  // Add loader entry per express method
@@ -36,5 +36,10 @@ export function getPaymentMethods({ methods, state }) {
36
36
  }
37
37
  });
38
38
 
39
+ if (!window.ApplePaySession) {
40
+ result.EXPRESS_METHODS = result.EXPRESS_METHODS.filter(method => method?.feature?.name !== 'Apple Pay');
41
+ state.loader.stopLoading({ id: 'applePay-express' });
42
+ }
43
+
39
44
  return result;
40
45
  }
@@ -4,36 +4,39 @@ import ReadyToPayModel from '@/storefront/models/ready-to-pay-model';
4
4
  class TestInstance {
5
5
  constructor() {
6
6
  this.loader = {
7
- startLoading: jest.fn()
7
+ startLoading: jest.fn(),
8
+ stopLoading: jest.fn()
8
9
  };
10
+ this.data = {
11
+ readyToPay: [
12
+ new ReadyToPayModel({
13
+ method: 'payment-card',
14
+ feature: {
15
+ name: 'Google Pay',
16
+ merchantName: 'google-pay-merchant-name',
17
+ merchantOrigin: 'google-pay-merchant-origin'
18
+ },
19
+ brands: ['Visa'],
20
+ filters: []
21
+ }),
22
+ new ReadyToPayModel({
23
+ method: 'bitcoin',
24
+ filters: []
25
+ }),
26
+ new ReadyToPayModel({
27
+ method: 'payment-card',
28
+ brands: ['Visa'],
29
+ filters: []
30
+ })
31
+ ]
32
+ }
9
33
  }
10
34
  }
11
35
 
12
36
  it('should only return the allowed methods', () => {
13
37
  const instance = new TestInstance();
14
- const methods = [
15
- new ReadyToPayModel({
16
- method: 'payment-card',
17
- feature: {
18
- name: 'Google Pay',
19
- merchantName: 'google-pay-merchant-name',
20
- merchantOrigin: 'google-pay-merchant-origin'
21
- },
22
- brands: ['Visa'],
23
- filters: []
24
- }),
25
- new ReadyToPayModel({
26
- method: 'bitcoin',
27
- filters: []
28
- }),
29
- new ReadyToPayModel({
30
- method: 'payment-card',
31
- brands: ['Visa'],
32
- filters: []
33
- })
34
- ];
35
38
 
36
- const results = getPaymentMethods({ methods, state: instance });
39
+ const results = getPaymentMethods({ state: instance });
37
40
  expect(results.hasOwnProperty('EXPRESS_METHODS')).toEqual(true);
38
41
  expect(results['EXPRESS_METHODS'].length).toEqual(1);
39
42
  expect(results['METHODS'].length).toEqual(1);
@@ -4,7 +4,7 @@ import { getPaymentMethods } from './get-payment-methods';
4
4
  import { mountExpressMethods } from './mount-express-methods';
5
5
  import { generateDigitalWallet } from './generate-digital-wallet';
6
6
  import { MountMethods } from './mount-methods';
7
- import { fetchSummaryData } from '../../functions/mount/fetch-summary-data';
7
+ import { fetchData } from '../../functions/mount/fetch-data';
8
8
 
9
9
  export const baseMethodSelectorHTML = (compactExpressInstruments) => `
10
10
  <div class="rebilly-instruments-content">
@@ -23,15 +23,11 @@ export const baseMethodSelectorHTML = (compactExpressInstruments) => `
23
23
  </div>
24
24
  `;
25
25
 
26
- export function mountMethodSelector({ state, formOptions }) {
27
- const { readyToPay, summary, plans, products, mainStyle } = formOptions;
28
- const { EXPRESS_METHODS, METHODS } = getPaymentMethods({
29
- methods: readyToPay,
30
- state
31
- });
26
+ export function mountMethodSelector({ state }) {
27
+ const { EXPRESS_METHODS, METHODS } = getPaymentMethods({ state });
32
28
 
33
29
  state.form.innerHTML += baseMethodSelectorHTML(
34
- state.options.paymentInstruments.compactExpressInstruments
30
+ state.options.paymentInstruments.compactExpressInstruments && EXPRESS_METHODS.length
35
31
  );
36
32
 
37
33
  const EXPRESS_METHODS_CONTAINER = document.querySelector(
@@ -46,16 +42,13 @@ export function mountMethodSelector({ state, formOptions }) {
46
42
  '.rebilly-instruments-methods'
47
43
  );
48
44
 
49
- state.options.digitalWallet = generateDigitalWallet({state, summary, EXPRESS_METHODS});
45
+ state.options.digitalWallet = generateDigitalWallet({state, EXPRESS_METHODS});
50
46
 
51
47
  if (METHODS.length) {
52
48
  MountMethods({
53
49
  state,
54
50
  METHODS_CONTAINER,
55
- METHODS,
56
- mainStyle,
57
- plans,
58
- products
51
+ METHODS
59
52
  });
60
53
  } else {
61
54
  METHODS_CONTAINER.style.display = 'none';
@@ -71,29 +64,29 @@ export function mountMethodSelector({ state, formOptions }) {
71
64
  EXPRESS_METHODS_CONTAINER.parentNode.style.display = 'none';
72
65
  }
73
66
 
67
+ if (!METHODS.length && !EXPRESS_METHODS.length) {
68
+ state.form.innerHTML = `
69
+ <p data-rebilly-i18n="form.error.noPaymentMethods">
70
+ No payment methods available for this transaction, please contact support.
71
+ <p>
72
+ `;
73
+ state.form.style.minHeight = 'auto';
74
+ }
75
+
74
76
  state.translate.translateItems();
75
77
 
76
78
  state.loader.stopLoading({ id: 'initForm' });
77
79
  }
78
80
 
79
- export async function updateMethodSelector({ state, mainStyle }) {
81
+ export async function updateMethodSelector({ state }) {
80
82
  state.loader.startLoading({ id: 'initForm' });
81
83
  const { riskMetadata } = await collectData();
82
84
 
83
- const {
84
- readyToPay,
85
- summary: summaryData,
86
- plans,
87
- products
88
- } = await fetchSummaryData({ state, riskMetadata });
85
+ state.data = await fetchData({ state, riskMetadata });
89
86
 
90
- const formOptions = {
91
- summary: summaryData,
92
- readyToPay,
93
- plans,
94
- products,
95
- mainStyle
96
- };
87
+ if (state.data.transaction && state.data.transaction?.type === 'setup') {
88
+ state.options.transactionType = 'setup';
89
+ }
97
90
 
98
91
  state.form
99
92
  .querySelectorAll(':not(.rebilly-instruments-confirmation)')
@@ -106,5 +99,5 @@ export async function updateMethodSelector({ state, mainStyle }) {
106
99
  }
107
100
  });
108
101
 
109
- mountMethodSelector({ state, formOptions });
102
+ mountMethodSelector({ state });
110
103
  }
@@ -5,6 +5,8 @@ import { Translate } from '../../i18n';
5
5
  import { mountMethodSelector, updateMethodSelector } from './index';
6
6
  import { avoidUnhandledPromises } from 'tests/async-utilities';
7
7
  import { MockStorefront } from 'tests/mocks/storefront-mock';
8
+ import { DataInstance } from '../../functions/mount/fetch-data';
9
+ import setupOptions from '../../functions/mount/setup-options';
8
10
 
9
11
  describe('Summary component', () => {
10
12
  let formElement;
@@ -20,11 +22,54 @@ describe('Summary component', () => {
20
22
  loader = new Loader(),
21
23
  translate = new Translate()
22
24
  } = {}) {
23
- this.options = options;
25
+ this.options = setupOptions({options});
24
26
  this.form = form;
25
27
  this.loader = loader;
26
28
  this.translate = translate;
27
29
  this.storefront = MockStorefront();
30
+ this.data = new DataInstance({
31
+ state: {options},
32
+ previewPurchase: new SummaryModel({
33
+ currency: 'USD',
34
+ lineItems: [
35
+ {
36
+ type: 'debit',
37
+ description: 'My Awesome Product',
38
+ unitPrice: 30,
39
+ quantity: 1,
40
+ price: 30,
41
+ productId: 'my-awesome-product',
42
+ planId: 'my-awesome-product'
43
+ },
44
+ {
45
+ type: 'debit',
46
+ description: 'Awesome T-Shirt',
47
+ unitPrice: 20,
48
+ quantity: 2,
49
+ price: 40,
50
+ productId: 'my-app',
51
+ planId: 'awesome-t-shirt'
52
+ }
53
+ ],
54
+ subtotalAmount: 70,
55
+ taxAmount: 0,
56
+ shippingAmount: 0,
57
+ discountsAmount: 0,
58
+ total: 70
59
+ }),
60
+ readyToPay: [
61
+ new ReadyToPayModel({
62
+ method: 'payment-card',
63
+ feature: {
64
+ name: 'Google Pay',
65
+ merchantName: 'google-pay-merchant-name',
66
+ merchantOrigin: 'google-pay-merchant-origin'
67
+ },
68
+ brands: ['Visa'],
69
+ filters: []
70
+ }),
71
+ ]
72
+ });
28
73
  }
29
74
  }
30
75
 
@@ -34,72 +79,18 @@ describe('Summary component', () => {
34
79
  items: [
35
80
  {
36
81
  planId: 'my-awesome-product',
37
- quantity: 1,
38
- thumbnail: ''
82
+ quantity: 1
39
83
  },
40
84
  {
41
85
  planId: 'awesome-t-shirt',
42
- quantity: 2,
43
- thumbnail: ''
86
+ quantity: 2
44
87
  }
45
88
  ],
46
- paymentInstruments: {
47
- googlePay: {
48
- displayOptions: {
49
- buttonColor: 'black',
50
- buttonHeight: '44px',
51
- buttonType: 'short'
52
- }
53
- },
54
- compactExpressInstruments: true
55
- },
56
89
  _computed: {
57
90
  paymentMethodsUrl: ''
58
91
  }
59
92
  };
60
93
 
61
- const summaryData = new SummaryModel({
62
- currency: 'USD',
63
- lineItems: [
64
- {
65
- type: 'debit',
66
- description: 'My Awesome Product',
67
- unitPrice: 30,
68
- quantity: 1,
69
- price: 30,
70
- productId: 'my-awesome-product',
71
- planId: 'my-awesome-product'
72
- },
73
- {
74
- type: 'debit',
75
- description: 'Awesome T-Shirt',
76
- unitPrice: 20,
77
- quantity: 2,
78
- price: 40,
79
- productId: 'my-app',
80
- planId: 'awesome-t-shirt'
81
- }
82
- ],
83
- subtotalAmount: 70,
84
- taxAmount: 0,
85
- shippingAmount: 0,
86
- discountsAmount: 0,
87
- total: 70
88
- });
89
-
90
- const readyToPayData = [
91
- new ReadyToPayModel({
92
- method: 'payment-card',
93
- feature: {
94
- name: 'Google Pay',
95
- merchantName: 'google-pay-merchant-name',
96
- merchantOrigin: 'google-pay-merchant-origin'
97
- },
98
- brands: ['Visa'],
99
- filters: []
100
- })
101
- ];
102
-
103
94
  it('should inject the proper HTML for express methods', async () => {
104
95
  const mountSummaryInstance = new TestMountMethodSelectorInstance({
105
96
  options
@@ -107,13 +98,7 @@ describe('Summary component', () => {
107
98
 
108
99
  mountSummaryInstance.loader.DOM.form = mountSummaryInstance.form;
109
100
 
110
- mountMethodSelector({
111
- state: mountSummaryInstance,
112
- formOptions: {
113
- summary: summaryData,
114
- readyToPay: readyToPayData
115
- }
116
- });
101
+ mountMethodSelector({ state: mountSummaryInstance });
117
102
 
118
103
  const form = document.querySelector('.rebilly-instruments-form');
119
104
  expect(form).toMatchSnapshot();
@@ -6,10 +6,7 @@ import { getMethodData } from './get-method-data';
6
6
  export function MountMethods({
7
7
  state,
8
8
  METHODS_CONTAINER,
9
- METHODS,
10
- mainStyle,
11
- plans,
12
- products
9
+ METHODS
13
10
  }) {
14
11
  METHODS.forEach(async (method) => {
15
12
  const { METHOD_ID: methodId, METHOD_TYPE: methodType } =
@@ -23,10 +20,10 @@ export function MountMethods({
23
20
  !state.options.paymentInstruments[methodType]?.popup;
24
21
  const model = {
25
22
  options: state.options,
26
- mainStyle,
27
- method,
28
- plans,
29
- products
23
+ mainStyle: state.mainStyle,
24
+ plans: state.data.plans,
25
+ products: state.data.products,
26
+ method
30
27
  };
31
28
 
32
29
  METHODS_CONTAINER.insertAdjacentHTML(
@@ -5,9 +5,11 @@ const modalTemplate = (isRedirect, method) => `
5
5
  <div class="rebilly-instruments-modal-container ${
6
6
  method ? `rebilly-instruments-${method}` : ''
7
7
  } ${isRedirect ? 'is-redirect' : ''}">
8
+ ${isRedirect ? '' : `
8
9
  <svg class="rebilly-instruments-modal-close" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg">
9
10
  <path d="m15 13.5858 7.2929-7.293c.3905-.3904 1.0237-.3904 1.4142 0 .3905.3906.3905 1.0238 0 1.4143L16.4142 15l7.293 7.2929c.3904.3905.3904 1.0237 0 1.4142-.3906.3905-1.0238.3905-1.4143 0L15 16.4142l-7.2929 7.293c-.3905.3904-1.0237.3904-1.4142 0-.3905-.3906-.3905-1.0238 0-1.4143L13.5858 15l-7.293-7.2929c-.3904-.3905-.3904-1.0237 0-1.4142.3906-.3905 1.0238-.3905 1.4143 0L15 13.5858Z" fill-rule="nonzero"/>
10
11
  </svg>
12
+ `}
11
13
  <div class="rebilly-instruments-modal-content"></div>
12
14
  </div>
13
15
  </div>
@@ -52,6 +54,7 @@ export async function mountModal({
52
54
  };
53
55
 
54
56
  const iframe = await new ModalIframe({
57
+ state,
55
58
  name,
56
59
  url,
57
60
  model: injectedModel,
@@ -76,8 +79,9 @@ export async function mountModal({
76
79
  loader: state.loader
77
80
  });
78
81
 
79
- modalOverlay.addEventListener('click', closeModal);
80
- closeButton.addEventListener('click', closeModal);
82
+ if (!isRedirect) {
83
+ closeButton.addEventListener('click', closeModal);
84
+ }
81
85
 
82
86
  return iframe;
83
87
  }
@@ -1,7 +1,7 @@
1
1
  import { ViewIframe } from './common/iframe';
2
2
  import { replaceContent } from './common/render-utilities';
3
3
 
4
- export async function mountResult({ purchase, mainStyle, state }) {
4
+ export async function mountResult({ payload, state }) {
5
5
  const resultContainerClassName = 'rebilly-instruments-result';
6
6
  replaceContent(state.form, `<div class="${resultContainerClassName}"></div>`);
7
7
 
@@ -12,9 +12,10 @@ export async function mountResult({ purchase, mainStyle, state }) {
12
12
 
13
13
  const model = {
14
14
  options: state.options,
15
- mainStyle,
16
- purchase
15
+ mainStyle: state.mainStyle,
16
+ [state.options.transactionType]: payload
17
17
  };
18
+
18
19
  const iframe = await new ViewIframe({
19
20
  name: 'rebilly-instruments-result',
20
21
  url: `${paymentMethodsUrl}/result`,