@rebilly/instruments 3.13.2-beta.0 → 3.13.4-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 (84) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +66 -43
  3. package/dist/index.min.js +66 -43
  4. package/package.json +6 -3
  5. package/src/functions/destroy.js +2 -8
  6. package/src/functions/mount/fetch-data.js +2 -9
  7. package/src/functions/mount/index.js +10 -15
  8. package/src/functions/mount/mount.spec.js +11 -10
  9. package/src/functions/mount/setup-framepay-theme.js +72 -30
  10. package/src/functions/mount/setup-options.js +2 -2
  11. package/src/functions/mount/{setup-styles-vars.js → setup-styles.js} +7 -9
  12. package/src/functions/purchase.js +5 -2
  13. package/src/functions/setup.js +6 -3
  14. package/src/functions/show.js +2 -2
  15. package/src/functions/show.spec.js +4 -4
  16. package/src/functions/update.spec.js +3 -4
  17. package/src/instance.js +1 -4
  18. package/src/loader/index.js +33 -57
  19. package/src/storefront/index.js +5 -2
  20. package/src/storefront/payment-instruments.js +0 -7
  21. package/src/style/base/__snapshots__/theme.spec.js.snap +220 -136
  22. package/src/style/base/default-theme.js +14 -187
  23. package/src/style/base/index.js +79 -487
  24. package/src/style/base/theme.js +4 -3
  25. package/src/style/base/theme.spec.js +3 -2
  26. package/src/style/browserslist.js +1 -0
  27. package/src/style/components/accordion.js +140 -0
  28. package/src/style/components/address.js +55 -0
  29. package/src/style/components/button.js +117 -0
  30. package/src/style/components/divider.js +39 -0
  31. package/src/style/components/forms/checkbox.js +75 -0
  32. package/src/style/components/forms/field.js +56 -0
  33. package/src/style/components/forms/form.js +18 -0
  34. package/src/style/components/forms/input.js +77 -0
  35. package/src/style/components/forms/label.js +55 -0
  36. package/src/style/components/forms/radio.js +80 -0
  37. package/src/style/components/forms/select.js +86 -0
  38. package/src/style/components/forms/validation.js +72 -0
  39. package/src/style/components/icons.js +13 -0
  40. package/src/style/components/index.js +39 -0
  41. package/src/style/components/loader.js +41 -0
  42. package/src/style/components/methods.js +97 -0
  43. package/src/style/components/overlay.js +24 -0
  44. package/src/style/helpers/index.js +54 -0
  45. package/src/style/index.js +24 -4
  46. package/src/style/payment-instruments/content.js +8 -0
  47. package/src/style/payment-instruments/index.js +14 -0
  48. package/src/style/payment-instruments/payment-card.js +27 -0
  49. package/src/style/payment-instruments/payment-instrument-list.js +44 -0
  50. package/src/style/payment-instruments/payment-instrument.js +55 -0
  51. package/src/style/utils/color-values.js +1 -1
  52. package/src/style/utils/remove-empty-null.js +10 -0
  53. package/src/style/vendor/framepay.js +28 -0
  54. package/src/style/vendor/postmate.js +18 -0
  55. package/src/style/views/confirmation.js +26 -0
  56. package/src/style/views/index.js +16 -0
  57. package/src/style/views/method-selector.js +11 -0
  58. package/src/style/views/modal.js +91 -0
  59. package/src/style/views/result.js +52 -0
  60. package/src/style/views/summary.js +118 -0
  61. package/src/views/__snapshots__/summary.spec.js.snap +246 -0
  62. package/src/views/common/iframe/base-iframe.js +2 -3
  63. package/src/views/common/iframe/event-listeners.js +9 -12
  64. package/src/views/common/iframe/method-iframe.js +1 -3
  65. package/src/views/common/iframe/modal-iframe.js +2 -4
  66. package/src/views/common/iframe/view-iframe.js +1 -3
  67. package/src/views/confirmation.js +7 -12
  68. package/src/views/method-selector/express-methods/apple-pay.js +92 -0
  69. package/src/views/method-selector/express-methods/index.js +25 -0
  70. package/src/views/method-selector/get-payment-methods.js +1 -0
  71. package/src/views/method-selector/index.js +58 -45
  72. package/src/views/method-selector/method-selector.spec.js +1 -1
  73. package/src/views/method-selector/mount-express-methods.js +26 -66
  74. package/src/views/method-selector/mount-methods.js +178 -0
  75. package/src/views/modal.js +1 -1
  76. package/src/views/result.js +3 -3
  77. package/src/views/summary.js +190 -24
  78. package/src/views/summary.spec.js +145 -0
  79. package/tests/mocks/storefront-api-mock.js +27 -48
  80. package/src/style/utils/minifyCss.js +0 -14
  81. package/src/views/errors.js +0 -95
  82. package/src/views/method-selector/express-methods.js +0 -51
  83. package/src/views/method-selector/generate-framepay-config.js +0 -54
  84. package/src/views/method-selector/generate-framepay-config.spec.js +0 -195
@@ -1,6 +1,6 @@
1
1
  import Postmate from 'popostmate';
2
2
  import { SUPPORTED_METHODS } from '../../method-selector/get-payment-methods';
3
- import { basicLoaderHTML } from '../../../loader';
3
+ import { loaderHTML } from '../../../loader';
4
4
 
5
5
  export default class BaseIframe {
6
6
  constructor({
@@ -45,14 +45,13 @@ export default class BaseIframe {
45
45
  appendChild: (iframe) => {
46
46
  iframe.setAttribute('loading', 'lazy');
47
47
  iframe.setAttribute('allow', 'payment');
48
- iframe.setAttribute('scrolling', 'no');
49
48
  iframe.allowPaymentRequest = true;
50
49
  this.container.appendChild(iframe);
51
50
  },
52
51
  };
53
52
 
54
53
  if (SUPPORTED_METHODS.includes(this.name)) {
55
- this.container.insertAdjacentHTML('beforeend', basicLoaderHTML);
54
+ this.container.insertAdjacentHTML('beforeend', loaderHTML);
56
55
  }
57
56
 
58
57
  const component = await new Postmate({
@@ -1,6 +1,5 @@
1
1
  import camelCase from 'lodash.camelcase';
2
2
  import Events from '../../../events';
3
- import { showError } from '../../errors';
4
3
 
5
4
  export function dispatchRebillyInsturmentEventHandler(iframe) {
6
5
  iframe.component.on(`${iframe.name}-dispatch`, ({ event, detail }) => {
@@ -14,13 +13,15 @@ export function resizeComponentHandler(iframe) {
14
13
  });
15
14
  }
16
15
 
17
- export function stopLoaderHandler(iframe, data) {
18
- iframe.component.on(`${iframe.name}-stop-loading`, (id) => {
19
- let {section} = data;
20
- if (!section) {
21
- section = id.includes('summary') ? 'summary' : 'form';
22
- }
23
- data.loader?.stopLoading({ section, id });
16
+ export function stopLoaderHandler(iframe, data = { section: 'form' }) {
17
+ const iframeLoader = iframe.container.querySelectorAll('.rebilly-instruments-loader.is-active');
18
+
19
+ if (iframeLoader && iframeLoader.length) {
20
+ iframeLoader.forEach(loader => loader.classList.remove('is-active'));
21
+ }
22
+
23
+ iframe.component.on(`${iframe.name}-stop-loading`, (id = null) => {
24
+ data.loader?.stopLoading({ section: data.section, id: id || data.id });
24
25
  });
25
26
  }
26
27
 
@@ -40,7 +41,3 @@ export function displayOverlay(iframe) {
40
41
  }
41
42
  });
42
43
  }
43
-
44
- export function showErrorHandler(iframe) {
45
- iframe.component.on(`${iframe.name}-show-error`, showError);
46
- }
@@ -3,8 +3,7 @@ import {
3
3
  dispatchRebillyInsturmentEventHandler,
4
4
  resizeComponentHandler,
5
5
  stopLoaderHandler,
6
- displayOverlay,
7
- showErrorHandler
6
+ displayOverlay
8
7
  } from './event-listeners';
9
8
 
10
9
  export class MethodIframe extends BaseIframe {
@@ -20,6 +19,5 @@ export class MethodIframe extends BaseIframe {
20
19
  id
21
20
  });
22
21
  displayOverlay(this);
23
- showErrorHandler(this);
24
22
  }
25
23
  }
@@ -3,8 +3,7 @@ import {
3
3
  dispatchRebillyInsturmentEventHandler,
4
4
  resizeComponentHandler,
5
5
  changeIframeSrcHandler,
6
- stopLoaderHandler,
7
- showErrorHandler
6
+ stopLoaderHandler
8
7
  } from './event-listeners';
9
8
 
10
9
  export class ModalIframe extends BaseIframe {
@@ -19,9 +18,8 @@ export class ModalIframe extends BaseIframe {
19
18
  stopLoaderHandler(this, {
20
19
  loader,
21
20
  section: 'modal',
22
- id: this.name
21
+ id: 'modal-content'
23
22
  });
24
- showErrorHandler(this);
25
23
 
26
24
  // Close modal via postmate
27
25
  this.component.on(`${this.name}-close`, (...args) => {
@@ -2,8 +2,7 @@ import BaseIframe from './base-iframe';
2
2
  import {
3
3
  dispatchRebillyInsturmentEventHandler,
4
4
  resizeComponentHandler,
5
- stopLoaderHandler,
6
- showErrorHandler,
5
+ stopLoaderHandler
7
6
  } from './event-listeners';
8
7
 
9
8
  export class ViewIframe extends BaseIframe {
@@ -15,6 +14,5 @@ export class ViewIframe extends BaseIframe {
15
14
  dispatchRebillyInsturmentEventHandler(this);
16
15
  resizeComponentHandler(this);
17
16
  stopLoaderHandler(this, { loader });
18
- showErrorHandler(this);
19
17
  }
20
18
  }
@@ -1,6 +1,7 @@
1
1
  import { purchase } from '../functions/purchase';
2
2
  import { setup } from '../functions/setup';
3
3
  import { ViewIframe } from './common/iframe';
4
+ import { replaceContent } from './common/render-utilities';
4
5
  import { updateMethodSelector } from './method-selector';
5
6
  import { updateSummary } from './summary';
6
7
 
@@ -15,14 +16,9 @@ export async function mountConfirmation({ payload: instrument, state }) {
15
16
  updateSummary({ state, instrument });
16
17
  }
17
18
 
18
- const contentElement = state.form.querySelector('.rebilly-instruments-content');
19
- contentElement.insertAdjacentHTML('afterend', baseConfirmationHTML);
19
+ replaceContent(state.form, baseConfirmationHTML);
20
20
 
21
- const methodSelectorElement = state.form.querySelector('.rebilly-instruments-method-selector');
22
- methodSelectorElement.style.visibility = 'hidden';
23
- methodSelectorElement.style.height = '0px';
24
-
25
- state.loader.startLoading({ id: 'rebilly-instruments-confirmation' });
21
+ state.loader.startLoading({ id: 'confirmation' });
26
22
 
27
23
  const container = document.querySelector('.rebilly-instruments-confirmation');
28
24
 
@@ -31,7 +27,7 @@ export async function mountConfirmation({ payload: instrument, state }) {
31
27
  const model = {
32
28
  options: state.options,
33
29
  data: state.data.toPostmatesModel(),
34
- mainStyleVars: state.mainStyleVars,
30
+ mainStyle: state.mainStyle,
35
31
  instrument
36
32
  };
37
33
  const name = 'rebilly-instruments-confirmation';
@@ -54,7 +50,7 @@ export async function mountConfirmation({ payload: instrument, state }) {
54
50
  });
55
51
 
56
52
  iframe.component.on('choose-another-method', () => {
57
- state.iframeComponents.form = state.iframeComponents.form.filter((item) => {
53
+ state.iframeComponents = state.iframeComponents.filter((item) => {
58
54
  if (item.name === iframe.name) {
59
55
  item.destroy();
60
56
  return false;
@@ -64,9 +60,8 @@ export async function mountConfirmation({ payload: instrument, state }) {
64
60
  if (state.data.isPurchase) {
65
61
  updateSummary({ state });
66
62
  }
67
- updateMethodSelector({ state, mainStyleVars: state.mainStyleVars });
68
- state.form.querySelector('.rebilly-instruments-confirmation').remove();
63
+ updateMethodSelector({ state, mainStyle: state.mainStyle });
69
64
  });
70
65
 
71
- state.iframeComponents.form.push(iframe);
66
+ state.iframeComponents.push(iframe);
72
67
  }
@@ -0,0 +1,92 @@
1
+ import Events from '../../../events';
2
+
3
+ const browserIsSafari = () => window.ApplePaySession;
4
+
5
+ export default function mountApplePay({
6
+ state,
7
+ METHOD_ID,
8
+ METHOD_TYPE,
9
+ EXPRESS_METHODS,
10
+ EXPRESS_METHODS_CONTAINER
11
+ }) {
12
+ const container = document.querySelector(`.rebilly-instruments-${METHOD_ID}-method`);
13
+ const digitalWallet = state.options.digitalWallet.applePay;
14
+
15
+ function mountApplePayButton() {
16
+ if(!container.children.length) {
17
+ Rebilly.applePay.mount(`.rebilly-instruments-${METHOD_ID}-method`);
18
+ }
19
+ state.loader.stopLoading({ id: `${METHOD_TYPE}-express` });
20
+ }
21
+
22
+ // Hack: The correct way to do this is to accept the options via the framepay package
23
+ // Will remove once these options are added to framepay
24
+ function updateBtnStyling() {
25
+ const applePayButton = document.querySelector('#rebilly-apple-pay-button');
26
+ applePayButton.style.margin = '0px';
27
+ applePayButton.style.width = '100%';
28
+ applePayButton.style.height = digitalWallet.applePayDisplayOptions.buttonHeight;
29
+ }
30
+
31
+ if(!browserIsSafari()) {
32
+ if(EXPRESS_METHODS.length === 1) {
33
+ EXPRESS_METHODS_CONTAINER.parentNode.style.display = 'none';
34
+ }
35
+ state.loader.stopLoading({ id: `${METHOD_TYPE}-express` });
36
+ container.style.display = 'none';
37
+ return;
38
+ }
39
+
40
+ container.style.height = digitalWallet.applePayDisplayOptions.buttonHeight;
41
+
42
+ if (!Rebilly.initialized) {
43
+ const options = {
44
+ transactionData: digitalWallet.transactionData,
45
+ methods: state.data.readyToPay,
46
+ applePay: digitalWallet.applePayDisplayOptions,
47
+ organizationId: state.options.organizationId
48
+ }
49
+ if (state.options.jwt && !state.options.publishableKey) {
50
+ options.jwt = state.options.jwt;
51
+ options.sandbox = state.options.apiMode === 'sandbox';
52
+ } else {
53
+ options.publishableKey = state.options.publishableKey;
54
+ }
55
+ Rebilly.initialize(options);
56
+ } else {
57
+ mountApplePayButton();
58
+ updateBtnStyling();
59
+ }
60
+
61
+ Rebilly.on('ready', () => {
62
+ mountApplePayButton();
63
+ updateBtnStyling();
64
+ });
65
+
66
+ // HOTFIX: Hardcoded, use env variables in the future
67
+ const redirectUrl = state.options.apiMode === 'sandbox'
68
+ ? 'https://forms-sandbox.secure-payments.app/approval-url?close=true'
69
+ : 'https://forms.secure-payments.app/approval-url?close=true';
70
+
71
+ Rebilly.on('token-ready', (token) => {
72
+ const instrumentReadyPayload = {
73
+ websiteId: state.options.websiteId,
74
+ items: state.options.items,
75
+ paymentInstruction: {
76
+ token: token.id,
77
+ },
78
+ billingAddress: token.billingAddress,
79
+ redirectUrl,
80
+ _raw: token
81
+ }
82
+ if (!token.shippingAddress) {
83
+ instrumentReadyPayload.deliveryAddress = token.shippingAddress;
84
+ }
85
+
86
+ Events.instrumentReady.dispatch(instrumentReadyPayload);
87
+ });
88
+
89
+ Rebilly.on('error', error => {
90
+ console.error(error)
91
+ });
92
+ }
@@ -0,0 +1,25 @@
1
+ import { MethodIframe } from '../../common/iframe';
2
+
3
+ export default async function mountExpressMethod({ state, METHOD_ID }) {
4
+ const container = document.querySelector(`.rebilly-instruments-${METHOD_ID}-method`);
5
+
6
+ const { paymentMethodsUrl } = state.options._computed;
7
+
8
+ const model = {
9
+ options: state.options,
10
+ data: state.data.toPostmatesModel()
11
+ };
12
+
13
+ const iframe = await new MethodIframe({
14
+ name: METHOD_ID,
15
+ url: `${paymentMethodsUrl}/${METHOD_ID}`,
16
+ container,
17
+ model
18
+ });
19
+
20
+ iframe.bindEventListeners({
21
+ loader: state.loader
22
+ });
23
+
24
+ state.iframeComponents.push(iframe);
25
+ }
@@ -9,6 +9,7 @@ const isExpressMethod = ({ method, feature }) => (
9
9
 
10
10
  const isSupportedMethod = ({ method }) => SUPPORTED_METHODS.includes(method);
11
11
 
12
+ // TODO: just loader is used. We could simplify signature
12
13
  export function getPaymentMethods({ state }) {
13
14
  const result = {
14
15
  EXPRESS_METHODS: [],
@@ -1,14 +1,13 @@
1
1
  /* eslint-disable no-undef */
2
2
  import { collectData } from '@rebilly/risk-data-collector';
3
3
  import { getPaymentMethods } from './get-payment-methods';
4
- import { fetchData } from '../../functions/mount/fetch-data';
5
- import { ViewIframe } from '../common/iframe';
6
4
  import { mountExpressMethods } from './mount-express-methods';
7
5
  import { generateDigitalWallet } from './generate-digital-wallet';
6
+ import { MountMethods } from './mount-methods';
7
+ import { fetchData } from '../../functions/mount/fetch-data';
8
8
 
9
9
  export const baseMethodSelectorHTML = (compactExpressInstruments) => `
10
10
  <div class="rebilly-instruments-content">
11
- <div id="rebilly-instruments-error"></div>
12
11
  <div class="rebilly-instruments-method-selector ${compactExpressInstruments ? 'has-express-compact' : ''}">
13
12
  <div class="rebilly-instruments-express-methods ${
14
13
  compactExpressInstruments ? 'is-compact' : ''
@@ -24,67 +23,81 @@ export const baseMethodSelectorHTML = (compactExpressInstruments) => `
24
23
  </div>
25
24
  `;
26
25
 
27
- export async function mountMethodSelector({ state }) {
26
+ export function mountMethodSelector({ state }) {
28
27
  const { EXPRESS_METHODS, METHODS } = getPaymentMethods({ state });
29
28
 
30
- const methodSelectorElement = state.form.querySelector('.rebilly-instruments-method-selector');
31
- if (methodSelectorElement) {
32
- methodSelectorElement.style.visibility = 'visible';
33
- methodSelectorElement.style.height = 'auto';
34
- } else {
35
- state.form.innerHTML += baseMethodSelectorHTML(
36
- state.options.paymentInstruments.compactExpressInstruments && EXPRESS_METHODS.length
37
- );
38
- }
29
+ state.form.innerHTML += baseMethodSelectorHTML(
30
+ state.options.paymentInstruments.compactExpressInstruments && EXPRESS_METHODS.length
31
+ );
39
32
 
40
- const METHODS_CONTAINER = document.querySelector('.rebilly-instruments-methods');
41
- const EXPRESS_METHODS_CONTAINER = document.querySelector('.rebilly-instruments-express-methods-container');
33
+ const EXPRESS_METHODS_CONTAINER = document.querySelector(
34
+ '.rebilly-instruments-express-methods-container'
35
+ );
36
+ const METHODS_DIVIDER = document.querySelector(
37
+ '.rebilly-instruments-divider'
38
+ );
39
+ METHODS_DIVIDER.style.display =
40
+ METHODS.length && EXPRESS_METHODS.length ? 'block' : 'none';
41
+ const METHODS_CONTAINER = document.querySelector(
42
+ '.rebilly-instruments-methods'
43
+ );
42
44
 
43
- if(EXPRESS_METHODS.length) {
44
- if (!methodSelectorElement) {
45
- state.options.digitalWallet = generateDigitalWallet({state, EXPRESS_METHODS});
46
- mountExpressMethods({
47
- state,
48
- methods: EXPRESS_METHODS,
49
- container: EXPRESS_METHODS_CONTAINER,
50
- });
51
- }
52
- } else {
53
- EXPRESS_METHODS_CONTAINER.style.display = 'none';
54
- document.querySelector('.rebilly-instruments-divider')
55
- .style.display = 'none';
56
- }
45
+ state.options.digitalWallet = generateDigitalWallet({state, EXPRESS_METHODS});
57
46
 
58
47
  if (METHODS.length) {
59
- const model = {
60
- options: state.options,
61
- data: state.data.toPostmatesModel(),
62
- mainStyleVars: state.mainStyleVars,
63
- };
64
- const { paymentMethodsUrl } = state.options._computed;
65
-
66
- const iframe = await new ViewIframe({
67
- name: 'rebilly-instruments-methods',
68
- url: `${paymentMethodsUrl}`,
69
- container: METHODS_CONTAINER,
70
- model
48
+ MountMethods({
49
+ state,
50
+ METHODS_CONTAINER,
51
+ METHODS
71
52
  });
72
- iframe.bindEventListeners({loader: state.loader});
73
- state.iframeComponents.form.push(iframe);
74
53
  } else {
75
54
  METHODS_CONTAINER.style.display = 'none';
76
55
  }
56
+
57
+ if (EXPRESS_METHODS.length) {
58
+ mountExpressMethods({
59
+ state,
60
+ EXPRESS_METHODS,
61
+ EXPRESS_METHODS_CONTAINER
62
+ });
63
+ } else {
64
+ EXPRESS_METHODS_CONTAINER.parentNode.style.display = 'none';
65
+ }
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
+
76
+ state.translate.translateItems();
77
+
78
+ state.loader.stopLoading({ id: 'initForm' });
77
79
  }
78
80
 
79
81
  export async function updateMethodSelector({ state }) {
80
- state.loader.startLoading({ id: 'rebilly-instruments-methods' });
81
-
82
+ state.loader.startLoading({ id: 'initForm' });
82
83
  const { riskMetadata } = await collectData();
84
+
83
85
  state.data = await fetchData({ state, riskMetadata });
84
86
 
85
87
  if (state.data.transaction && state.data.transaction?.type === 'setup') {
86
88
  state.options.transactionType = 'setup';
87
89
  }
88
90
 
91
+ state.form
92
+ .querySelectorAll(':not(.rebilly-instruments-confirmation)')
93
+ .forEach((element) => {
94
+ if (
95
+ !element.classList.contains('rebilly-instruments-loader') &&
96
+ !element.classList.contains('rebilly-instruments-loader-spinner')
97
+ ) {
98
+ element.remove();
99
+ }
100
+ });
101
+
89
102
  mountMethodSelector({ state });
90
103
  }
@@ -114,7 +114,7 @@ describe('Summary component', () => {
114
114
 
115
115
  await updateMethodSelector({
116
116
  state,
117
- mainStyleVars: 'any main style'
117
+ mainStyle: 'any main style'
118
118
  });
119
119
  });
120
120
  });
@@ -1,81 +1,41 @@
1
1
  import mountExpressMethod from './express-methods';
2
- import {generateFramepayConfig} from './generate-framepay-config'
2
+ import mountApplePay from './express-methods/apple-pay';
3
3
  import { getMethodData } from './get-method-data';
4
- import Events from '../../events';
5
4
 
6
- const browserIsSafari = () => window.ApplePaySession;
7
-
8
- export async function mountExpressMethods({
5
+ export function mountExpressMethods({
9
6
  state,
10
- methods,
11
- container
7
+ EXPRESS_METHODS,
8
+ EXPRESS_METHODS_CONTAINER
12
9
  }) {
13
- const methodIds = methods.map((expressMethod) => {
10
+ // A child div for each method must be created before mounting.
11
+ // Any DOM operation (innerHTML, append, etc) done on the parent div (EXPRESS_METHODS_CONTAINER) in between
12
+ // the two Postmate's instantiation (1 parent, 1 child) will cause the parent <-> child handshake to fail
13
+ EXPRESS_METHODS.forEach((expressMethod) => {
14
14
  const { METHOD_ID } = getMethodData(expressMethod);
15
- return METHOD_ID
16
- });
17
- const {Rebilly} = window;
18
15
 
19
- if(!Rebilly?.initialized) {
20
- await Rebilly?.initialize(
21
- generateFramepayConfig({
22
- state,
23
- methodIds
24
- })
25
- );
26
- }
27
-
28
- methodIds.forEach((id) => {
29
- // filter out apple pay unless in safari
30
- if (id === 'apple-pay' && !browserIsSafari()) return
31
-
32
- container.innerHTML += `
33
- <div class="rebilly-instruments-${id}-method"></div>
16
+ EXPRESS_METHODS_CONTAINER.innerHTML += `
17
+ <div class="rebilly-instruments-${METHOD_ID}-method"></div>
34
18
  `;
35
- mountExpressMethod({
36
- state,
37
- id,
38
- });
39
19
  });
40
20
 
41
- // HOTFIX: Hardcoded, use env variables in the future
42
- const redirectUrl = state.options.apiMode === 'sandbox'
43
- ? 'https://forms-sandbox.secure-payments.app/approval-url?close=true'
44
- : 'https://forms.secure-payments.app/approval-url?close=true';
45
-
46
- Rebilly?.on('token-ready', (token) => {
47
- const instrumentReadyPayload = {
48
- websiteId: state.options.websiteId,
49
- billingAddress: token.billingAddress,
50
- redirectUrl,
51
- _raw: token
52
- };
53
-
54
- if (state.data?.isShippingRequired) {
55
- if (token.shippingAddress) {
56
- instrumentReadyPayload.deliveryAddress = token.shippingAddress;
57
- } else {
58
- instrumentReadyPayload.deliveryAddress = instrumentReadyPayload.billingAddress;
59
- }
60
- }
61
-
62
- if (Array.isArray(instrumentReadyPayload.billingAddress?.emails)) {
63
- const email = instrumentReadyPayload.billingAddress.emails
64
- .find(e => e.label === 'main')
65
21
 
66
- if (email?.value) {
67
- instrumentReadyPayload.billingAddress.email = email.value;
68
- }
69
- }
70
- if (Array.isArray(instrumentReadyPayload.deliveryAddress?.emails)) {
71
- const email = instrumentReadyPayload.deliveryAddress.emails
72
- .find(e => e.label === 'main')
22
+ EXPRESS_METHODS.forEach((expressMethod) => {
23
+ const { feature } = expressMethod;
24
+ const { METHOD_ID, METHOD_TYPE } = getMethodData(expressMethod);
73
25
 
74
- if (email?.value) {
75
- instrumentReadyPayload.deliveryAddress.email = email.value;
76
- }
26
+ if (feature?.name === 'Apple Pay') {
27
+ mountApplePay({
28
+ state,
29
+ METHOD_ID,
30
+ METHOD_TYPE,
31
+ EXPRESS_METHODS,
32
+ EXPRESS_METHODS_CONTAINER
33
+ });
34
+ } else {
35
+ mountExpressMethod({
36
+ state,
37
+ METHOD_ID
38
+ })
77
39
  }
78
-
79
- Events.instrumentReady.dispatch(instrumentReadyPayload);
80
40
  });
81
41
  }