@rebilly/instruments 3.2.1-beta.0 → 3.4.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 +1 -1
- package/src/functions/mount/index.js +5 -3
- package/src/functions/mount/mount.spec.js +5 -7
- package/src/functions/mount/setup-framepay-theme.js +44 -21
- package/src/functions/mount/setup-framepay.js +17 -38
- package/src/functions/mount/setup-options.js +6 -1
- package/src/functions/mount/setup-options.spec.js +1 -2
- package/src/functions/purchase.js +13 -4
- package/src/functions/setup.js +20 -2
- package/src/i18n/en.json +3 -1
- package/src/i18n/es.json +3 -1
- package/src/instance.spec.js +4 -2
- package/src/storefront/index.js +11 -9
- 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/payment-instruments.js +2 -2
- package/src/storefront/ready-to-pay.js +19 -5
- package/src/storefront/transactions.js +1 -1
- package/src/style/components/accordion.js +127 -0
- package/src/style/components/button.js +20 -0
- package/src/style/components/forms/checkbox.js +17 -19
- package/src/style/components/forms/form.js +1 -2
- package/src/style/components/forms/radio.js +80 -0
- package/src/style/components/index.js +5 -1
- package/src/style/helpers/index.js +3 -0
- package/src/style/payment-instruments/index.js +4 -0
- package/src/style/payment-instruments/payment-instrument-list.js +44 -0
- package/src/style/payment-instruments/payment-instrument.js +43 -0
- package/src/style/views/confirmation.js +0 -51
- package/src/views/method-selector/get-payment-methods.js +1 -1
- package/src/views/method-selector/mount-methods.js +126 -23
- package/tests/mocks/rebilly-api-mock.js +9 -0
- package/tests/mocks/rebilly-instruments-mock.js +22 -18
- package/tests/msw/server.js +2 -0
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@ import { fetchData } from './fetch-data';
|
|
|
5
5
|
import setupElement from './setup-element';
|
|
6
6
|
import setupStorefront from './setup-storefront';
|
|
7
7
|
import setupOptions from './setup-options';
|
|
8
|
-
import
|
|
8
|
+
import setupFramepayInstance from './setup-framepay';
|
|
9
9
|
import setupStyles from './setup-styles';
|
|
10
10
|
import setupI18n from './setup-i18n';
|
|
11
11
|
import setupFramepayTheme from './setup-framepay-theme';
|
|
@@ -63,11 +63,12 @@ import setupUserFlow from './setup-user-flow';
|
|
|
63
63
|
* Mount library with configurations.
|
|
64
64
|
* @param {object} options - The options object
|
|
65
65
|
* @param {object} options.state - Global state
|
|
66
|
+
* @param {function} options.setupFramepayInstance - Helper for adding FramePay scripts to the DOM
|
|
66
67
|
* @param {string | HTMLElement} options.form - The CSS class or HTML element were the form will be mounted.
|
|
67
68
|
* @param {string | HTMLElement} options.summary - The CSS class or HTML element were the summary will be mounted.
|
|
68
69
|
* @param {Item[]} options.items - Which plans the customer is purchasing.
|
|
69
70
|
* @param {string} options.invoiceId - The Rebilly id of the invoice used for purchasing.
|
|
70
|
-
* @param {string} options.
|
|
71
|
+
* @param {string} options.jwt - The customer token to access the invoice.
|
|
71
72
|
* @param {string} [options.countryCode=USD] - The country code for the transaction
|
|
72
73
|
* @param {PaymentInstruments} options.paymentInstruments - settings for various payment instruments
|
|
73
74
|
* @param {Features} options.features - flags to enable and disable different features
|
|
@@ -75,6 +76,7 @@ import setupUserFlow from './setup-user-flow';
|
|
|
75
76
|
*/
|
|
76
77
|
export async function mount({
|
|
77
78
|
state,
|
|
79
|
+
setupFramepay = setupFramepayInstance,
|
|
78
80
|
...options
|
|
79
81
|
} = {}) {
|
|
80
82
|
try {
|
|
@@ -100,7 +102,7 @@ export async function mount({
|
|
|
100
102
|
state.options.themeFramepay = await setupFramepayTheme({ state, options });
|
|
101
103
|
state.i18n = setupI18n({ state });
|
|
102
104
|
|
|
103
|
-
setupFramepay(
|
|
105
|
+
await setupFramepay(state);
|
|
104
106
|
|
|
105
107
|
// Update state options from data
|
|
106
108
|
if ((!state.options.websiteId) && state.data.transaction?.websiteId) {
|
|
@@ -8,9 +8,9 @@ import ProductModel from '@/storefront/models/product-model';
|
|
|
8
8
|
import SummaryModel from '@/storefront/models/summary-model';
|
|
9
9
|
|
|
10
10
|
describe('RebillyInstruments instance', () => {
|
|
11
|
-
it(
|
|
11
|
+
it('should inject HTML to the merchant\'s website', async () => {
|
|
12
12
|
const framePayScriptUrl = 'https://framepay.rebilly.com/rebilly.js';
|
|
13
|
-
const framePayStyleUrl = 'https://
|
|
13
|
+
const framePayStyleUrl = 'https://framepay.rebilly.com/rebilly.css';
|
|
14
14
|
|
|
15
15
|
const options = {
|
|
16
16
|
form: '.form-selector',
|
|
@@ -34,7 +34,6 @@ describe('RebillyInstruments instance', () => {
|
|
|
34
34
|
framePayStyleLink: framePayStyleUrl
|
|
35
35
|
},
|
|
36
36
|
};
|
|
37
|
-
|
|
38
37
|
await RenderMockRebillyInstruments(options);
|
|
39
38
|
|
|
40
39
|
// Mounts form and summary
|
|
@@ -64,15 +63,14 @@ describe('RebillyInstruments instance', () => {
|
|
|
64
63
|
|
|
65
64
|
// Mounts _dev FramePay style
|
|
66
65
|
const STYLE_LINKS = [...document.querySelectorAll('head link')];
|
|
67
|
-
const FRAMEPAY_STYLE = STYLE_LINKS.find(
|
|
68
|
-
|
|
69
|
-
);
|
|
66
|
+
const FRAMEPAY_STYLE = STYLE_LINKS.find(script => script.href === framePayStyleUrl);
|
|
67
|
+
|
|
70
68
|
expect(FRAMEPAY_STYLE.href).toEqual(framePayStyleUrl);
|
|
71
69
|
});
|
|
72
70
|
|
|
73
71
|
it('should mount with JWT pruchase data', async () => {
|
|
74
72
|
// Use https://www.jwt.io to help encode and decode JWT
|
|
75
|
-
const jwt =
|
|
73
|
+
const jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJkMGYzNWEzYy03N2M0LTQ0NDItOWFhNC03ODA5NDA2NzBjN2IiLCJleHAiOjE2NzM2NDk0ODcsImlhdCI6MTY0MjExMDczOS4zMjYyNDQsImFjbCI6W3sic2NvcGUiOnsib3JnYW5pemF0aW9uSWQiOlsidGVzdC1vcmdhbml6YXRpb24tZCJdLCJ0cmFuc2FjdGlvbklkIjpbInRlc3QtdHJhbnNhY3Rpb24taWQiXX0sInBlcm1pc3Npb25zIjpbMV19XSwiY2xhaW1zIjp7InRyYW5zYWN0aW9uSWQiOiJ0ZXN0LXRyYW5zYWN0aW9uLWlkIn0sIm1lcmNoYW50IjoidGVzdC1vcmdhbml6YXRpb24taWQiLCJjdXN0b21lciI6eyJpZCI6InRlc3QtY3VzdG9tZXItaWQiLCJuYW1lIjoiVGVzdGVyIFRlc3RlcnNvbiIsImNyZWF0ZWRUaW1lIjoiMjAyMi0wMS0xNFQwMDowMDowMCswMDowMCJ9fQ.h4voW-UvXzXRm1JlxkN8cNHhQ_IIPSWWN9BANfBWEHQ';
|
|
76
74
|
|
|
77
75
|
const options = {
|
|
78
76
|
form: '.form-selector',
|
|
@@ -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,41 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
export default async function setupFramepay (state = {}) {
|
|
2
|
+
const {_dev} = state.options || {};
|
|
3
|
+
const urls = {
|
|
4
|
+
script: _dev?.framePayScriptLink || 'https://framepay.rebilly.com/rebilly.js',
|
|
5
|
+
style: _dev?.framePayStyleLink || 'https://framepay.rebilly.com/rebilly.css',
|
|
6
|
+
};
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
} = {}) => {
|
|
10
|
-
const framePayUrls = {
|
|
11
|
-
script: _dev
|
|
12
|
-
? _dev.framePayScriptLink || 'https://framepay.rebilly.com/rebilly.js'
|
|
13
|
-
: 'https://framepay.rebilly.com/rebilly.js',
|
|
14
|
-
style: _dev
|
|
15
|
-
? _dev.framePayStyleLink || 'https://framepay.rebilly.com/rebilly.css'
|
|
16
|
-
: 'https://framepay.rebilly.com/rebilly.css'
|
|
17
|
-
};
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
const framepayStyle = document.createElement('link');
|
|
10
|
+
framepayStyle.setAttribute('href', urls.style);
|
|
11
|
+
framepayStyle.setAttribute('rel', 'stylesheet');
|
|
12
|
+
document.head.prepend(framepayStyle);
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
src: framePayUrls.script
|
|
25
|
-
},
|
|
26
|
-
target: 'head'
|
|
14
|
+
const framepayScript = document.createElement('script');
|
|
15
|
+
framepayScript.setAttribute('src', urls.script);
|
|
16
|
+
|
|
17
|
+
framepayScript.onload = () => resolve();
|
|
18
|
+
document.head.append(framepayScript);
|
|
27
19
|
});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (!document.querySelectorAll('[framepay*="stylesheet"]').length) {
|
|
31
|
-
addDOMElement({
|
|
32
|
-
element: 'link',
|
|
33
|
-
attributes: {
|
|
34
|
-
framepay: 'stylesheet',
|
|
35
|
-
href: framePayUrls.style,
|
|
36
|
-
rel: 'stylesheet'
|
|
37
|
-
},
|
|
38
|
-
target: 'head'
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
}
|
|
20
|
+
}
|
|
@@ -59,6 +59,10 @@ export function validateOptions(options) {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
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
|
+
}
|
|
62
66
|
throw new Error('Must provide only one purchase data type');
|
|
63
67
|
}
|
|
64
68
|
}
|
|
@@ -66,6 +70,7 @@ export function validateOptions(options) {
|
|
|
66
70
|
export default ({
|
|
67
71
|
options = {}
|
|
68
72
|
} = {}) => {
|
|
73
|
+
|
|
69
74
|
validateOptions(options);
|
|
70
75
|
|
|
71
76
|
const _computed = {
|
|
@@ -122,7 +127,7 @@ export default ({
|
|
|
122
127
|
'money',
|
|
123
128
|
'invoiceId',
|
|
124
129
|
'transactionId',
|
|
125
|
-
'
|
|
130
|
+
'jwt',
|
|
126
131
|
'_dev'
|
|
127
132
|
].forEach(key => {
|
|
128
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);
|
|
@@ -6,15 +6,24 @@ import { DataInstance } from './mount/fetch-data';
|
|
|
6
6
|
export async function makePayment({ state, payload }) {
|
|
7
7
|
const {
|
|
8
8
|
_raw: {
|
|
9
|
-
id
|
|
10
|
-
}
|
|
9
|
+
id
|
|
10
|
+
},
|
|
11
|
+
isExistingInstrument
|
|
11
12
|
} = payload;
|
|
13
|
+
delete payload.isExistingInstrument;
|
|
14
|
+
delete payload._raw;
|
|
12
15
|
|
|
13
16
|
const data = {
|
|
14
|
-
token,
|
|
15
17
|
...payload
|
|
16
18
|
};
|
|
17
19
|
|
|
20
|
+
if (isExistingInstrument) {
|
|
21
|
+
data.paymentInstrumentId = id;
|
|
22
|
+
|
|
23
|
+
} else {
|
|
24
|
+
data.token = id;
|
|
25
|
+
}
|
|
26
|
+
|
|
18
27
|
if (state.options.invoiceId) {
|
|
19
28
|
data.invoiceId = state.options.invoiceId;
|
|
20
29
|
}
|
|
@@ -36,7 +45,7 @@ export async function makePayment({ state, payload }) {
|
|
|
36
45
|
|
|
37
46
|
fields = {
|
|
38
47
|
transaction: fields,
|
|
39
|
-
token: fields.token || state.options.
|
|
48
|
+
token: fields.token || state.options.jwt
|
|
40
49
|
};
|
|
41
50
|
|
|
42
51
|
if (state.data.invoice) {
|
package/src/functions/setup.js
CHANGED
|
@@ -5,12 +5,30 @@ import { DataInstance } from './mount/fetch-data';
|
|
|
5
5
|
|
|
6
6
|
export async function setup({ state, payload }) {
|
|
7
7
|
try {
|
|
8
|
+
const {
|
|
9
|
+
_raw: {
|
|
10
|
+
id
|
|
11
|
+
},
|
|
12
|
+
isExistingInstrument
|
|
13
|
+
} = payload;
|
|
14
|
+
delete payload.isExistingInstrument;
|
|
15
|
+
delete payload._raw;
|
|
16
|
+
|
|
17
|
+
const data = {
|
|
18
|
+
...payload
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
if (isExistingInstrument) {
|
|
22
|
+
data.paymentInstrumentId = id;
|
|
23
|
+
} else {
|
|
24
|
+
data.token = id;
|
|
25
|
+
}
|
|
26
|
+
|
|
8
27
|
const {instrument, transaction} = await setupPaymentInstrument({
|
|
9
28
|
state,
|
|
10
29
|
data: {
|
|
11
|
-
token: payload._raw.id,
|
|
12
30
|
websiteId: state.options?.websiteId,
|
|
13
|
-
...
|
|
31
|
+
...data
|
|
14
32
|
}
|
|
15
33
|
});
|
|
16
34
|
|
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/instance.spec.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { avoidUnhandledPromises } from 'tests/async-utilities';
|
|
2
|
+
import { setupFramepayMock } from 'tests/mocks/rebilly-instruments-mock';
|
|
1
3
|
import RebillyInstruments from './index';
|
|
2
4
|
import { RebillyInstrumentsInstance } from './instance';
|
|
3
|
-
import { avoidUnhandledPromises } from 'tests/async-utilities';
|
|
4
5
|
|
|
5
6
|
describe('RebillyInstruments instance', () => {
|
|
6
7
|
let rebillyInstruments;
|
|
@@ -24,7 +25,8 @@ describe('RebillyInstruments instance', () => {
|
|
|
24
25
|
const options = {
|
|
25
26
|
form: '.form-selector',
|
|
26
27
|
summary: '.summary-selector',
|
|
27
|
-
items: []
|
|
28
|
+
items: [],
|
|
29
|
+
setupFramepay: setupFramepayMock,
|
|
28
30
|
};
|
|
29
31
|
|
|
30
32
|
await rebillyInstruments.mount(options);
|
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) {
|
|
@@ -43,23 +43,25 @@ export class StorefrontInstance {
|
|
|
43
43
|
sandbox: sandboxUrl || 'https://api-sandbox.rebilly.com'
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
-
const
|
|
46
|
+
const config = {
|
|
47
47
|
organizationId,
|
|
48
48
|
sandbox: mode === 'sandbox',
|
|
49
49
|
timeout: Number.isNaN(parseInt(timeout, 10))
|
|
50
50
|
? 10000
|
|
51
51
|
: parseInt(timeout, 10),
|
|
52
52
|
urls
|
|
53
|
-
}
|
|
53
|
+
};
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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);
|
|
58
|
+
|
|
59
|
+
api.setSessionToken(publishableKey || jwt);
|
|
60
|
+
rebilly.setSessionToken(publishableKey || jwt);
|
|
61
61
|
|
|
62
62
|
this.api = api;
|
|
63
|
+
this.api.rebilly = rebilly;
|
|
64
|
+
|
|
63
65
|
return this.api;
|
|
64
66
|
}
|
|
65
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
|
}
|
|
@@ -16,10 +16,10 @@ export async function setupPaymentInstrument({ data, state }) {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
if(state.data.
|
|
19
|
+
if(state.data.amountAndCurrency) {
|
|
20
20
|
setupPayload.data = {
|
|
21
21
|
...setupPayload.data,
|
|
22
|
-
...state.data.
|
|
22
|
+
...state.data.amountAndCurrency
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -33,16 +33,30 @@ export async function fetchReadyToPay({ state, riskMetadata = null }) {
|
|
|
33
33
|
data.currency = money.currency;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const
|
|
37
|
-
|
|
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);
|
|
38
45
|
|
|
39
46
|
return Object.values(readyToPayFields)
|
|
40
47
|
// Remove result for "old" paypal method
|
|
41
48
|
.filter((fields) => !(fields.method === 'paypal' && !fields.feature))
|
|
42
|
-
|
|
49
|
+
// Remove Plaid payment method
|
|
50
|
+
.filter((fields) => !(fields.method === 'ach' && fields.feature))
|
|
51
|
+
.map((fields, index) => {
|
|
52
|
+
const metadata = paymentMethodsMetadata
|
|
53
|
+
.find(methodMetadata => methodMetadata.apiName === fields.method);
|
|
54
|
+
|
|
55
|
+
return new ReadyToPayModel({
|
|
43
56
|
index,
|
|
57
|
+
metadata,
|
|
44
58
|
...fields
|
|
45
|
-
})
|
|
46
|
-
);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
47
61
|
});
|
|
48
62
|
}
|
|
@@ -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);
|