@rebilly/instruments 3.1.4-beta.0 → 3.3.0-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.
- package/dist/index.js +13 -13
- package/dist/index.min.js +13 -13
- package/package.json +2 -1
- package/src/functions/mount/fetch-data.js +13 -3
- package/src/functions/mount/index.js +9 -2
- package/src/functions/mount/mount.spec.js +20 -0
- package/src/functions/mount/setup-framepay-theme.js +44 -21
- package/src/functions/mount/setup-options.js +37 -4
- package/src/functions/mount/setup-options.spec.js +1 -2
- package/src/functions/mount/setup-storefront.js +4 -1
- package/src/functions/purchase.js +1 -1
- package/src/i18n/en.json +3 -1
- package/src/i18n/es.json +3 -1
- package/src/storefront/index.js +12 -4
- package/src/storefront/invoices.js +1 -1
- package/src/storefront/models/payment-metadata.js +7 -0
- package/src/storefront/models/ready-to-pay-model.js +6 -1
- package/src/storefront/products.js +6 -4
- package/src/storefront/ready-to-pay.js +29 -9
- package/src/storefront/transactions.js +1 -1
- package/src/style/components/accordion.js +127 -0
- package/src/style/components/button.js +3 -0
- package/src/style/components/forms/form.js +1 -2
- package/src/style/components/index.js +2 -0
- package/src/views/method-selector/generate-digital-wallet.js +1 -1
- package/src/views/method-selector/get-payment-methods.js +2 -2
- package/src/views/method-selector/mount-methods.js +117 -14
- package/tests/mocks/rebilly-api-mock.js +9 -0
- package/tests/mocks/rebilly-instruments-mock.js +2 -1
- package/tests/msw/server.js +2 -0
|
@@ -12,6 +12,7 @@ import { loader } from './loader';
|
|
|
12
12
|
import { icons } from './icons';
|
|
13
13
|
import { address } from './address';
|
|
14
14
|
import { overlay } from './overlay';
|
|
15
|
+
import {accordion} from './accordion';
|
|
15
16
|
|
|
16
17
|
// Order of components matters for style cascade
|
|
17
18
|
export const components = (theme) => `
|
|
@@ -32,4 +33,5 @@ export const components = (theme) => `
|
|
|
32
33
|
${icons(theme)}
|
|
33
34
|
${address(theme)}
|
|
34
35
|
${overlay(theme)}
|
|
36
|
+
${accordion(theme)}
|
|
35
37
|
`;
|
|
@@ -3,7 +3,7 @@ import { getMethodData } from './get-method-data';
|
|
|
3
3
|
|
|
4
4
|
const SUPPORTED_EXPRESS_METHODS = ['Google Pay', 'Apple Pay', 'paypal'];
|
|
5
5
|
|
|
6
|
-
const SUPPORTED_METHODS = ['payment-card'];
|
|
6
|
+
const SUPPORTED_METHODS = ['payment-card', 'ach'];
|
|
7
7
|
|
|
8
8
|
const isExpressMethod = ({ method, feature }) => {
|
|
9
9
|
return (
|
|
@@ -23,7 +23,7 @@ export function getPaymentMethods({ state }) {
|
|
|
23
23
|
METHODS: []
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
state.data.readyToPay
|
|
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
|
|
@@ -3,11 +3,57 @@ import { mountModal } from '../modal';
|
|
|
3
3
|
import { MethodIframe } from '../common/iframe';
|
|
4
4
|
import { getMethodData } from './get-method-data';
|
|
5
5
|
|
|
6
|
+
async function mountInline(state, {
|
|
7
|
+
methodId,
|
|
8
|
+
paymentMethodsUrl,
|
|
9
|
+
container,
|
|
10
|
+
model,
|
|
11
|
+
method
|
|
12
|
+
}) {
|
|
13
|
+
const iframe = await new MethodIframe({
|
|
14
|
+
name: methodId,
|
|
15
|
+
url: `${paymentMethodsUrl}/${methodId}`,
|
|
16
|
+
container,
|
|
17
|
+
model
|
|
18
|
+
});
|
|
19
|
+
iframe.bindEventListeners({
|
|
20
|
+
loader: state.loader,
|
|
21
|
+
id: method.method
|
|
22
|
+
});
|
|
23
|
+
state.iframeComponents.push(iframe);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function displayBrands({summary, method}) {
|
|
27
|
+
function renderBrand(brand) {
|
|
28
|
+
return `
|
|
29
|
+
<figure>
|
|
30
|
+
<img alt="${brand}" src="https://forms.secure-payments.app/payment-instruments/brand/${brand.replace(/\s/, '')}.svg" />
|
|
31
|
+
</figure>
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const {brands} = method;
|
|
36
|
+
summary.insertAdjacentHTML(
|
|
37
|
+
'beforeend',
|
|
38
|
+
`<div class="rebilly-instruments-accordion-brands">${(() => {
|
|
39
|
+
if (brands.length >= 4) {
|
|
40
|
+
const truncatedBrands = brands.slice(0, 3);
|
|
41
|
+
return `${truncatedBrands.map(brand => renderBrand(brand)).join('')}
|
|
42
|
+
<span data-rebilly-i18n="forms.andMore">and more</span>
|
|
43
|
+
`
|
|
44
|
+
}
|
|
45
|
+
return brands.map(brand => renderBrand(brand)).join('');
|
|
46
|
+
})()}</div>`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
6
50
|
export function MountMethods({
|
|
7
51
|
state,
|
|
8
52
|
METHODS_CONTAINER,
|
|
9
53
|
METHODS
|
|
10
54
|
}) {
|
|
55
|
+
const isAccordion = METHODS.length > 1;
|
|
56
|
+
|
|
11
57
|
METHODS.forEach(async (method) => {
|
|
12
58
|
const { METHOD_ID: methodId, METHOD_TYPE: methodType } =
|
|
13
59
|
getMethodData(method);
|
|
@@ -26,25 +72,63 @@ export function MountMethods({
|
|
|
26
72
|
method
|
|
27
73
|
};
|
|
28
74
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
75
|
+
if (isAccordion) {
|
|
76
|
+
METHODS_CONTAINER.insertAdjacentHTML(
|
|
77
|
+
'beforeend',
|
|
78
|
+
`<details class="rebilly-instruments-accordion for-${methodId}">
|
|
79
|
+
<summary class="rebilly-instruments-accordion-summary">
|
|
80
|
+
<span class="rebilly-instruments-accordion-summary-radio"></span>
|
|
81
|
+
<img class="rebilly-instruments-accordion-${method.method}-img" src="${method.metadata.logo}" alt="${method.method}"/>
|
|
82
|
+
<span class="rebilly-instruments-accordion-title" data-rebilly-i18n="paymentMethods.${method.method}">${method.metadata.name}</span>
|
|
83
|
+
</summary>
|
|
84
|
+
<div id="${selector}" data-rebilly-instruments-type="${methodId}"></div>
|
|
85
|
+
</details>`
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
if ([
|
|
89
|
+
'payment-card'
|
|
90
|
+
].includes(method.method)) {
|
|
91
|
+
const summary = document.querySelector(`.for-${methodId} > .rebilly-instruments-accordion-summary`);
|
|
92
|
+
displayBrands({summary, method});
|
|
93
|
+
}
|
|
34
94
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
95
|
+
state.loader.stopLoading({ id: method.method });
|
|
96
|
+
METHODS_CONTAINER.insertAdjacentHTML(
|
|
97
|
+
'beforeend',
|
|
98
|
+
`<div id="${selector}" data-rebilly-instruments-type="${methodId}"></div>`
|
|
99
|
+
);
|
|
100
|
+
const container = document.querySelector(`#${selector}`);
|
|
101
|
+
|
|
102
|
+
state.loader.stopLoading({ id: method.method });
|
|
103
|
+
mountInline(state, {
|
|
104
|
+
methodId,
|
|
105
|
+
paymentMethodsUrl,
|
|
39
106
|
container,
|
|
40
|
-
model
|
|
107
|
+
model,
|
|
108
|
+
method
|
|
41
109
|
});
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
110
|
+
} else if (isiFrame) {
|
|
111
|
+
METHODS_CONTAINER.insertAdjacentHTML(
|
|
112
|
+
'beforeend',
|
|
113
|
+
`<div id="${selector}" data-rebilly-instruments-type="${methodId}"></div>`
|
|
114
|
+
);
|
|
115
|
+
const container = document.querySelector(`#${selector}`);
|
|
116
|
+
|
|
117
|
+
state.loader.stopLoading({ id: method.method });
|
|
118
|
+
mountInline(state, {
|
|
119
|
+
methodId,
|
|
120
|
+
paymentMethodsUrl,
|
|
121
|
+
container,
|
|
122
|
+
model,
|
|
123
|
+
method
|
|
45
124
|
});
|
|
46
|
-
state.iframeComponents.push(iframe);
|
|
47
125
|
} else {
|
|
126
|
+
METHODS_CONTAINER.insertAdjacentHTML(
|
|
127
|
+
'beforeend',
|
|
128
|
+
`<div id="${selector}" data-rebilly-instruments-type="${methodId}"></div>`
|
|
129
|
+
);
|
|
130
|
+
const container = document.querySelector(`#${selector}`);
|
|
131
|
+
|
|
48
132
|
container.insertAdjacentHTML(
|
|
49
133
|
'beforeend',
|
|
50
134
|
`<button class="${selector} rebilly-instruments-button" data-rebilly-i18n="paymentMethods.${
|
|
@@ -64,4 +148,23 @@ export function MountMethods({
|
|
|
64
148
|
state.loader.stopLoading({ id: method.method });
|
|
65
149
|
}
|
|
66
150
|
});
|
|
151
|
+
|
|
152
|
+
if (isAccordion) {
|
|
153
|
+
// Fetch all the accordion elements.
|
|
154
|
+
const details = document.querySelectorAll('.rebilly-instruments-accordion');
|
|
155
|
+
// Add the onclick listeners.
|
|
156
|
+
details.forEach((targetDetail) => {
|
|
157
|
+
targetDetail.addEventListener('click', () => {
|
|
158
|
+
// Close all the accordion that are not targetDetail.
|
|
159
|
+
details.forEach((detail) => {
|
|
160
|
+
detail.removeAttribute('open');
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Open the first accordion by default
|
|
166
|
+
details[0].open = true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
state.translate.translateItems();
|
|
67
170
|
}
|
package/tests/msw/server.js
CHANGED
|
@@ -3,6 +3,7 @@ import {rest} from 'msw';
|
|
|
3
3
|
import {whenThen} from 'msw-when-then';
|
|
4
4
|
import {handlers} from './handlers';
|
|
5
5
|
import {initStoreFrontApiMocks} from '../mocks/storefront-api-mock';
|
|
6
|
+
import {initRebillyApiMocks} from '../mocks/rebilly-api-mock';
|
|
6
7
|
|
|
7
8
|
export const server = setupServer(...handlers);
|
|
8
9
|
|
|
@@ -10,4 +11,5 @@ export const {when} = whenThen(server, rest);
|
|
|
10
11
|
|
|
11
12
|
export const initGlobalHandlers = () => {
|
|
12
13
|
initStoreFrontApiMocks(when);
|
|
14
|
+
initRebillyApiMocks(when);
|
|
13
15
|
};
|