@rebilly/instruments 1.0.1-beta → 1.0.2-beta.10

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 (277) hide show
  1. package/.babelrc +23 -5
  2. package/.eslintrc.js +27 -0
  3. package/.prettierrc.js +11 -0
  4. package/CONTRIBUTING.md +4 -0
  5. package/README.md +361 -2
  6. package/dist/events/base-event.js +51 -37
  7. package/dist/events/events.spec.js +18 -0
  8. package/dist/events/index.js +11 -8
  9. package/dist/functions/destroy.js +27 -5
  10. package/dist/functions/destroy.spec.js +69 -0
  11. package/dist/functions/initialize.js +60 -41
  12. package/dist/functions/initialize.spec.js +13 -13
  13. package/dist/functions/mount/fetch-summary-data.js +46 -0
  14. package/dist/functions/mount/fetch-summary-data.spec.js +44 -0
  15. package/dist/functions/mount/index.js +346 -0
  16. package/dist/functions/mount/mount.spec.js +135 -0
  17. package/dist/functions/on.js +26 -18
  18. package/dist/functions/on.spec.js +45 -63
  19. package/dist/functions/purchase.js +41 -154
  20. package/dist/functions/purchase.spec.js +60 -76
  21. package/dist/functions/show.js +39 -43
  22. package/dist/functions/show.spec.js +57 -0
  23. package/dist/functions/update.js +60 -5
  24. package/dist/functions/update.spec.js +100 -0
  25. package/dist/i18n/en.json +19 -0
  26. package/dist/i18n/es.json +19 -0
  27. package/dist/i18n/i18n.spec.js +6 -23
  28. package/dist/i18n/index.js +44 -67
  29. package/dist/index.js +70 -71
  30. package/dist/index.spec.js +24 -44
  31. package/dist/loader/index.js +63 -62
  32. package/dist/loader/loader.spec.js +14 -11
  33. package/dist/storefront/index.js +28 -39
  34. package/dist/storefront/models/plan-model.js +37 -54
  35. package/dist/storefront/models/product-model.js +25 -36
  36. package/dist/storefront/models/ready-to-pay-model.js +38 -42
  37. package/dist/storefront/models/summary-model.js +72 -99
  38. package/dist/storefront/plans.js +37 -84
  39. package/dist/storefront/plans.spec.js +61 -151
  40. package/dist/storefront/products.js +35 -83
  41. package/dist/storefront/products.spec.js +60 -150
  42. package/dist/storefront/purchase.js +27 -64
  43. package/dist/storefront/purchase.spec.js +51 -87
  44. package/dist/storefront/ready-to-pay.js +45 -107
  45. package/dist/storefront/ready-to-pay.spec.js +72 -147
  46. package/dist/storefront/storefront.spec.js +6 -6
  47. package/dist/storefront/summary.js +37 -84
  48. package/dist/storefront/summary.spec.js +135 -240
  49. package/dist/style/base/__snapshots__/theme.spec.js.snap +52 -0
  50. package/dist/style/base/index.js +72 -0
  51. package/dist/style/base/theme.js +73 -0
  52. package/dist/style/base/theme.spec.js +30 -0
  53. package/dist/style/browserslist.js +8 -0
  54. package/dist/style/components/address.js +64 -0
  55. package/dist/style/components/button.js +61 -0
  56. package/dist/style/components/divider.js +48 -0
  57. package/dist/style/components/forms/checkbox.js +83 -0
  58. package/dist/style/components/forms/field.js +53 -0
  59. package/dist/style/components/forms/form.js +28 -0
  60. package/dist/style/components/forms/input.js +45 -0
  61. package/dist/style/components/forms/label.js +43 -0
  62. package/dist/style/components/forms/select.js +63 -0
  63. package/dist/style/components/forms/validation.js +34 -0
  64. package/dist/style/components/icons.js +22 -0
  65. package/dist/style/components/index.js +57 -0
  66. package/dist/style/components/loader.js +48 -0
  67. package/dist/style/components/methods.js +104 -0
  68. package/dist/style/components/overlay.js +33 -0
  69. package/dist/style/helpers/index.js +59 -0
  70. package/dist/style/index.js +48 -0
  71. package/dist/style/payment-instruments/content.js +17 -0
  72. package/dist/style/payment-instruments/index.js +20 -0
  73. package/dist/style/payment-instruments/payment-card.js +35 -0
  74. package/dist/style/utils/color-values.js +22 -0
  75. package/dist/style/vendor/framepay.js +34 -0
  76. package/dist/style/vendor/postmate.js +17 -0
  77. package/dist/style/views/confirmation.js +85 -0
  78. package/dist/style/views/index.js +29 -0
  79. package/dist/style/views/method-selector.js +20 -0
  80. package/dist/style/views/modal.js +93 -0
  81. package/dist/style/views/result.js +61 -0
  82. package/dist/style/views/summary.js +123 -0
  83. package/dist/utils/add-dom-element.js +12 -34
  84. package/dist/utils/format-currency.js +4 -4
  85. package/dist/utils/has-valid-css-selector.js +2 -2
  86. package/dist/utils/index.js +15 -31
  87. package/dist/utils/is-dom-element.js +1 -1
  88. package/dist/utils/process-property-as-dom-element.js +12 -17
  89. package/dist/utils/sleep.js +10 -0
  90. package/{src/components → dist/views}/__snapshots__/summary.spec.js.snap +7 -3
  91. package/dist/views/common/iframe/base-iframe.js +57 -0
  92. package/dist/views/common/iframe/event-listeners.js +50 -0
  93. package/dist/views/common/iframe/index.js +19 -0
  94. package/dist/views/common/iframe/method-iframe.js +33 -0
  95. package/dist/views/common/iframe/modal-iframe.js +38 -0
  96. package/dist/views/common/iframe/view-iframe.js +31 -0
  97. package/dist/views/common/render-utilities.js +11 -0
  98. package/dist/views/confirmation.js +82 -0
  99. package/dist/views/method-selector/__snapshots__/method-selector.spec.js.snap +3 -0
  100. package/dist/views/method-selector/express-methods/apple-pay.js +92 -0
  101. package/dist/views/method-selector/express-methods/google-pay.js +32 -0
  102. package/dist/views/method-selector/express-methods/paypal.js +19 -0
  103. package/dist/views/method-selector/generate-digital-wallet.js +59 -0
  104. package/dist/views/method-selector/generate-digital-wallet.spec.js +132 -0
  105. package/dist/views/method-selector/get-method-data.js +25 -0
  106. package/dist/views/method-selector/get-payment-methods.js +55 -0
  107. package/dist/views/method-selector/get-payment-methods.spec.js +44 -0
  108. package/dist/views/method-selector/index.js +133 -0
  109. package/dist/views/method-selector/method-selector.spec.js +139 -0
  110. package/dist/views/method-selector/mount-express-methods.js +69 -0
  111. package/dist/views/method-selector/mount-methods.js +78 -0
  112. package/dist/views/modal.js +83 -0
  113. package/dist/views/result.js +42 -0
  114. package/dist/views/summary.js +162 -0
  115. package/dist/views/summary.spec.js +148 -0
  116. package/package.json +12 -6
  117. package/src/events/base-event.js +35 -12
  118. package/src/events/events.spec.js +11 -0
  119. package/src/events/index.js +12 -6
  120. package/src/functions/destroy.js +22 -3
  121. package/src/functions/destroy.spec.js +63 -0
  122. package/src/functions/initialize.js +43 -20
  123. package/src/functions/initialize.spec.js +9 -7
  124. package/src/functions/mount/fetch-summary-data.js +29 -0
  125. package/src/functions/mount/fetch-summary-data.spec.js +41 -0
  126. package/src/functions/mount/index.js +312 -0
  127. package/src/functions/mount/mount.spec.js +171 -0
  128. package/src/functions/on.js +17 -14
  129. package/src/functions/on.spec.js +39 -29
  130. package/src/functions/purchase.js +24 -64
  131. package/src/functions/purchase.spec.js +19 -17
  132. package/src/functions/show.js +27 -7
  133. package/src/functions/show.spec.js +61 -0
  134. package/src/functions/update.js +50 -3
  135. package/src/functions/update.spec.js +107 -0
  136. package/src/i18n/i18n.spec.js +6 -4
  137. package/src/i18n/index.js +20 -12
  138. package/src/index.js +43 -49
  139. package/src/index.spec.js +11 -42
  140. package/src/loader/index.js +55 -39
  141. package/src/loader/loader.spec.js +30 -23
  142. package/src/storefront/index.js +9 -7
  143. package/src/storefront/models/plan-model.js +1 -1
  144. package/src/storefront/models/product-model.js +1 -1
  145. package/src/storefront/models/ready-to-pay-model.js +10 -4
  146. package/src/storefront/models/summary-model.js +8 -15
  147. package/src/storefront/plans.js +16 -12
  148. package/src/storefront/plans.spec.js +29 -37
  149. package/src/storefront/products.js +16 -12
  150. package/src/storefront/products.spec.js +28 -39
  151. package/src/storefront/purchase.js +8 -6
  152. package/src/storefront/purchase.spec.js +18 -17
  153. package/src/storefront/ready-to-pay.js +19 -13
  154. package/src/storefront/ready-to-pay.spec.js +41 -41
  155. package/src/storefront/storefront.spec.js +1 -1
  156. package/src/storefront/summary.js +14 -12
  157. package/src/storefront/summary.spec.js +37 -50
  158. package/src/style/base/__snapshots__/theme.spec.js.snap +52 -0
  159. package/src/style/base/index.js +63 -0
  160. package/src/style/base/theme.js +61 -0
  161. package/src/style/base/theme.spec.js +32 -0
  162. package/src/style/browserslist.js +1 -0
  163. package/src/style/components/address.js +55 -0
  164. package/src/style/components/button.js +54 -0
  165. package/src/style/components/divider.js +39 -0
  166. package/src/style/components/forms/checkbox.js +76 -0
  167. package/src/style/components/forms/field.js +44 -0
  168. package/src/style/components/forms/form.js +19 -0
  169. package/src/style/components/forms/input.js +36 -0
  170. package/src/style/components/forms/label.js +34 -0
  171. package/src/style/components/forms/select.js +54 -0
  172. package/src/style/components/forms/validation.js +25 -0
  173. package/src/style/components/icons.js +13 -0
  174. package/src/style/components/index.js +35 -0
  175. package/src/style/components/loader.js +41 -0
  176. package/src/style/components/methods.js +93 -0
  177. package/src/style/components/overlay.js +24 -0
  178. package/src/style/helpers/index.js +51 -0
  179. package/src/style/index.js +30 -0
  180. package/src/style/payment-instruments/content.js +8 -0
  181. package/src/style/payment-instruments/index.js +10 -0
  182. package/src/style/payment-instruments/payment-card.js +26 -0
  183. package/src/style/utils/color-values.js +9 -0
  184. package/src/style/vendor/framepay.js +25 -0
  185. package/src/style/vendor/postmate.js +8 -0
  186. package/src/style/views/confirmation.js +76 -0
  187. package/src/style/views/index.js +16 -0
  188. package/src/style/views/method-selector.js +11 -0
  189. package/src/style/views/modal.js +84 -0
  190. package/src/style/views/result.js +52 -0
  191. package/src/style/views/summary.js +114 -0
  192. package/src/utils/add-dom-element.js +12 -13
  193. package/src/utils/format-currency.js +4 -1
  194. package/src/utils/has-valid-css-selector.js +2 -2
  195. package/src/utils/index.js +2 -6
  196. package/src/utils/is-dom-element.js +1 -1
  197. package/src/utils/process-property-as-dom-element.js +27 -24
  198. package/src/utils/sleep.js +3 -0
  199. package/src/views/__snapshots__/summary.spec.js.snap +292 -0
  200. package/src/views/common/iframe/base-iframe.js +46 -0
  201. package/src/views/common/iframe/event-listeners.js +27 -0
  202. package/src/views/common/iframe/index.js +7 -0
  203. package/src/views/common/iframe/method-iframe.js +21 -0
  204. package/src/views/common/iframe/modal-iframe.js +27 -0
  205. package/src/views/common/iframe/view-iframe.js +18 -0
  206. package/src/views/common/render-utilities.js +4 -0
  207. package/src/views/confirmation.js +57 -0
  208. package/src/views/method-selector/__snapshots__/method-selector.spec.js.snap +3 -0
  209. package/src/views/method-selector/express-methods/apple-pay.js +78 -0
  210. package/src/views/method-selector/express-methods/google-pay.js +25 -0
  211. package/src/views/method-selector/express-methods/paypal.js +7 -0
  212. package/src/views/method-selector/generate-digital-wallet.js +44 -0
  213. package/src/views/method-selector/generate-digital-wallet.spec.js +131 -0
  214. package/src/{components/form → views/method-selector}/get-method-data.js +9 -5
  215. package/src/views/method-selector/get-payment-methods.js +40 -0
  216. package/src/views/method-selector/get-payment-methods.spec.js +40 -0
  217. package/src/views/method-selector/index.js +110 -0
  218. package/src/views/method-selector/method-selector.spec.js +146 -0
  219. package/src/views/method-selector/mount-express-methods.js +53 -0
  220. package/src/views/method-selector/mount-methods.js +71 -0
  221. package/src/views/modal.js +84 -0
  222. package/src/views/result.js +30 -0
  223. package/src/{components → views}/summary.js +90 -21
  224. package/src/views/summary.spec.js +170 -0
  225. package/tests/async-utilities.js +22 -0
  226. package/tests/mocks/rebilly-instruments-mock.js +105 -7
  227. package/dist/components/confirmation.js +0 -103
  228. package/dist/components/form/form.js +0 -110
  229. package/dist/components/form/form.spec.js +0 -135
  230. package/dist/components/form/get-method-data.js +0 -21
  231. package/dist/components/form/get-payment-methods.js +0 -42
  232. package/dist/components/form/method-selector.js +0 -61
  233. package/dist/components/form/mount-express-payment-methods.js +0 -102
  234. package/dist/components/form/process-digital-wallet-options.js +0 -20
  235. package/dist/components/form/zoid-helpers.js +0 -130
  236. package/dist/components/result.js +0 -66
  237. package/dist/components/summary.js +0 -60
  238. package/dist/components/summary.spec.js +0 -144
  239. package/dist/events/instrument-ready.js +0 -51
  240. package/dist/events/purchase-complete.js +0 -51
  241. package/dist/functions/mount.js +0 -311
  242. package/dist/functions/mount.spec.js +0 -203
  243. package/dist/styles/base-styles.js +0 -12
  244. package/dist/styles/flat-theme-object.js +0 -42
  245. package/dist/styles/framepay.js +0 -15
  246. package/dist/styles/main.js +0 -25
  247. package/dist/styles/payment-card.js +0 -12
  248. package/dist/styles/shade-tint-values-helper.js +0 -28
  249. package/dist/styles/style-variables.js +0 -43
  250. package/dist/utils/camel-case.js +0 -12
  251. package/dist/utils/kebab-case.js +0 -10
  252. package/dist/utils/un-kebab-case.js +0 -10
  253. package/src/components/confirmation.js +0 -77
  254. package/src/components/form/__snapshots__/form.spec.js.snap +0 -43
  255. package/src/components/form/form.js +0 -88
  256. package/src/components/form/form.spec.js +0 -109
  257. package/src/components/form/get-payment-methods.js +0 -32
  258. package/src/components/form/method-selector.js +0 -47
  259. package/src/components/form/mount-express-payment-methods.js +0 -84
  260. package/src/components/form/process-digital-wallet-options.js +0 -11
  261. package/src/components/form/zoid-helpers.js +0 -114
  262. package/src/components/result.js +0 -50
  263. package/src/components/summary.spec.js +0 -106
  264. package/src/events/instrument-ready.js +0 -11
  265. package/src/events/purchase-complete.js +0 -11
  266. package/src/functions/mount.js +0 -204
  267. package/src/functions/mount.spec.js +0 -172
  268. package/src/styles/base-styles.js +0 -741
  269. package/src/styles/flat-theme-object.js +0 -12
  270. package/src/styles/framepay.js +0 -30
  271. package/src/styles/main.js +0 -17
  272. package/src/styles/payment-card.js +0 -18
  273. package/src/styles/shade-tint-values-helper.js +0 -13
  274. package/src/styles/style-variables.js +0 -34
  275. package/src/utils/camel-case.js +0 -3
  276. package/src/utils/kebab-case.js +0 -3
  277. package/src/utils/un-kebab-case.js +0 -3
@@ -0,0 +1,146 @@
1
+ import SummaryModel from '@/storefront/models/summary-model';
2
+ import ReadyToPayModel from '@/storefront/models/ready-to-pay-model';
3
+ import { Loader } from '../../loader';
4
+ import { Translate } from '../../i18n';
5
+ import { mountMethodSelector, updateMethodSelector } from './index';
6
+ import { avoidUnhandledPromises } from 'tests/async-utilities';
7
+ import { MockStorefront } from 'tests/mocks/storefront-mock';
8
+
9
+ describe('Summary component', () => {
10
+ let formElement;
11
+ beforeEach(() => {
12
+ formElement = document.createElement('div');
13
+ document.body.append(formElement);
14
+ });
15
+
16
+ class TestMountMethodSelectorInstance {
17
+ constructor({
18
+ configs = {},
19
+ options = {},
20
+ form = formElement,
21
+ loader = new Loader(),
22
+ translate = new Translate(),
23
+ zoidComponents = {}
24
+ } = {}) {
25
+ this.configs = configs;
26
+ this.options = options;
27
+ this.form = form;
28
+ this.loader = loader;
29
+ this.translate = translate;
30
+ this.zoidComponents = zoidComponents;
31
+ this.storefront = MockStorefront();
32
+ }
33
+ }
34
+
35
+ const options = {
36
+ intent: {
37
+ countryCode: 'US',
38
+ items: [
39
+ {
40
+ planId: 'my-awesome-product',
41
+ quantity: 1,
42
+ thumbnail: ''
43
+ },
44
+ {
45
+ planId: 'awesome-t-shirt',
46
+ quantity: 2,
47
+ thumbnail: ''
48
+ }
49
+ ]
50
+ },
51
+ paymentInstruments: {
52
+ googlePay: {
53
+ displayOptions: {
54
+ buttonColor: 'black',
55
+ buttonHeight: '44px',
56
+ buttonType: 'short'
57
+ }
58
+ },
59
+ compactExpressInstruments: true
60
+ },
61
+ _computed: {
62
+ paymentMethodsUrl: ''
63
+ }
64
+ };
65
+
66
+ const summaryData = new SummaryModel({
67
+ currency: 'USD',
68
+ lineItems: [
69
+ {
70
+ type: 'debit',
71
+ description: 'My Awesome Product',
72
+ unitPrice: 30,
73
+ quantity: 1,
74
+ price: 30,
75
+ productId: 'my-awesome-product',
76
+ planId: 'my-awesome-product'
77
+ },
78
+ {
79
+ type: 'debit',
80
+ description: 'Awesome T-Shirt',
81
+ unitPrice: 20,
82
+ quantity: 2,
83
+ price: 40,
84
+ productId: 'my-app',
85
+ planId: 'awesome-t-shirt'
86
+ }
87
+ ],
88
+ subtotalAmount: 70,
89
+ taxAmount: 0,
90
+ shippingAmount: 0,
91
+ discountsAmount: 0,
92
+ total: 70
93
+ });
94
+
95
+ const readyToPayData = [
96
+ new ReadyToPayModel({
97
+ method: 'payment-card',
98
+ feature: {
99
+ name: 'Google Pay',
100
+ merchantName: 'google-pay-merchant-name',
101
+ merchantOrigin: 'google-pay-merchant-origin'
102
+ },
103
+ brands: ['Visa'],
104
+ filters: []
105
+ })
106
+ ];
107
+
108
+ const configs = {
109
+ websiteId: 'test-website-id'
110
+ };
111
+
112
+ it('should inject the proper HTML for express methods', async () => {
113
+ const mountSummaryInstance = new TestMountMethodSelectorInstance({
114
+ configs,
115
+ options
116
+ });
117
+
118
+ mountSummaryInstance.loader.DOM.form = mountSummaryInstance.form;
119
+
120
+ mountMethodSelector({
121
+ state: mountSummaryInstance,
122
+ formOptions: {
123
+ summary: summaryData,
124
+ readyToPay: readyToPayData
125
+ }
126
+ });
127
+
128
+ const form = document.querySelector('.rebilly-instruments-form');
129
+ expect(form).toMatchSnapshot();
130
+ await avoidUnhandledPromises();
131
+ });
132
+
133
+ it('should allow updating method selector', async () => {
134
+ const state = new TestMountMethodSelectorInstance({
135
+ configs,
136
+ options
137
+ });
138
+
139
+ state.loader.DOM.form = state.form;
140
+
141
+ await updateMethodSelector({
142
+ state,
143
+ mainStyle: 'any main style'
144
+ });
145
+ });
146
+ });
@@ -0,0 +1,53 @@
1
+
2
+ import mountGooglePay from './express-methods/google-pay';
3
+ import mountApplePay from './express-methods/apple-pay';
4
+ import mountPaypal from './express-methods/paypal';
5
+ import { getMethodData } from './get-method-data';
6
+
7
+ export function mountExpressMethods({
8
+ state,
9
+ EXPRESS_METHODS,
10
+ EXPRESS_METHODS_CONTAINER
11
+ }) {
12
+ // A child div for each method must be created before mounting.
13
+ // Any DOM operation (innerHTML, append, etc) done on the parent div (EXPRESS_METHODS_CONTAINER) in between
14
+ // the two Postmate's instantiation (1 parent, 1 child) will cause the parent <-> child handshake to fail
15
+ EXPRESS_METHODS.forEach((expressMethod) => {
16
+ const { METHOD_ID } = getMethodData(expressMethod);
17
+
18
+ EXPRESS_METHODS_CONTAINER.innerHTML += `
19
+ <div class="rebilly-instruments-${METHOD_ID}-method"></div>
20
+ `;
21
+ });
22
+
23
+
24
+ EXPRESS_METHODS.forEach((expressMethod) => {
25
+ const { method, feature } = expressMethod;
26
+ const { METHOD_ID, METHOD_TYPE } = getMethodData(expressMethod);
27
+
28
+ if (feature?.name === 'Google Pay') {
29
+ mountGooglePay({
30
+ state,
31
+ METHOD_ID
32
+ });
33
+ }
34
+
35
+ if (feature?.name === 'Apple Pay') {
36
+ mountApplePay({
37
+ state,
38
+ METHOD_ID,
39
+ METHOD_TYPE,
40
+ EXPRESS_METHODS,
41
+ EXPRESS_METHODS_CONTAINER
42
+ });
43
+ }
44
+
45
+ if (method === 'paypal') {
46
+ mountPaypal({
47
+ state,
48
+ METHOD_ID,
49
+ METHOD_TYPE,
50
+ });
51
+ }
52
+ });
53
+ }
@@ -0,0 +1,71 @@
1
+ import camelCase from 'lodash.camelcase';
2
+ import { mountModal } from '../modal';
3
+ import { MethodIframe } from '../common/iframe';
4
+ import { getMethodData } from './get-method-data';
5
+
6
+ export function MountMethods({
7
+ state,
8
+ METHODS_CONTAINER,
9
+ METHODS,
10
+ mainStyle,
11
+ plans,
12
+ products
13
+ }) {
14
+ METHODS.forEach(async (method) => {
15
+ const { METHOD_ID: methodId, METHOD_TYPE: methodType } =
16
+ getMethodData(method);
17
+ const { paymentMethodsUrl } =
18
+ state.options._computed || 'https://www.example.com';
19
+
20
+ const selector = `rebilly-instruments-${methodId}`;
21
+ const isiFrame =
22
+ methodId === 'payment-card' &&
23
+ !state.options.paymentInstruments[methodType]?.popup;
24
+ const model = {
25
+ configs: state.configs,
26
+ options: state.options,
27
+ mainStyle,
28
+ method,
29
+ plans,
30
+ products
31
+ };
32
+
33
+ METHODS_CONTAINER.insertAdjacentHTML(
34
+ 'beforeend',
35
+ `<div id="${selector}" data-rebilly-instruments-type="${methodId}"></div>`
36
+ );
37
+ const container = document.querySelector(`#${selector}`);
38
+
39
+ if (isiFrame) {
40
+ const iframe = await new MethodIframe({
41
+ name: methodId,
42
+ url: `${paymentMethodsUrl}/${methodId}`,
43
+ container,
44
+ model
45
+ });
46
+ iframe.bindEventListeners({
47
+ loader: state.loader,
48
+ id: method.method
49
+ });
50
+ state.iframeComponents.push(iframe);
51
+ } else {
52
+ container.insertAdjacentHTML(
53
+ 'beforeend',
54
+ `<button class="${selector} rebilly-instruments-button" data-rebilly-i18n="paymentMethods.${
55
+ method.method
56
+ }">${camelCase(method.method)}</button>`
57
+ );
58
+ const paymentCardButton = document.querySelector(`.${selector}`);
59
+ paymentCardButton.addEventListener('click', async () => {
60
+ const iframe = await mountModal({
61
+ state,
62
+ name: methodId,
63
+ url: `${paymentMethodsUrl}/${methodId}`,
64
+ model
65
+ });
66
+ state.iframeComponents.push(iframe);
67
+ });
68
+ state.loader.stopLoading({ id: method.method });
69
+ }
70
+ });
71
+ }
@@ -0,0 +1,84 @@
1
+ import { ModalIframe } from './common/iframe';
2
+
3
+ const modalTemplate = (isRedirect, method) => `
4
+ <div class="rebilly-instruments-modal-overlay">
5
+ <div class="rebilly-instruments-modal-container ${
6
+ method ? `rebilly-instruments-${method}` : ''
7
+ } ${isRedirect ? 'is-redirect' : ''}">
8
+ <svg class="rebilly-instruments-modal-close" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg">
9
+ <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
+ </svg>
11
+ <div class="rebilly-instruments-modal-content"></div>
12
+ </div>
13
+ </div>
14
+ `;
15
+
16
+ export async function mountModal({
17
+ name = '',
18
+ url = '',
19
+ model = {},
20
+ classListArray = [],
21
+ close = () => {},
22
+ state = null
23
+ } = {}) {
24
+ const method = model?.method?.method;
25
+ const isRedirect = name === 'rebilly-instruments-approval-url';
26
+ state.form.insertAdjacentHTML('beforeend', modalTemplate(isRedirect, method));
27
+
28
+ const modalOverlay = document.querySelector(
29
+ '.rebilly-instruments-modal-overlay'
30
+ );
31
+ const modalContainer = document.querySelector(
32
+ '.rebilly-instruments-modal-container'
33
+ );
34
+ const closeButton = document.querySelector(
35
+ '.rebilly-instruments-modal-close'
36
+ );
37
+ const modalContent = document.querySelector(
38
+ '.rebilly-instruments-modal-content'
39
+ );
40
+
41
+ document.body.style.overflow = 'hidden';
42
+ setTimeout(() => {
43
+ modalOverlay.classList.add('is-visible');
44
+ modalContainer.classList.add('is-visible');
45
+ }, 240);
46
+ state.loader.addDOMElement({ section: 'modal', el: modalContent });
47
+ state.loader.startLoading({ section: 'modal', id: 'modal-content' });
48
+
49
+ const injectedModel = {
50
+ configs: state.configs,
51
+ options: state.options,
52
+ ...model
53
+ };
54
+
55
+ const iframe = await new ModalIframe({
56
+ name,
57
+ url,
58
+ model: injectedModel,
59
+ classListArray,
60
+ container: modalContent
61
+ });
62
+
63
+ const closeModal = (...args) => {
64
+ modalContainer.classList.remove('is-visible');
65
+ modalOverlay.classList.remove('is-visible');
66
+ setTimeout(() => {
67
+ document.body.style.overflow = 'auto';
68
+ modalOverlay.children.forEach((child) => child.remove());
69
+ modalOverlay.remove();
70
+ close(...args);
71
+ iframe.destroy();
72
+ }, 300);
73
+ };
74
+
75
+ iframe.bindEventListeners({
76
+ close: closeModal,
77
+ loader: state.loader
78
+ });
79
+
80
+ modalOverlay.addEventListener('click', closeModal);
81
+ closeButton.addEventListener('click', closeModal);
82
+
83
+ return iframe;
84
+ }
@@ -0,0 +1,30 @@
1
+ import { ViewIframe } from './common/iframe';
2
+ import { replaceContent } from './common/render-utilities';
3
+
4
+ export async function mountResult({ purchase, mainStyle, state }) {
5
+ const resultContainerClassName = 'rebilly-instruments-result';
6
+ replaceContent(state.form, `<div class="${resultContainerClassName}"></div>`);
7
+
8
+ state.loader.startLoading({ id: 'result' });
9
+
10
+ const container = document.querySelector(`.${resultContainerClassName}`);
11
+ const { paymentMethodsUrl } = state.options._computed;
12
+
13
+ const model = {
14
+ configs: state.configs,
15
+ options: state.options,
16
+ mainStyle,
17
+ purchase
18
+ };
19
+ const iframe = await new ViewIframe({
20
+ name: 'rebilly-instruments-result',
21
+ url: `${paymentMethodsUrl}/result`,
22
+ container,
23
+ model
24
+ });
25
+ iframe.bindEventListeners({
26
+ loader: state.loader
27
+ });
28
+
29
+ state.iframeComponents.push(iframe);
30
+ }
@@ -1,18 +1,27 @@
1
+ import { collectData } from '@rebilly/risk-data-collector';
1
2
  import { formatCurrency } from '../utils';
3
+ import { fetchSummaryData } from '../functions/mount/fetch-summary-data';
2
4
 
3
5
  export const baseSummaryHTML = `
4
- <div class="rebilly-instruments-summary-container">
6
+ <div class="rebilly-instruments-content">
5
7
  <div class="rebilly-instruments-summary-line-items"></div>
6
8
  <div class="rebilly-instruments-summary-breakdown"></div>
7
9
  </div>
8
10
  `;
9
11
 
10
- export function MountSummary({summary, plans, products} = {}) {
11
- this.summary.innerHTML += baseSummaryHTML;
12
- const itemsContainer = document.querySelector('.rebilly-instruments-summary-line-items');
13
- const summaryBreakdown = document.querySelector('.rebilly-instruments-summary-breakdown')
14
- const {intent: {items: optionItems}} = this.options;
15
- const hasThumbnails = optionItems.some(optionItem => optionItem.thumbnail);
12
+ export function mountSummary({ state, summaryOptions }) {
13
+ const { summary, plans, products } = summaryOptions;
14
+ state.summary.innerHTML += baseSummaryHTML;
15
+ const itemsContainer = document.querySelector(
16
+ '.rebilly-instruments-summary-line-items'
17
+ );
18
+ const summaryBreakdown = document.querySelector(
19
+ '.rebilly-instruments-summary-breakdown'
20
+ );
21
+ const {
22
+ intent: { items: optionItems }
23
+ } = state.options;
24
+ const hasThumbnails = optionItems?.some((optionItem) => optionItem.thumbnail);
16
25
 
17
26
  const {
18
27
  lineItems,
@@ -24,28 +33,47 @@ export function MountSummary({summary, plans, products} = {}) {
24
33
  total
25
34
  } = summary;
26
35
 
27
- lineItems.forEach(lineItem => {
28
- const {thumbnail} = optionItems.find(optionItem => optionItem.planId === lineItem.planId);
29
- const {name} = plans.find(plan => plan.id === lineItem.planId);
30
- const {description} = products.find(product => product.id === lineItem.productId);
36
+ lineItems.forEach((lineItem) => {
37
+ const { thumbnail } = optionItems.find(
38
+ (optionItem) => optionItem.planId === lineItem.planId
39
+ );
40
+ const { name } = plans.find((plan) => plan.id === lineItem.planId);
41
+ const { description } = products.find(
42
+ (product) => product.id === lineItem.productId
43
+ );
31
44
 
32
45
  itemsContainer.innerHTML += `
33
46
  <div class="rebilly-instruments-summary-line-item">
34
- ${hasThumbnails ? `
47
+ ${
48
+ hasThumbnails
49
+ ? `
35
50
  <figure class="rebilly-instruments-summary-line-item-figure">
36
51
  ${thumbnail ? `<img src="${thumbnail}" alt="${name}">` : ''}
37
52
  </figure>
38
- ` : ``}
53
+ `
54
+ : ''
55
+ }
39
56
  <div class="rebilly-instruments-summary-line-item-synopsis">
40
57
  <p class="rebilly-instruments-summary-line-item-synopsis-title">${name}</p>
41
- <p class="rebilly-instruments-summary-line-item-synopsis-description">${description}</p>
58
+ ${
59
+ description
60
+ ? `
61
+ <p class="rebilly-instruments-summary-line-item-synopsis-description">${description}</p>
62
+ `
63
+ : ''
64
+ }
42
65
  </div>
43
66
  <div class="rebilly-instruments-summary-line-item-price-breakdown">
44
- <p class="rebilly-instruments-summary-line-item-price-breakdown-quantity">${lineItem.quantity}</p>
67
+ <p class="rebilly-instruments-summary-line-item-price-breakdown-quantity">${
68
+ lineItem.quantity
69
+ }</p>
45
70
  <svg class="rebilly-instruments-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
46
71
  <path d="M12 10.5858l2.8284-2.8284c.3906-.3906 1.0237-.3906 1.4142 0 .3906.3905.3906 1.0236 0 1.4142L13.4142 12l2.8284 2.8284c.3906.3906.3906 1.0237 0 1.4142-.3905.3906-1.0236.3906-1.4142 0L12 13.4142l-2.8284 2.8284c-.3906.3906-1.0237.3906-1.4142 0-.3906-.3905-.3906-1.0236 0-1.4142L10.5858 12 7.7574 9.1716c-.3906-.3906-.3906-1.0237 0-1.4142.3905-.3906 1.0236-.3906 1.4142 0L12 10.5858z" fill-rule="nonzero"/>
47
72
  </svg>
48
- <p class="rebilly-instruments-summary-line-item-price-breakdown-unit-price">${formatCurrency(lineItem.unitPrice, currency)}</p>
73
+ <p class="rebilly-instruments-summary-line-item-price-breakdown-unit-price">${formatCurrency(
74
+ lineItem.unitPrice,
75
+ currency
76
+ )}</p>
49
77
  </div>
50
78
  </div>
51
79
  `;
@@ -76,12 +104,53 @@ export function MountSummary({summary, plans, products} = {}) {
76
104
  <div class="rebilly-instruments-summary-breakdown-total">
77
105
  <p data-rebilly-i18n="summary.total">Total</p>
78
106
  <p class="rebilly-instruments-summary-breakdown-total-amount">
79
- <span class="rebilly-instruments-summary-breakdown-total-amount-currency">${currency}</span>${formatCurrency(total, currency)}
107
+ <span class="rebilly-instruments-summary-breakdown-total-amount-currency">${currency}</span>${formatCurrency(
108
+ total,
109
+ currency
110
+ )}
80
111
  </p>
81
112
  </div>
82
113
  `;
83
-
84
- this.translate.translateItems();
85
114
 
86
- this.loader.stopLoading({section: 'summary', id: 'initSummary'});
87
- };
115
+ state.translate.translateItems();
116
+
117
+ state.loader.stopLoading({ section: 'summary', id: 'initSummary' });
118
+ }
119
+
120
+ export async function updateSummary({ state, instrument = null }) {
121
+ state.loader.startLoading({ section: 'summary', id: 'initSummary' });
122
+ const { riskMetadata } = await collectData();
123
+
124
+ let summaryPayload;
125
+
126
+ if (instrument?.billingAddress) {
127
+ summaryPayload = {
128
+ billingAddress: instrument.billingAddress
129
+ };
130
+ }
131
+
132
+ const {
133
+ readyToPay,
134
+ summary: summaryData,
135
+ plans,
136
+ products
137
+ } = await fetchSummaryData({
138
+ riskMetadata,
139
+ summaryPayload,
140
+ state
141
+ });
142
+
143
+ const summaryOptions = {
144
+ summary: summaryData,
145
+ readyToPay,
146
+ plans,
147
+ products
148
+ };
149
+
150
+ const itemsContainer = state.summary.querySelector(
151
+ '.rebilly-instruments-content'
152
+ );
153
+ itemsContainer?.remove();
154
+
155
+ mountSummary({ state, summaryOptions });
156
+ }