@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebilly/instruments",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0-beta.0",
|
|
4
4
|
"author": "Rebilly",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"unpkg": "dist/index.min.js",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"@rebilly/risk-data-collector": "^2.0.1",
|
|
19
19
|
"autoprefixer": "^10.3.4",
|
|
20
20
|
"css": "^3.0.0",
|
|
21
|
+
"jwt-decode": "^3.1.2",
|
|
21
22
|
"lodash.camelcase": "^4.3.0",
|
|
22
23
|
"lodash.isequal": "^4.5.0",
|
|
23
24
|
"lodash.kebabcase": "^4.1.1",
|
|
@@ -142,9 +142,19 @@ export async function fetchData({
|
|
|
142
142
|
state.options.items ? fetchSummary({ data: summaryPayload, state }) : null
|
|
143
143
|
]);
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
let plans = null;
|
|
146
|
+
let products = null;
|
|
147
|
+
try {
|
|
148
|
+
plans = await fetchPlans({ state });
|
|
149
|
+
state.data.plans = plans;
|
|
150
|
+
} catch(e) {
|
|
151
|
+
plans = [];
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
products = await fetchProducts({ state });
|
|
155
|
+
} catch (e) {
|
|
156
|
+
products = [];
|
|
157
|
+
}
|
|
148
158
|
|
|
149
159
|
return new DataInstance({
|
|
150
160
|
state,
|
|
@@ -67,7 +67,7 @@ import setupUserFlow from './setup-user-flow';
|
|
|
67
67
|
* @param {string | HTMLElement} options.summary - The CSS class or HTML element were the summary will be mounted.
|
|
68
68
|
* @param {Item[]} options.items - Which plans the customer is purchasing.
|
|
69
69
|
* @param {string} options.invoiceId - The Rebilly id of the invoice used for purchasing.
|
|
70
|
-
* @param {string} options.
|
|
70
|
+
* @param {string} options.jwt - The customer token to access the invoice.
|
|
71
71
|
* @param {string} [options.countryCode=USD] - The country code for the transaction
|
|
72
72
|
* @param {PaymentInstruments} options.paymentInstruments - settings for various payment instruments
|
|
73
73
|
* @param {Features} options.features - flags to enable and disable different features
|
|
@@ -92,15 +92,22 @@ export async function mount({
|
|
|
92
92
|
state.loader.startLoading({ id: 'initForm' });
|
|
93
93
|
|
|
94
94
|
// Setup state
|
|
95
|
-
state.storefront = setupStorefront({ options });
|
|
96
95
|
state.options = setupOptions({ options });
|
|
96
|
+
state.storefront = setupStorefront({ options });
|
|
97
97
|
state.mainStyle = await setupStyles({ options });
|
|
98
98
|
state.data = await fetchData({ state });
|
|
99
|
+
|
|
99
100
|
state.options.themeFramepay = await setupFramepayTheme({ state, options });
|
|
100
101
|
state.i18n = setupI18n({ state });
|
|
101
102
|
|
|
102
103
|
setupFramepay({ state });
|
|
103
104
|
|
|
105
|
+
// Update state options from data
|
|
106
|
+
if ((!state.options.websiteId) && state.data.transaction?.websiteId) {
|
|
107
|
+
state.options.websiteId = state.data.transaction.websiteId;
|
|
108
|
+
} else if ((!state.options.websiteId) && state.data.invoice?.websiteId) {
|
|
109
|
+
state.options.websiteId = state.data.invoice.websiteId;
|
|
110
|
+
}
|
|
104
111
|
if (state.data.transaction && state.data.transaction?.type === 'setup') {
|
|
105
112
|
state.options.transactionType = 'setup';
|
|
106
113
|
}
|
|
@@ -69,4 +69,24 @@ describe('RebillyInstruments instance', () => {
|
|
|
69
69
|
);
|
|
70
70
|
expect(FRAMEPAY_STYLE.href).toEqual(framePayStyleUrl);
|
|
71
71
|
});
|
|
72
|
+
|
|
73
|
+
it('should mount with JWT pruchase data', async () => {
|
|
74
|
+
// Use https://www.jwt.io to help encode and decode JWT
|
|
75
|
+
const jwt = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkMGYzNWEzYy03N2M0LTQ0NDItOWFhNC03ODA5NDA2NzBjN2IiLCJleHAiOjE2NzM2NDk0ODcsImlhdCI6MTY0MjExMDczOS4zMjYyNDQsImFjbCI6W3sic2NvcGUiOnsib3JnYW5pemF0aW9uSWQiOlsidGVzdC1vcmdhbml6YXRpb24tZCJdLCJ0cmFuc2FjdGlvbklkIjpbInRlc3QtdHJhbnNhY3Rpb24taWQiXX0sInBlcm1pc3Npb25zIjpbMV19XSwiY2xhaW1zIjp7InRyYW5zYWN0aW9uSWQiOiJ0ZXN0LXRyYW5zYWN0aW9uLWlkIn0sIm1lcmNoYW50IjoidGVzdC1vcmdhbml6YXRpb24taWQiLCJjdXN0b21lciI6eyJpZCI6InRlc3QtY3VzdG9tZXItaWQiLCJuYW1lIjoiVGVzdGVyIFRlc3RlcnNvbiIsImNyZWF0ZWRUaW1lIjoiMjAyMi0wMS0xNFQwMDowMDowMCswMDowMCJ9fQ.h4voW-UvXzXRm1JlxkN8cNHhQ_IIPSWWN9BANfBWEHQ`;
|
|
76
|
+
|
|
77
|
+
const options = {
|
|
78
|
+
form: '.form-selector',
|
|
79
|
+
summary: '.summary-selector',
|
|
80
|
+
jwt,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const instance = await RenderMockRebillyInstruments(options);
|
|
84
|
+
|
|
85
|
+
expect(instance.state.options).toEqual(
|
|
86
|
+
expect.objectContaining({
|
|
87
|
+
transactionId: 'test-transaction-id',
|
|
88
|
+
organizationId: 'test-organization-id'
|
|
89
|
+
})
|
|
90
|
+
);
|
|
91
|
+
});
|
|
72
92
|
});
|
|
@@ -48,33 +48,56 @@ export default async ({
|
|
|
48
48
|
const cssAst = css.parse(resolvedCss);
|
|
49
49
|
|
|
50
50
|
const cssSelectors = {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
51
|
+
input: {
|
|
52
|
+
base: '.rebilly-instruments-form-field-input',
|
|
53
|
+
baseHover: '.rebilly-instruments-form-field-input:hover',
|
|
54
|
+
baseFocus: '.rebilly-instruments-form-field-input:focus',
|
|
55
|
+
basePlaceholder: '.rebilly-instruments-form-field-input::placeholder',
|
|
56
|
+
baseSelection: '.rebilly-instruments-form-field-input::selection',
|
|
57
|
+
|
|
58
|
+
invalid: '.rebilly-instruments-form-field.is-error .rebilly-instruments-form-field-input',
|
|
59
|
+
invalidHover: '.rebilly-instruments-form-field.is-error .rebilly-instruments-form-field-input:hover',
|
|
60
|
+
invalidFocus: '.rebilly-instruments-form-field.is-error .rebilly-instruments-form-field-input:focus',
|
|
61
|
+
invalidPlaceholder: '.rebilly-instruments-form-field.is-error .rebilly-instruments-form-field-input::placeholder',
|
|
62
|
+
invalidSelection: '.rebilly-instruments-form-field.is-error .rebilly-instruments-form-field-input::selection'
|
|
63
|
+
},
|
|
64
|
+
button: {
|
|
65
|
+
base: '.rebilly-instruments-button.rebilly-instruments-button-secondary',
|
|
66
|
+
baseHover: '.rebilly-instruments-button.rebilly-instruments-button-secondary:not([disabled]):hover',
|
|
67
|
+
baseFocus: '.rebilly-instruments-button.rebilly-instruments-button-secondary:not([disabled]):active',
|
|
68
|
+
|
|
69
|
+
active: '.rebilly-instruments-button',
|
|
70
|
+
activeHover: '.rebilly-instruments-button:not([disabled]):hover',
|
|
71
|
+
activeFocus: '.rebilly-instruments-button:not([disabled]):active',
|
|
72
|
+
}
|
|
62
73
|
}
|
|
63
74
|
|
|
64
75
|
const framepayStyle = {
|
|
65
76
|
base: {
|
|
66
|
-
...getStyleProps(cssAst, cssSelectors.base),
|
|
67
|
-
':hover': getStyleProps(cssAst, cssSelectors.baseHover),
|
|
68
|
-
':focus': getStyleProps(cssAst, cssSelectors.baseFocus),
|
|
69
|
-
'::placeholder': getStyleProps(cssAst, cssSelectors.basePlaceholder),
|
|
70
|
-
'::selection': getStyleProps(cssAst, cssSelectors.baseSelection),
|
|
77
|
+
...getStyleProps(cssAst, cssSelectors.input.base),
|
|
78
|
+
':hover': getStyleProps(cssAst, cssSelectors.input.baseHover),
|
|
79
|
+
':focus': getStyleProps(cssAst, cssSelectors.input.baseFocus),
|
|
80
|
+
'::placeholder': getStyleProps(cssAst, cssSelectors.input.basePlaceholder),
|
|
81
|
+
'::selection': getStyleProps(cssAst, cssSelectors.input.baseSelection),
|
|
71
82
|
},
|
|
72
83
|
invalid: {
|
|
73
|
-
...getStyleProps(cssAst, cssSelectors.invalid),
|
|
74
|
-
':hover': getStyleProps(cssAst, cssSelectors.invalidHover),
|
|
75
|
-
':focus': getStyleProps(cssAst, cssSelectors.invalidFocus),
|
|
76
|
-
'::placeholder': getStyleProps(cssAst, cssSelectors.invalidPlaceholder),
|
|
77
|
-
'::selection': getStyleProps(cssAst, cssSelectors.invalidSelection),
|
|
84
|
+
...getStyleProps(cssAst, cssSelectors.input.invalid),
|
|
85
|
+
':hover': getStyleProps(cssAst, cssSelectors.input.invalidHover),
|
|
86
|
+
':focus': getStyleProps(cssAst, cssSelectors.input.invalidFocus),
|
|
87
|
+
'::placeholder': getStyleProps(cssAst, cssSelectors.input.invalidPlaceholder),
|
|
88
|
+
'::selection': getStyleProps(cssAst, cssSelectors.input.invalidSelection),
|
|
89
|
+
},
|
|
90
|
+
buttons: {
|
|
91
|
+
base: {
|
|
92
|
+
...getStyleProps(cssAst, cssSelectors.button.base),
|
|
93
|
+
':hover': getStyleProps(cssAst, cssSelectors.button.baseHover),
|
|
94
|
+
':focus': getStyleProps(cssAst, cssSelectors.button.baseFocus),
|
|
95
|
+
},
|
|
96
|
+
active: {
|
|
97
|
+
...getStyleProps(cssAst, cssSelectors.button.active),
|
|
98
|
+
':hover': getStyleProps(cssAst, cssSelectors.button.activeHover),
|
|
99
|
+
':focus': getStyleProps(cssAst, cssSelectors.button.activeFocus),
|
|
100
|
+
}
|
|
78
101
|
}
|
|
79
102
|
}
|
|
80
103
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import merge from 'lodash.merge';
|
|
2
|
+
import decodeJwt from 'jwt-decode';
|
|
2
3
|
|
|
3
4
|
export const defaults = {
|
|
4
5
|
countryCode: 'US',
|
|
@@ -46,6 +47,7 @@ export const defaults = {
|
|
|
46
47
|
export function validateOptions(options) {
|
|
47
48
|
// TODO: validate more options
|
|
48
49
|
const purchaseData = [
|
|
50
|
+
options.jwt,
|
|
49
51
|
options.items,
|
|
50
52
|
options.invoiceId,
|
|
51
53
|
options.money,
|
|
@@ -57,6 +59,10 @@ export function validateOptions(options) {
|
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
if (purchaseData.length > 1) {
|
|
62
|
+
// JWT can be alone or with specific invoiceId or transactionId
|
|
63
|
+
if (options.jwt && (options.invoiceId || options.transactionId)) {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
60
66
|
throw new Error('Must provide only one purchase data type');
|
|
61
67
|
}
|
|
62
68
|
}
|
|
@@ -64,6 +70,7 @@ export function validateOptions(options) {
|
|
|
64
70
|
export default ({
|
|
65
71
|
options = {}
|
|
66
72
|
} = {}) => {
|
|
73
|
+
|
|
67
74
|
validateOptions(options);
|
|
68
75
|
|
|
69
76
|
const _computed = {
|
|
@@ -73,9 +80,6 @@ export default ({
|
|
|
73
80
|
};
|
|
74
81
|
|
|
75
82
|
const combinedOptions = merge({...defaults}, {
|
|
76
|
-
organizationId: options.organizationId,
|
|
77
|
-
publishableKey: options.publishableKey,
|
|
78
|
-
websiteId: options.websiteId,
|
|
79
83
|
apiMode: options.apiMode,
|
|
80
84
|
i18n: options.i18n,
|
|
81
85
|
theme: options.theme,
|
|
@@ -88,13 +92,42 @@ export default ({
|
|
|
88
92
|
_computed
|
|
89
93
|
});
|
|
90
94
|
|
|
95
|
+
if (options.publishableKey) {
|
|
96
|
+
Object.entries({
|
|
97
|
+
organizationId: options.organizationId,
|
|
98
|
+
publishableKey: options.publishableKey,
|
|
99
|
+
websiteId: options.websiteId,
|
|
100
|
+
}).forEach(([key, value]) => {
|
|
101
|
+
combinedOptions[key] = value;
|
|
102
|
+
});
|
|
103
|
+
} else if (options.jwt) {
|
|
104
|
+
combinedOptions.jwt = options.jwt;
|
|
105
|
+
const {
|
|
106
|
+
merchant: organizationId,
|
|
107
|
+
claims: {
|
|
108
|
+
transactionId,
|
|
109
|
+
invoiceId,
|
|
110
|
+
}
|
|
111
|
+
} = decodeJwt(combinedOptions.jwt);
|
|
112
|
+
|
|
113
|
+
combinedOptions.organizationId = organizationId;
|
|
114
|
+
|
|
115
|
+
if (transactionId) {
|
|
116
|
+
combinedOptions.transactionId = transactionId;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (invoiceId) {
|
|
120
|
+
combinedOptions.invoiceId = invoiceId;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
91
124
|
// Add optional key's
|
|
92
125
|
[
|
|
93
126
|
'items',
|
|
94
127
|
'money',
|
|
95
128
|
'invoiceId',
|
|
96
129
|
'transactionId',
|
|
97
|
-
'
|
|
130
|
+
'jwt',
|
|
98
131
|
'_dev'
|
|
99
132
|
].forEach(key => {
|
|
100
133
|
if (options[key]) {
|
|
@@ -21,8 +21,7 @@ describe('Setup mount options', () => {
|
|
|
21
21
|
publishableKey: 'test-publishable-key',
|
|
22
22
|
organizationId: 'test-organization-id',
|
|
23
23
|
websiteId: 'test-website-id',
|
|
24
|
-
|
|
25
|
-
customerJwt: 'test-customer-jwt'
|
|
24
|
+
jwt: 'test-jwt'
|
|
26
25
|
}
|
|
27
26
|
const rebillyInstruments = await RenderMockRebillyInstruments(options);
|
|
28
27
|
expect(rebillyInstruments.state.options).toMatchObject(options);
|
|
@@ -9,11 +9,14 @@ export default ({
|
|
|
9
9
|
}
|
|
10
10
|
}) => {
|
|
11
11
|
const storefront = {
|
|
12
|
-
publishableKey,
|
|
13
12
|
orgnizationId,
|
|
14
13
|
mode: apiMode || 'live'
|
|
15
14
|
};
|
|
16
15
|
|
|
16
|
+
if (publishableKey) {
|
|
17
|
+
storefront.publishableKey = publishableKey;
|
|
18
|
+
}
|
|
19
|
+
|
|
17
20
|
if (_dev) {
|
|
18
21
|
storefront.liveUrl = _dev.liveUrl || 'https://api.rebilly.com';
|
|
19
22
|
storefront.sandboxUrl =
|
package/src/i18n/en.json
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"expressCheckout": "Express checkout",
|
|
12
12
|
"or": "Or",
|
|
13
13
|
"popupOverlayText": "Click here to show popup window",
|
|
14
|
+
"andMore": "and more",
|
|
14
15
|
"error": {
|
|
15
16
|
"noPaymentMethods": "No payment methods available for this transaction, please contact support."
|
|
16
17
|
},
|
|
@@ -19,7 +20,8 @@
|
|
|
19
20
|
}
|
|
20
21
|
},
|
|
21
22
|
"paymentMethods": {
|
|
22
|
-
"payment-card": "Payment card"
|
|
23
|
+
"payment-card": "Payment card",
|
|
24
|
+
"ach": "Bank account"
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
27
|
}
|
package/src/i18n/es.json
CHANGED
|
@@ -10,13 +10,15 @@
|
|
|
10
10
|
"form": {
|
|
11
11
|
"expressCheckout": "Chequeo rápido",
|
|
12
12
|
"or": "O pague con",
|
|
13
|
+
"andMore": "y más",
|
|
13
14
|
"popupOverlayText": "Haga clic aquí para mostrar la ventana emergente",
|
|
14
15
|
"error": {
|
|
15
16
|
"noPaymentMethods": "No hay métodos de pago disponibles para esta transacción, por favor, póngase en contacto con el servicio de asistencia."
|
|
16
17
|
}
|
|
17
18
|
},
|
|
18
19
|
"paymentMethods": {
|
|
19
|
-
"payment-card": "Tarjeta de crédito"
|
|
20
|
+
"payment-card": "Tarjeta de crédito",
|
|
21
|
+
"ach": "Cuenta bancaria"
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
}
|
package/src/storefront/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import RebillyApi, {RebillyStorefrontAPI} from 'rebilly-js-sdk';
|
|
2
2
|
|
|
3
3
|
export function validateStateForStorefront({state}) {
|
|
4
4
|
if (!state.storefront) {
|
|
@@ -31,6 +31,7 @@ export async function Endpoint({
|
|
|
31
31
|
export class StorefrontInstance {
|
|
32
32
|
constructor({
|
|
33
33
|
publishableKey = null,
|
|
34
|
+
jwt = null,
|
|
34
35
|
organizationId = null,
|
|
35
36
|
mode = 'live',
|
|
36
37
|
timeout = 10000,
|
|
@@ -42,18 +43,25 @@ export class StorefrontInstance {
|
|
|
42
43
|
sandbox: sandboxUrl || 'https://api-sandbox.rebilly.com'
|
|
43
44
|
};
|
|
44
45
|
|
|
45
|
-
const
|
|
46
|
+
const config = {
|
|
46
47
|
organizationId,
|
|
47
48
|
sandbox: mode === 'sandbox',
|
|
48
49
|
timeout: Number.isNaN(parseInt(timeout, 10))
|
|
49
50
|
? 10000
|
|
50
51
|
: parseInt(timeout, 10),
|
|
51
52
|
urls
|
|
52
|
-
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const api = RebillyStorefrontAPI(config);
|
|
56
|
+
// TODO: Check why Rollup is making the default as an named export
|
|
57
|
+
const rebilly = typeof RebillyApi.default === 'function' ? RebillyApi.default(config) : RebillyApi(config);
|
|
53
58
|
|
|
54
|
-
api.
|
|
59
|
+
api.setSessionToken(publishableKey || jwt);
|
|
60
|
+
rebilly.setSessionToken(publishableKey || jwt);
|
|
55
61
|
|
|
56
62
|
this.api = api;
|
|
63
|
+
this.api.rebilly = rebilly;
|
|
64
|
+
|
|
57
65
|
return this.api;
|
|
58
66
|
}
|
|
59
67
|
}
|
|
@@ -3,7 +3,7 @@ import { Endpoint } from './index';
|
|
|
3
3
|
|
|
4
4
|
export async function fetchInvoice({ data = null, state = null }) {
|
|
5
5
|
return Endpoint({state}, async () => {
|
|
6
|
-
state.storefront.setSessionToken(state.options.
|
|
6
|
+
state.storefront.setSessionToken(state.options.jwt);
|
|
7
7
|
const {fields} = await state.storefront.invoices.get(data);
|
|
8
8
|
|
|
9
9
|
return new InvoiceModel(fields);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import PaymentMetadataModel from './payment-metadata';
|
|
2
|
+
|
|
1
3
|
export class ReadyToPayFeatureModel {
|
|
2
4
|
constructor({
|
|
3
5
|
name = '',
|
|
@@ -16,6 +18,7 @@ export class ReadyToPayFeatureModel {
|
|
|
16
18
|
} = {}) {
|
|
17
19
|
this.name = name;
|
|
18
20
|
this.expirationTime = expirationTime;
|
|
21
|
+
|
|
19
22
|
|
|
20
23
|
this.merchantName = merchantName;
|
|
21
24
|
this.merchantOrigin = merchantOrigin;
|
|
@@ -33,12 +36,14 @@ export default class ReadyToPayModel {
|
|
|
33
36
|
method = '',
|
|
34
37
|
feature = null,
|
|
35
38
|
brands = [],
|
|
36
|
-
filters = []
|
|
39
|
+
filters = [],
|
|
40
|
+
metadata = null
|
|
37
41
|
} = {}) {
|
|
38
42
|
this.index = index;
|
|
39
43
|
this.method = method;
|
|
40
44
|
this.feature = feature ? new ReadyToPayFeatureModel(feature) : null;
|
|
41
45
|
this.brands = brands;
|
|
42
46
|
this.filters = filters;
|
|
47
|
+
this.metadata = metadata ? new PaymentMetadataModel(metadata) : null;
|
|
43
48
|
}
|
|
44
49
|
}
|
|
@@ -3,11 +3,13 @@ import { Endpoint } from './index';
|
|
|
3
3
|
|
|
4
4
|
export async function fetchProducts({ state }) {
|
|
5
5
|
return Endpoint({state}, async () => {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
let plansData = [];
|
|
7
|
+
if (state.data.plans) {
|
|
8
|
+
plansData = state.data.plans;
|
|
9
|
+
}
|
|
10
|
+
if (state.data.invoice?.items) {
|
|
11
|
+
plansData = state.data.invoice.items;
|
|
8
12
|
}
|
|
9
|
-
|
|
10
|
-
const plansData = state.data.plans || [];
|
|
11
13
|
const filterByProductId = {
|
|
12
14
|
filter: ''
|
|
13
15
|
};
|
|
@@ -8,13 +8,21 @@ export async function fetchReadyToPay({ state, riskMetadata = null }) {
|
|
|
8
8
|
const { riskMetadata: data } = await collectData();
|
|
9
9
|
riskMetadata = data;
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
|
|
13
12
|
const data = {
|
|
14
|
-
websiteId,
|
|
15
13
|
riskMetadata
|
|
16
14
|
};
|
|
17
|
-
|
|
15
|
+
|
|
16
|
+
let websiteId = state.options?.websiteId || null;
|
|
17
|
+
if (!websiteId) {
|
|
18
|
+
if (state.data.transaction?.websiteId) {
|
|
19
|
+
websiteId = state.data.transaction.websiteId
|
|
20
|
+
} else if (state.data.invoice?.websiteId) {
|
|
21
|
+
websiteId = state.data.invoice.websiteId;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
data.websiteId = websiteId;
|
|
25
|
+
|
|
18
26
|
if (state.options?.items) {
|
|
19
27
|
data.items = state.options.items;
|
|
20
28
|
}
|
|
@@ -25,16 +33,28 @@ export async function fetchReadyToPay({ state, riskMetadata = null }) {
|
|
|
25
33
|
data.currency = money.currency;
|
|
26
34
|
}
|
|
27
35
|
|
|
28
|
-
const
|
|
29
|
-
|
|
36
|
+
const [
|
|
37
|
+
{ fields: readyToPayFields },
|
|
38
|
+
{ items: paymentMethodsMetadataItems }
|
|
39
|
+
] = await Promise.all([
|
|
40
|
+
state.storefront.purchase.readyToPay({ data }),
|
|
41
|
+
state.storefront.rebilly.paymentMethods.getAll()
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
const paymentMethodsMetadata = paymentMethodsMetadataItems.map(({fields}) => fields);
|
|
30
45
|
|
|
31
46
|
return Object.values(readyToPayFields)
|
|
32
47
|
// Remove result for "old" paypal method
|
|
33
48
|
.filter((fields) => !(fields.method === 'paypal' && !fields.feature))
|
|
34
|
-
.map((fields, index) =>
|
|
49
|
+
.map((fields, index) => {
|
|
50
|
+
const metadata = paymentMethodsMetadata
|
|
51
|
+
.find(methodMetadata => methodMetadata.apiName === fields.method);
|
|
52
|
+
|
|
53
|
+
return new ReadyToPayModel({
|
|
35
54
|
index,
|
|
55
|
+
metadata,
|
|
36
56
|
...fields
|
|
37
|
-
})
|
|
38
|
-
);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
39
59
|
});
|
|
40
60
|
}
|
|
@@ -3,7 +3,7 @@ import { Endpoint } from './index';
|
|
|
3
3
|
|
|
4
4
|
export async function fetchTransaction({ data = null, state = null }) {
|
|
5
5
|
return Endpoint({state}, async () => {
|
|
6
|
-
state.storefront.setSessionToken(state.options.
|
|
6
|
+
state.storefront.setSessionToken(state.options.jwt);
|
|
7
7
|
const {fields} = await state.storefront.transactions.get(data);
|
|
8
8
|
|
|
9
9
|
return new TransactionModel(fields);
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { lighten } from '../utils/color-values';
|
|
2
|
+
|
|
3
|
+
// -----------------------------------------------------------------------------
|
|
4
|
+
// This file contains all styles related to the accordion component.
|
|
5
|
+
// -----------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
export const accordion = (theme) => `
|
|
8
|
+
/* ACCORDION CLOSED */
|
|
9
|
+
.rebilly-instruments-accordion {
|
|
10
|
+
border: 1px solid var(--rebilly-colorMutedBorder);
|
|
11
|
+
padding: 0 var(--rebilly-spacings-s);
|
|
12
|
+
background: var(--rebilly-colorBackground);
|
|
13
|
+
transition: border 0.2s ease, box-shadow 0.2s ease;
|
|
14
|
+
margin: var(--rebilly-spacings-s) 0;
|
|
15
|
+
border-radius: var(--rebilly-borderRadius);
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.rebilly-instruments-accordion:first-of-type {
|
|
21
|
+
margin-top: 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.rebilly-instruments-accordion:last-of-type {
|
|
25
|
+
margin-bottom: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.rebilly-instruments-accordion .rebilly-instruments-accordion-summary::-webkit-details-marker {
|
|
29
|
+
display: none;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.rebilly-instruments-accordion .rebilly-instruments-accordion-summary {
|
|
33
|
+
display: flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
list-style: none;
|
|
36
|
+
padding: var(--rebilly-spacings-xs) var(--rebilly-spacings-s);
|
|
37
|
+
margin: 0px calc(-1 * var(--rebilly-spacings-s));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.rebilly-instruments-accordion .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-summary-radio {
|
|
41
|
+
height: 18px;
|
|
42
|
+
width: 18px;
|
|
43
|
+
border-radius: 50%;
|
|
44
|
+
margin-right: var(--rebilly-spacings-s);
|
|
45
|
+
border: 1px solid var(--rebilly-colorMutedBorder);
|
|
46
|
+
box-shadow: 0 0 0 0 transparent;
|
|
47
|
+
transition: all 0.2s ease;
|
|
48
|
+
position: relative;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.rebilly-instruments-accordion .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-summary-radio::after {
|
|
52
|
+
content: '';
|
|
53
|
+
position: absolute;
|
|
54
|
+
width: 10px;
|
|
55
|
+
height: 10px;
|
|
56
|
+
top: 50%;
|
|
57
|
+
left: 50%;
|
|
58
|
+
transform: translate(-50%, -50%) scale(0.4);
|
|
59
|
+
opacity: 0;
|
|
60
|
+
background: var(--rebilly-colorPrimary);
|
|
61
|
+
border-radius: 50%;
|
|
62
|
+
transition: all 0.2s ease;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.rebilly-instruments-accordion:hover .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-summary-radio {
|
|
66
|
+
border-color: ${lighten(theme.colorText, 60)};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.rebilly-instruments-accordion .rebilly-instruments-accordion-summary img {
|
|
70
|
+
margin-right: var(--rebilly-spacings-s);
|
|
71
|
+
height: auto;
|
|
72
|
+
max-width: 40px;
|
|
73
|
+
width: 100%;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.rebilly-instruments-accordion .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-title {
|
|
77
|
+
margin: 0;
|
|
78
|
+
font-weight: 500;
|
|
79
|
+
flex: 2;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.rebilly-instruments-accordion .rebilly-instruments-accordion-brands {
|
|
83
|
+
display: inline-flex;
|
|
84
|
+
justify-content: flex-end;
|
|
85
|
+
align-items: center;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.rebilly-instruments-accordion .rebilly-instruments-accordion-brands figure {
|
|
89
|
+
margin: auto;
|
|
90
|
+
padding: 0;
|
|
91
|
+
height: 26px;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.rebilly-instruments-accordion .rebilly-instruments-accordion-brands figure img {
|
|
95
|
+
width: auto;
|
|
96
|
+
height: 100%;
|
|
97
|
+
border-radius: 4px;
|
|
98
|
+
margin-right: var(--rebilly-spacings-xs);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.rebilly-instruments-accordion .rebilly-instruments-accordion-brands span {
|
|
102
|
+
color: var(--rebilly-colorMutedText);
|
|
103
|
+
margin: 0;
|
|
104
|
+
font-size: calc(var(--rebilly-fontSizeBase) * 0.875);
|
|
105
|
+
line-height: 1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* ACCORDION OPENED */
|
|
109
|
+
.rebilly-instruments-accordion[open] {
|
|
110
|
+
padding: 0 var(--rebilly-spacings-s) var(--rebilly-spacings-s);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.rebilly-instruments-accordion[open] .rebilly-instruments-accordion-summary {
|
|
114
|
+
border-bottom: 1px solid var(--rebilly-colorMutedBorder);
|
|
115
|
+
margin-bottom: var(--rebilly-spacings-m);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.rebilly-instruments-accordion[open] .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-summary-radio {
|
|
119
|
+
border-color: var(--rebilly-colorPrimary);
|
|
120
|
+
box-shadow: 0 0 0 1px var(--rebilly-colorPrimary);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.rebilly-instruments-accordion[open] .rebilly-instruments-accordion-summary .rebilly-instruments-accordion-summary-radio::after {
|
|
124
|
+
transform: translate(-50%, -50%) scale(1);
|
|
125
|
+
opacity: 1;
|
|
126
|
+
}
|
|
127
|
+
`;
|
|
@@ -50,6 +50,9 @@ export const button = () => `
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
.rebilly-instruments-button.rebilly-instruments-button-secondary {
|
|
53
|
+
font-size: var(--rebilly-buttonFontSize);
|
|
54
|
+
font-family: var(--rebilly-buttonFontFamily);
|
|
55
|
+
line-height: var(--rebilly-buttonFontLineHeight);
|
|
53
56
|
background: var(--rebilly-colorBackground);
|
|
54
57
|
color: var(--rebilly-buttonColorBackground);
|
|
55
58
|
border-color: var(--rebilly-buttonColorBackground);
|
|
@@ -13,7 +13,6 @@ export const form = () => `
|
|
|
13
13
|
.rebilly-instruments-form select:-webkit-autofill:hover,
|
|
14
14
|
.rebilly-instruments-form select:-webkit-autofill:focus {
|
|
15
15
|
-webkit-text-fill-color: var(--rebilly-colorText);
|
|
16
|
-
-
|
|
17
|
-
transition: background-color 5000s ease-in-out 0s;
|
|
16
|
+
transition: background-color 5000s ease-in-out 0s, box-shadow 200ms, border 200ms;
|
|
18
17
|
}
|
|
19
18
|
`;
|