@rebilly/instruments 3.0.0-beta.0 → 3.1.2-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 +88 -107
- package/dist/index.min.js +88 -0
- package/package.json +17 -6
- package/rollup.config.js +84 -0
- package/src/functions/mount/fetch-data.js +13 -1
- package/src/functions/mount/index.js +6 -42
- package/src/functions/mount/setup-framepay-theme.js +2 -2
- package/src/functions/mount/setup-options.js +3 -0
- package/src/functions/mount/setup-user-flow.js +49 -0
- package/src/functions/purchase.js +1 -1
- package/src/functions/setup.js +1 -1
- package/src/functions/show.spec.js +1 -1
- package/src/i18n/en.json +3 -0
- package/src/i18n/index.js +1 -1
- package/src/index.js +1 -61
- package/src/instance.js +65 -0
- package/src/{index.spec.js → instance.spec.js} +2 -1
- package/src/loader/index.js +21 -1
- package/src/storefront/models/ready-to-pay-model.js +13 -2
- package/src/storefront/plans.js +8 -4
- package/src/storefront/plans.spec.js +8 -2
- package/src/storefront/products.js +8 -4
- package/src/storefront/products.spec.js +8 -2
- package/src/storefront/ready-to-pay.js +5 -4
- package/src/style/base/__snapshots__/theme.spec.js.snap +34 -2
- package/src/style/base/default-theme.js +106 -3
- package/src/style/components/button.js +17 -1
- package/src/style/components/forms/label.js +0 -5
- package/src/style/components/loader.js +2 -1
- package/src/style/payment-instruments/payment-card.js +2 -1
- package/src/style/utils/remove-empty-null.js +9 -9
- package/src/style/vendor/postmate.js +13 -0
- package/src/style/views/confirmation.js +2 -1
- package/src/views/common/iframe/base-iframe.js +2 -0
- package/src/views/common/iframe/event-listeners.js +10 -0
- package/src/views/common/iframe/method-iframe.js +3 -1
- package/src/views/confirmation.js +1 -0
- package/src/views/method-selector/express-methods/{google-pay.js → index.js} +3 -2
- package/src/views/method-selector/mount-express-methods.js +6 -18
- package/src/views/result.js +1 -0
- package/tests/mocks/rebilly-instruments-mock.js +2 -2
- package/dist/events/base-event.js +0 -66
- package/dist/events/events.spec.js +0 -18
- package/dist/events/index.js +0 -22
- package/dist/functions/destroy.js +0 -34
- package/dist/functions/destroy.spec.js +0 -69
- package/dist/functions/mount/fetch-data.js +0 -187
- package/dist/functions/mount/fetch-data.spec.js +0 -189
- package/dist/functions/mount/index.js +0 -218
- package/dist/functions/mount/mount.spec.js +0 -64
- package/dist/functions/mount/setup-element.js +0 -40
- package/dist/functions/mount/setup-framepay-theme.js +0 -95
- package/dist/functions/mount/setup-framepay.js +0 -46
- package/dist/functions/mount/setup-i18n.js +0 -33
- package/dist/functions/mount/setup-options.js +0 -99
- package/dist/functions/mount/setup-options.spec.js +0 -66
- package/dist/functions/mount/setup-storefront.js +0 -34
- package/dist/functions/mount/setup-styles.js +0 -43
- package/dist/functions/on.js +0 -40
- package/dist/functions/on.spec.js +0 -55
- package/dist/functions/purchase.js +0 -158
- package/dist/functions/purchase.spec.js +0 -74
- package/dist/functions/setup.js +0 -85
- package/dist/functions/setup.spec.js +0 -87
- package/dist/functions/show.js +0 -55
- package/dist/functions/show.spec.js +0 -61
- package/dist/functions/update.js +0 -74
- package/dist/functions/update.spec.js +0 -86
- package/dist/i18n/en.json +0 -22
- package/dist/i18n/es.json +0 -22
- package/dist/i18n/i18n.spec.js +0 -22
- package/dist/i18n/index.js +0 -72
- package/dist/index.spec.js +0 -35
- package/dist/loader/index.js +0 -94
- package/dist/loader/loader.spec.js +0 -69
- package/dist/storefront/index.js +0 -73
- package/dist/storefront/invoices.js +0 -27
- package/dist/storefront/models/base-model.js +0 -18
- package/dist/storefront/models/invoice-model.js +0 -14
- package/dist/storefront/models/plan-model.js +0 -14
- package/dist/storefront/models/product-model.js +0 -14
- package/dist/storefront/models/ready-to-pay-model.js +0 -46
- package/dist/storefront/models/summary-model.js +0 -79
- package/dist/storefront/models/transaction-model.js +0 -31
- package/dist/storefront/payment-instruments.js +0 -47
- package/dist/storefront/payment-instruments.spec.js +0 -55
- package/dist/storefront/plans.js +0 -37
- package/dist/storefront/plans.spec.js +0 -64
- package/dist/storefront/products.js +0 -40
- package/dist/storefront/products.spec.js +0 -65
- package/dist/storefront/purchase.js +0 -43
- package/dist/storefront/purchase.spec.js +0 -48
- package/dist/storefront/ready-to-pay.js +0 -58
- package/dist/storefront/ready-to-pay.spec.js +0 -69
- package/dist/storefront/storefront.spec.js +0 -15
- package/dist/storefront/summary.js +0 -55
- package/dist/storefront/summary.spec.js +0 -124
- package/dist/storefront/transactions.js +0 -27
- package/dist/style/base/__snapshots__/theme.spec.js.snap +0 -195
- package/dist/style/base/default-theme.js +0 -699
- package/dist/style/base/index.js +0 -104
- package/dist/style/base/theme.js +0 -41
- package/dist/style/base/theme.spec.js +0 -19
- package/dist/style/browserslist.js +0 -8
- package/dist/style/components/address.js +0 -64
- package/dist/style/components/button.js +0 -71
- package/dist/style/components/divider.js +0 -48
- package/dist/style/components/forms/checkbox.js +0 -86
- package/dist/style/components/forms/field.js +0 -65
- package/dist/style/components/forms/form.js +0 -28
- package/dist/style/components/forms/input.js +0 -86
- package/dist/style/components/forms/label.js +0 -69
- package/dist/style/components/forms/select.js +0 -95
- package/dist/style/components/forms/validation.js +0 -81
- package/dist/style/components/icons.js +0 -22
- package/dist/style/components/index.js +0 -57
- package/dist/style/components/loader.js +0 -50
- package/dist/style/components/methods.js +0 -108
- package/dist/style/components/overlay.js +0 -33
- package/dist/style/helpers/index.js +0 -59
- package/dist/style/index.js +0 -50
- package/dist/style/payment-instruments/content.js +0 -17
- package/dist/style/payment-instruments/index.js +0 -20
- package/dist/style/payment-instruments/payment-card.js +0 -35
- package/dist/style/utils/border.js +0 -47
- package/dist/style/utils/color-values.js +0 -58
- package/dist/style/utils/remove-empty-null.js +0 -20
- package/dist/style/vendor/framepay.js +0 -37
- package/dist/style/vendor/postmate.js +0 -17
- package/dist/style/views/confirmation.js +0 -85
- package/dist/style/views/index.js +0 -29
- package/dist/style/views/method-selector.js +0 -20
- package/dist/style/views/modal.js +0 -93
- package/dist/style/views/result.js +0 -61
- package/dist/style/views/summary.js +0 -127
- package/dist/utils/add-dom-element.js +0 -26
- package/dist/utils/format-currency.js +0 -15
- package/dist/utils/has-valid-css-selector.js +0 -11
- package/dist/utils/index.js +0 -55
- package/dist/utils/is-dom-element.js +0 -10
- package/dist/utils/process-property-as-dom-element.js +0 -38
- package/dist/utils/sleep.js +0 -10
- package/dist/views/__snapshots__/summary.spec.js.snap +0 -246
- package/dist/views/common/iframe/base-iframe.js +0 -59
- package/dist/views/common/iframe/event-listeners.js +0 -50
- package/dist/views/common/iframe/index.js +0 -19
- package/dist/views/common/iframe/method-iframe.js +0 -33
- package/dist/views/common/iframe/modal-iframe.js +0 -84
- package/dist/views/common/iframe/view-iframe.js +0 -31
- package/dist/views/common/render-utilities.js +0 -11
- package/dist/views/confirmation.js +0 -92
- package/dist/views/method-selector/__snapshots__/method-selector.spec.js.snap +0 -3
- package/dist/views/method-selector/express-methods/apple-pay.js +0 -92
- package/dist/views/method-selector/express-methods/google-pay.js +0 -31
- package/dist/views/method-selector/express-methods/paypal.js +0 -19
- package/dist/views/method-selector/generate-digital-wallet.js +0 -68
- package/dist/views/method-selector/generate-digital-wallet.spec.js +0 -135
- package/dist/views/method-selector/get-method-data.js +0 -25
- package/dist/views/method-selector/get-payment-methods.js +0 -66
- package/dist/views/method-selector/get-payment-methods.spec.js +0 -46
- package/dist/views/method-selector/index.js +0 -122
- package/dist/views/method-selector/method-selector.spec.js +0 -124
- package/dist/views/method-selector/mount-express-methods.js +0 -69
- package/dist/views/method-selector/mount-methods.js +0 -74
- package/dist/views/modal.js +0 -88
- package/dist/views/result.js +0 -40
- package/dist/views/summary.js +0 -215
- package/dist/views/summary.spec.js +0 -134
- package/src/views/method-selector/express-methods/paypal.js +0 -7
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebilly/instruments",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.2-beta.0",
|
|
4
4
|
"author": "Rebilly",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
|
+
"unpkg": "dist/index.min.js",
|
|
6
7
|
"license": "MIT",
|
|
7
8
|
"scripts": {
|
|
8
|
-
"build": "yarn
|
|
9
|
-
"dev": "yarn
|
|
9
|
+
"build": "yarn rollup -c --environment NODE_ENV:production",
|
|
10
|
+
"dev": "yarn rollup -c --watch --environment NODE_ENV:development",
|
|
10
11
|
"test": "yarn jest",
|
|
11
12
|
"test:watch": "yarn jest --watchAll"
|
|
12
13
|
},
|
|
@@ -22,16 +23,26 @@
|
|
|
22
23
|
"lodash.kebabcase": "^4.1.1",
|
|
23
24
|
"lodash.merge": "^4.6.2",
|
|
24
25
|
"popostmate": "^1.6.4",
|
|
25
|
-
"postcss": "^8.
|
|
26
|
-
"postcss-
|
|
26
|
+
"postcss": "^8.4.5",
|
|
27
|
+
"postcss-css-variables": "^0.18.0",
|
|
27
28
|
"rebilly-js-sdk": "^44.4.0",
|
|
28
29
|
"values.js": "^2.0.0"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
32
|
+
"@rollup/plugin-babel": "^5.1.0",
|
|
33
|
+
"@rollup/plugin-commonjs": "^14.0.0",
|
|
34
|
+
"@rollup/plugin-json": "^4.1.0",
|
|
35
|
+
"@rollup/plugin-node-resolve": "^8.4.0",
|
|
36
|
+
"@rollup/plugin-replace": "^3.0.0",
|
|
31
37
|
"babel-plugin-module-resolver": "^4.1.0",
|
|
32
38
|
"component-emitter": "^1.3.0",
|
|
33
39
|
"jest": "^27.0.6",
|
|
34
40
|
"msw": "^0.23.0",
|
|
35
|
-
"msw-when-then": "^1.4.0"
|
|
41
|
+
"msw-when-then": "^1.4.0",
|
|
42
|
+
"rollup": "^2.35.1",
|
|
43
|
+
"rollup-plugin-ignore": "^1.0.10",
|
|
44
|
+
"rollup-plugin-polyfill-node": "^0.8.0",
|
|
45
|
+
"rollup-plugin-terser": "^7.0.2",
|
|
46
|
+
"rollup-plugin-version-injector": "^1.3.3"
|
|
36
47
|
}
|
|
37
48
|
}
|
package/rollup.config.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import babel from '@rollup/plugin-babel';
|
|
2
|
+
import resolve from '@rollup/plugin-node-resolve';
|
|
3
|
+
import commonjs from '@rollup/plugin-commonjs';
|
|
4
|
+
import json from '@rollup/plugin-json';
|
|
5
|
+
import replace from '@rollup/plugin-replace';
|
|
6
|
+
import nodePolyfills from 'rollup-plugin-polyfill-node';
|
|
7
|
+
import ignore from 'rollup-plugin-ignore';
|
|
8
|
+
import versionInjector from 'rollup-plugin-version-injector';
|
|
9
|
+
import { builtinModules } from 'module'
|
|
10
|
+
import { terser } from 'rollup-plugin-terser';
|
|
11
|
+
|
|
12
|
+
const isDevMode = (process.env.NODE_ENV === 'development');
|
|
13
|
+
|
|
14
|
+
const buildOptions = () => {
|
|
15
|
+
const options = [
|
|
16
|
+
// Locates a module in the project's node_modules
|
|
17
|
+
resolve({
|
|
18
|
+
extensions: [ '.mjs', '.js', '.jsx', '.json' ],
|
|
19
|
+
preferBuiltins: true,
|
|
20
|
+
mainFields: ['browser', 'jsnext:main', 'module', 'main']
|
|
21
|
+
}),
|
|
22
|
+
// Converts CommonJS to ES6 modules
|
|
23
|
+
commonjs(),
|
|
24
|
+
// Fix commonjs issues with virtual node
|
|
25
|
+
// https://github.com/proteriax/rollup-plugin-ignore/issues/3
|
|
26
|
+
// https://github.com/rollup/plugins/issues/248
|
|
27
|
+
// https://github.com/rollup/rollup-plugin-commonjs/issues/315
|
|
28
|
+
ignore(builtinModules, { commonjsBugFix: true }),
|
|
29
|
+
// Replace values at bundle time
|
|
30
|
+
replace({
|
|
31
|
+
preventAssignment: true,
|
|
32
|
+
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
|
|
33
|
+
}),
|
|
34
|
+
// Allows the use of named imports in addition to the default import on node modules
|
|
35
|
+
nodePolyfills(),
|
|
36
|
+
// Babel transpiling
|
|
37
|
+
babel({
|
|
38
|
+
exclude: 'node_modules/**',
|
|
39
|
+
babelHelpers: 'runtime',
|
|
40
|
+
skipPreflightCheck: true
|
|
41
|
+
}),
|
|
42
|
+
// Converts .json files to ES6 modules
|
|
43
|
+
json(),
|
|
44
|
+
]
|
|
45
|
+
if (!isDevMode) {
|
|
46
|
+
options.push(
|
|
47
|
+
// Inject version from package.json (RebillyInstruments.version)
|
|
48
|
+
versionInjector(),
|
|
49
|
+
// Minify and reduce bundle file sizes
|
|
50
|
+
terser())
|
|
51
|
+
}
|
|
52
|
+
return options;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const buildOutput = () => {
|
|
56
|
+
const output = [
|
|
57
|
+
{
|
|
58
|
+
file: 'dist/index.js',
|
|
59
|
+
format: 'es',
|
|
60
|
+
sourcemap: isDevMode ? 'inline' : false,
|
|
61
|
+
},
|
|
62
|
+
]
|
|
63
|
+
if (!isDevMode) {
|
|
64
|
+
output.push(
|
|
65
|
+
{
|
|
66
|
+
file: 'dist/index.min.js',
|
|
67
|
+
format: 'iife',
|
|
68
|
+
name: 'RebillyInstruments',
|
|
69
|
+
exports: 'default'
|
|
70
|
+
},
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
return output;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default {
|
|
77
|
+
input: 'src/index.js',
|
|
78
|
+
output: [
|
|
79
|
+
...buildOutput(),
|
|
80
|
+
],
|
|
81
|
+
plugins: [
|
|
82
|
+
...buildOptions(),
|
|
83
|
+
],
|
|
84
|
+
};
|
|
@@ -83,7 +83,19 @@ export class DataInstance {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
get isShippingRequired() {
|
|
86
|
-
return this.products.some(product => product.requiresShipping);
|
|
86
|
+
return (this.products || []).some(product => product.requiresShipping);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
toPostmatesModel() {
|
|
90
|
+
return {
|
|
91
|
+
...this,
|
|
92
|
+
amountAndCurrency: this.amountAndCurrency,
|
|
93
|
+
isPayment: this.isPayment,
|
|
94
|
+
isPurchase: this.isPurchase,
|
|
95
|
+
summaryItems: this.summaryItems,
|
|
96
|
+
summaryLineItems: this.summaryLineItems,
|
|
97
|
+
isShippingRequired: this.isShippingRequired
|
|
98
|
+
}
|
|
87
99
|
}
|
|
88
100
|
}
|
|
89
101
|
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
import { mountSummary } from '../../views/summary';
|
|
3
3
|
import { mountMethodSelector } from '../../views/method-selector';
|
|
4
4
|
import { fetchData } from './fetch-data';
|
|
5
|
-
import { show } from '../show';
|
|
6
|
-
import { on } from '../on';
|
|
7
5
|
import setupElement from './setup-element';
|
|
8
6
|
import setupStorefront from './setup-storefront';
|
|
9
7
|
import setupOptions from './setup-options';
|
|
@@ -11,6 +9,7 @@ import setupFramepay from './setup-framepay';
|
|
|
11
9
|
import setupStyles from './setup-styles';
|
|
12
10
|
import setupI18n from './setup-i18n';
|
|
13
11
|
import setupFramepayTheme from './setup-framepay-theme';
|
|
12
|
+
import setupUserFlow from './setup-user-flow';
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* @typedef {object} Item
|
|
@@ -81,6 +80,7 @@ export async function mount({
|
|
|
81
80
|
try {
|
|
82
81
|
state.data = {};
|
|
83
82
|
state.options = {};
|
|
83
|
+
|
|
84
84
|
// Setup DOM
|
|
85
85
|
state.form = setupElement({ element: 'form', options });
|
|
86
86
|
state.summary = setupElement({ element: 'summary', options });
|
|
@@ -97,7 +97,8 @@ export async function mount({
|
|
|
97
97
|
state.mainStyle = await setupStyles({ options });
|
|
98
98
|
state.data = await fetchData({ state });
|
|
99
99
|
state.options.themeFramepay = await setupFramepayTheme({ state, options });
|
|
100
|
-
|
|
100
|
+
state.i18n = setupI18n({ state });
|
|
101
|
+
|
|
101
102
|
setupFramepay({ state });
|
|
102
103
|
|
|
103
104
|
if (state.data.transaction && state.data.transaction?.type === 'setup') {
|
|
@@ -111,48 +112,11 @@ export async function mount({
|
|
|
111
112
|
if (state.summary) {
|
|
112
113
|
mountSummary({ state });
|
|
113
114
|
}
|
|
114
|
-
i18n({state});
|
|
115
|
+
state.i18n({state});
|
|
115
116
|
state.hasMounted = true;
|
|
116
117
|
} catch (error) {
|
|
117
118
|
throw error;
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
|
|
121
|
-
on({
|
|
122
|
-
eventName: 'instrument-ready',
|
|
123
|
-
callback: (payload) => {
|
|
124
|
-
show({
|
|
125
|
-
componentName: 'confirmation',
|
|
126
|
-
payload,
|
|
127
|
-
state
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (state.options.features.autoResult) {
|
|
134
|
-
if (state.options.transactionType === 'setup') {
|
|
135
|
-
on({
|
|
136
|
-
eventName: 'setup-completed',
|
|
137
|
-
callback: (payload) => {
|
|
138
|
-
show({
|
|
139
|
-
componentName: 'result',
|
|
140
|
-
payload,
|
|
141
|
-
state
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
} else {
|
|
146
|
-
on({
|
|
147
|
-
eventName: 'purchase-completed',
|
|
148
|
-
callback: (payload) => {
|
|
149
|
-
show({
|
|
150
|
-
componentName: 'result',
|
|
151
|
-
payload,
|
|
152
|
-
state
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
}
|
|
121
|
+
setupUserFlow({state});
|
|
158
122
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import css from 'css';
|
|
2
2
|
import postcss from 'postcss';
|
|
3
|
-
import
|
|
3
|
+
import cssvariables from 'postcss-css-variables';
|
|
4
4
|
import camelCase from 'lodash.camelcase';
|
|
5
5
|
|
|
6
6
|
const resolveCssVars = async (rawCss) => postcss([
|
|
7
|
-
|
|
7
|
+
cssvariables({ preserve: false })
|
|
8
8
|
])
|
|
9
9
|
.process(rawCss, { from: undefined })
|
|
10
10
|
.then(output => output.css);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { on } from '../on';
|
|
2
|
+
import { show } from '../show';
|
|
3
|
+
import { purchase } from '../purchase';
|
|
4
|
+
import { setup } from '../setup';
|
|
5
|
+
|
|
6
|
+
function showResult({state, payload}) {
|
|
7
|
+
show({
|
|
8
|
+
componentName: 'result',
|
|
9
|
+
payload,
|
|
10
|
+
state
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default ({state = {}}) => {
|
|
15
|
+
if (state.options.features.autoConfirmation) {
|
|
16
|
+
on({
|
|
17
|
+
eventName: 'instrument-ready',
|
|
18
|
+
callback: (payload) => {
|
|
19
|
+
// Alternate flow for paypal.
|
|
20
|
+
if (payload._raw?.method === 'paypal') {
|
|
21
|
+
if (!state.data.isShippingRequired) {
|
|
22
|
+
if (state.options.transactionType === 'setup') {
|
|
23
|
+
setup({state, payload});
|
|
24
|
+
} else {
|
|
25
|
+
purchase({state, payload});
|
|
26
|
+
}
|
|
27
|
+
state.loader.startLoading({state, id: 'express-purchase', message: 'form.loaderMessages.processingPayment' });
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
show({
|
|
32
|
+
componentName: 'confirmation',
|
|
33
|
+
payload,
|
|
34
|
+
state
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (state.options.features.autoResult) {
|
|
41
|
+
on({
|
|
42
|
+
eventName: state.options.transactionType === 'setup' ?
|
|
43
|
+
'setup-completed' : 'purchase-completed',
|
|
44
|
+
callback: (payload) => {
|
|
45
|
+
showResult({state, payload});
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -93,7 +93,7 @@ export async function purchase({ state, payload }) {
|
|
|
93
93
|
fields = await makePurchase({ state, payload });
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
if (fields.transaction?.approvalUrl) {
|
|
96
|
+
if (fields.transaction?.approvalUrl && fields.transaction?.result === 'unknown') {
|
|
97
97
|
handleApprovalUrl({state, fields});
|
|
98
98
|
} else {
|
|
99
99
|
Events.purchaseCompleted.dispatch(fields);
|
package/src/functions/setup.js
CHANGED
|
@@ -16,7 +16,7 @@ export async function setup({ state, payload }) {
|
|
|
16
16
|
|
|
17
17
|
state.data = new DataInstance({state, instrument, transaction});
|
|
18
18
|
|
|
19
|
-
if (transaction.approvalUrl) {
|
|
19
|
+
if (transaction.approvalUrl && transaction.result === 'unknown') {
|
|
20
20
|
const { paymentMethodsUrl } = state.options._computed;
|
|
21
21
|
mountModal({
|
|
22
22
|
state,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as result from '@/views/result';
|
|
2
2
|
import * as confirmation from '@/views/confirmation';
|
|
3
3
|
import { RenderMockRebillyInstruments } from 'tests/mocks/rebilly-instruments-mock';
|
|
4
|
-
import { RebillyInstrumentsInstance } from '../
|
|
4
|
+
import { RebillyInstrumentsInstance } from '../instance';
|
|
5
5
|
|
|
6
6
|
const iframeMock = { destroy: jest.fn() };
|
|
7
7
|
|
package/src/i18n/en.json
CHANGED
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
"popupOverlayText": "Click here to show popup window",
|
|
14
14
|
"error": {
|
|
15
15
|
"noPaymentMethods": "No payment methods available for this transaction, please contact support."
|
|
16
|
+
},
|
|
17
|
+
"loaderMessages": {
|
|
18
|
+
"processingPayment": "Processing payment instrument."
|
|
16
19
|
}
|
|
17
20
|
},
|
|
18
21
|
"paymentMethods": {
|
package/src/i18n/index.js
CHANGED
|
@@ -12,7 +12,7 @@ export class Translate {
|
|
|
12
12
|
init(locale, messages) {
|
|
13
13
|
this.items = document.querySelectorAll('[data-rebilly-i18n]');
|
|
14
14
|
this.locale = this.getLocale(locale);
|
|
15
|
-
this.languages = merge({ ...en, ...es }, messages);
|
|
15
|
+
this.languages = merge({}, { ...en, ...es }, messages);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
translateItems() {
|
package/src/index.js
CHANGED
|
@@ -1,63 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { purchase } from './functions/purchase';
|
|
3
|
-
import { setup } from './functions/setup';
|
|
4
|
-
import { on } from './functions/on';
|
|
5
|
-
import { update } from './functions/update';
|
|
6
|
-
import { destroy } from './functions/destroy';
|
|
7
|
-
import { Loader } from './loader';
|
|
8
|
-
import { Translate } from './i18n';
|
|
9
|
-
import { show } from './functions/show';
|
|
10
|
-
|
|
11
|
-
export class InstrumentsState {
|
|
12
|
-
constructor() {
|
|
13
|
-
this.options = null;
|
|
14
|
-
this.data = {};
|
|
15
|
-
this.mountingPoints = null;
|
|
16
|
-
this.storefront = null;
|
|
17
|
-
this.form = null;
|
|
18
|
-
this.summary = null;
|
|
19
|
-
this.loader = new Loader();
|
|
20
|
-
this.translate = new Translate();
|
|
21
|
-
this.iframeComponents = [];
|
|
22
|
-
this.hasMounted = false;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export class RebillyInstrumentsInstance {
|
|
27
|
-
constructor() {
|
|
28
|
-
this.state = new InstrumentsState();
|
|
29
|
-
// TODO: mountConfirmation, mountResult have different contract shape when they look similar
|
|
30
|
-
// TODO: review test coverage of UpdateSummary and UpdateMethodSelector as no tests were broken
|
|
31
|
-
// when commenting them
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async mount(options) {
|
|
35
|
-
await mount({ state: this.state, ...options });
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async destroy() {
|
|
39
|
-
await destroy({ state: this.state });
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async update(newOptions) {
|
|
43
|
-
await update({state: this.state, newOptions});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async purchase(payload) {
|
|
47
|
-
await purchase({ state: this.state, payload });
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async setup(payload) {
|
|
51
|
-
await setup({ state: this.state, payload });
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async show(componentName, payload) {
|
|
55
|
-
await show({ state: this.state, componentName, payload });
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
on(eventName, callback) {
|
|
59
|
-
on({ state: this.state, eventName, callback });
|
|
60
|
-
}
|
|
61
|
-
}
|
|
1
|
+
import { RebillyInstrumentsInstance } from './instance';
|
|
62
2
|
|
|
63
3
|
export default new RebillyInstrumentsInstance();
|
package/src/instance.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { mount } from './functions/mount';
|
|
2
|
+
import { purchase } from './functions/purchase';
|
|
3
|
+
import { setup } from './functions/setup';
|
|
4
|
+
import { on } from './functions/on';
|
|
5
|
+
import { update } from './functions/update';
|
|
6
|
+
import { destroy } from './functions/destroy';
|
|
7
|
+
import { Loader } from './loader';
|
|
8
|
+
import { Translate } from './i18n';
|
|
9
|
+
import { show } from './functions/show';
|
|
10
|
+
|
|
11
|
+
export class InstrumentsState {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.options = null;
|
|
14
|
+
this.data = {};
|
|
15
|
+
this.mountingPoints = null;
|
|
16
|
+
this.storefront = null;
|
|
17
|
+
this.form = null;
|
|
18
|
+
this.summary = null;
|
|
19
|
+
this.loader = new Loader();
|
|
20
|
+
this.translate = new Translate();
|
|
21
|
+
this.iframeComponents = [];
|
|
22
|
+
this.hasMounted = false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class RebillyInstrumentsInstance {
|
|
27
|
+
constructor() {
|
|
28
|
+
this.state = new InstrumentsState();
|
|
29
|
+
// TODO: mountConfirmation, mountResult have different contract shape when they look similar
|
|
30
|
+
// TODO: review test coverage of UpdateSummary and UpdateMethodSelector as no tests were broken
|
|
31
|
+
// when commenting them
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async mount(options) {
|
|
35
|
+
await mount({ state: this.state, ...options });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async destroy() {
|
|
39
|
+
await destroy({ state: this.state });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async update(newOptions) {
|
|
43
|
+
await update({state: this.state, newOptions});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async purchase(payload) {
|
|
47
|
+
await purchase({ state: this.state, payload });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async setup(payload) {
|
|
51
|
+
await setup({ state: this.state, payload });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async show(componentName, payload) {
|
|
55
|
+
await show({ state: this.state, componentName, payload });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get version() {
|
|
59
|
+
return 'RebillyInstruments Ver.[VI]{version}[/VI]';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
on(eventName, callback) {
|
|
63
|
+
on({ state: this.state, eventName, callback });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import RebillyInstruments
|
|
1
|
+
import RebillyInstruments from './index';
|
|
2
|
+
import { RebillyInstrumentsInstance } from './instance';
|
|
2
3
|
import { avoidUnhandledPromises } from 'tests/async-utilities';
|
|
3
4
|
|
|
4
5
|
describe('RebillyInstruments instance', () => {
|
package/src/loader/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export class Loader {
|
|
|
9
9
|
loading: `
|
|
10
10
|
<div class="rebilly-instruments-loader is-active">
|
|
11
11
|
<div class="rebilly-instruments-loader-spinner"></div>
|
|
12
|
+
<span class="rebilly-instuments-loader-message"><span>
|
|
12
13
|
</div>
|
|
13
14
|
`
|
|
14
15
|
};
|
|
@@ -22,7 +23,7 @@ export class Loader {
|
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
startLoading({ section = 'form', id = '' } = {}) {
|
|
26
|
+
startLoading({state, section = 'form', id = '', message = null } = {}) {
|
|
26
27
|
const minHeight = '200px';
|
|
27
28
|
this[section].push(id);
|
|
28
29
|
|
|
@@ -36,6 +37,17 @@ export class Loader {
|
|
|
36
37
|
}
|
|
37
38
|
this.DOM[section].style.minHeight = minHeight;
|
|
38
39
|
}
|
|
40
|
+
|
|
41
|
+
if (message) {
|
|
42
|
+
const loaderMessage = this.DOM[section].querySelector('.rebilly-instuments-loader-message');
|
|
43
|
+
if (loaderMessage) {
|
|
44
|
+
loaderMessage.innerHTML = message;
|
|
45
|
+
loaderMessage.style.marginTop = '10px';
|
|
46
|
+
loaderMessage.setAttribute('data-message-id', id);
|
|
47
|
+
loaderMessage.setAttribute('data-rebilly-i18n', message);
|
|
48
|
+
state.i18n({state});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
stopLoading({ section = 'form', id = '' } = {}) {
|
|
@@ -54,6 +66,14 @@ export class Loader {
|
|
|
54
66
|
.classList.remove('is-active');
|
|
55
67
|
this.DOM[section].style.minHeight = '';
|
|
56
68
|
}
|
|
69
|
+
|
|
70
|
+
const loaderMessage = this.DOM[section].querySelector(`.rebilly-instuments-loader-message[data-message-id="${id}"]`);
|
|
71
|
+
if (loaderMessage) {
|
|
72
|
+
loaderMessage.innerHTML = null;
|
|
73
|
+
loaderMessage.style.marginTop = '0px';
|
|
74
|
+
loaderMessage.removeAttribute('data-message-id');
|
|
75
|
+
loaderMessage.removeAttribute('data-rebilly-i18n');
|
|
76
|
+
}
|
|
57
77
|
}
|
|
58
78
|
|
|
59
79
|
clearAll() {
|
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
export class ReadyToPayFeatureModel {
|
|
2
2
|
constructor({
|
|
3
3
|
name = '',
|
|
4
|
+
expirationTime = '',
|
|
5
|
+
|
|
4
6
|
// Google Pay fields
|
|
5
7
|
merchantName = '',
|
|
6
8
|
merchantOrigin = '',
|
|
9
|
+
|
|
10
|
+
// Paypal fields
|
|
11
|
+
paypalMerchantId = '',
|
|
12
|
+
billingAgreementToken = '',
|
|
13
|
+
|
|
7
14
|
// Plaid fields
|
|
8
15
|
linkToken = '',
|
|
9
|
-
expirationTime = ''
|
|
10
16
|
} = {}) {
|
|
11
17
|
this.name = name;
|
|
18
|
+
this.expirationTime = expirationTime;
|
|
19
|
+
|
|
12
20
|
this.merchantName = merchantName;
|
|
13
21
|
this.merchantOrigin = merchantOrigin;
|
|
22
|
+
|
|
23
|
+
this.paypalMerchantId = paypalMerchantId;
|
|
24
|
+
this.billingAgreementToken = billingAgreementToken;
|
|
25
|
+
|
|
14
26
|
this.linkToken = linkToken;
|
|
15
|
-
this.expirationTime = expirationTime;
|
|
16
27
|
}
|
|
17
28
|
}
|
|
18
29
|
|
package/src/storefront/plans.js
CHANGED
|
@@ -15,9 +15,13 @@ export async function fetchPlans({ state = {}, data = {} }) {
|
|
|
15
15
|
.join(',')}`;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
// Only fetch plans if we hae specific plans to fetch
|
|
19
|
+
if (filterByPlanId.filter.length) {
|
|
20
|
+
const { items: planItems } = await state.storefront.plans.getAll(
|
|
21
|
+
filterByPlanId
|
|
22
|
+
);
|
|
23
|
+
return planItems.map(({ fields }) => new PlanModel(fields));
|
|
24
|
+
}
|
|
25
|
+
return [];
|
|
22
26
|
});
|
|
23
27
|
}
|
|
@@ -16,11 +16,17 @@ describe('Storefront API Plan', () => {
|
|
|
16
16
|
|
|
17
17
|
jest.spyOn(instance.storefront.plans, 'getAll');
|
|
18
18
|
|
|
19
|
-
const response = await fetchPlans({ state: instance
|
|
19
|
+
const response = await fetchPlans({ state: instance, data: {
|
|
20
|
+
lineItems: [
|
|
21
|
+
{
|
|
22
|
+
planId: 'test-plan-id'
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
} });
|
|
20
26
|
|
|
21
27
|
expect(instance.storefront.plans.getAll).toBeCalledTimes(1);
|
|
22
28
|
expect(instance.storefront.plans.getAll).toBeCalledWith({
|
|
23
|
-
filter: ''
|
|
29
|
+
filter: 'id:test-plan-id'
|
|
24
30
|
});
|
|
25
31
|
expect(response).toBeInstanceOf(Array);
|
|
26
32
|
expect(response[0]).toBeInstanceOf(PlanModel);
|
|
@@ -18,9 +18,13 @@ export async function fetchProducts({ state }) {
|
|
|
18
18
|
.join(',')}`;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
// Only fetch products if we hae specific products to fetch
|
|
22
|
+
if (filterByProductId.filter.length) {
|
|
23
|
+
const { items: productItems } = await state.storefront.products.getAll(
|
|
24
|
+
filterByProductId
|
|
25
|
+
);
|
|
26
|
+
return productItems.map(({ fields }) => new ProductModel(fields));
|
|
27
|
+
}
|
|
28
|
+
return [];
|
|
25
29
|
});
|
|
26
30
|
}
|
|
@@ -12,7 +12,13 @@ describe('Storefront API Plan', () => {
|
|
|
12
12
|
|
|
13
13
|
when(get(`${storefrontURL}/products`)).thenReturn(ok([testProduct]));
|
|
14
14
|
|
|
15
|
-
const instance = new StorefontTestingInstance(
|
|
15
|
+
const instance = new StorefontTestingInstance({
|
|
16
|
+
data: {
|
|
17
|
+
plans: [{
|
|
18
|
+
productId: 'test-product-id'
|
|
19
|
+
}
|
|
20
|
+
]}
|
|
21
|
+
});
|
|
16
22
|
|
|
17
23
|
jest.spyOn(instance.storefront.products, 'getAll');
|
|
18
24
|
|
|
@@ -20,7 +26,7 @@ describe('Storefront API Plan', () => {
|
|
|
20
26
|
|
|
21
27
|
expect(instance.storefront.products.getAll).toBeCalledTimes(1);
|
|
22
28
|
expect(instance.storefront.products.getAll).toBeCalledWith({
|
|
23
|
-
filter: ''
|
|
29
|
+
filter: 'id:test-product-id'
|
|
24
30
|
});
|
|
25
31
|
expect(response).toBeInstanceOf(Array);
|
|
26
32
|
expect(response[0]).toBeInstanceOf(ProductModel);
|