@rebilly/instruments 2.0.0-beta → 3.0.1-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/events/index.js +2 -1
- package/dist/functions/mount/fetch-data.js +187 -0
- package/dist/functions/mount/fetch-data.spec.js +189 -0
- package/dist/functions/mount/index.js +132 -164
- package/dist/functions/mount/mount.spec.js +2 -4
- package/dist/functions/mount/setup-element.js +40 -0
- package/dist/functions/mount/setup-framepay-theme.js +95 -0
- package/dist/functions/mount/setup-framepay.js +5 -1
- package/dist/functions/mount/setup-i18n.js +33 -0
- package/dist/functions/mount/setup-options.js +68 -47
- package/dist/functions/mount/setup-options.spec.js +66 -0
- package/dist/functions/mount/setup-storefront.js +6 -4
- package/dist/functions/mount/setup-styles.js +4 -2
- package/dist/functions/purchase.js +129 -24
- package/dist/functions/purchase.spec.js +13 -10
- package/dist/functions/setup.js +85 -0
- package/dist/functions/setup.spec.js +87 -0
- package/dist/functions/show.js +8 -4
- package/dist/functions/show.spec.js +9 -5
- package/dist/functions/update.js +39 -24
- package/dist/functions/update.spec.js +0 -4
- package/dist/i18n/en.json +5 -2
- package/dist/i18n/es.json +4 -1
- package/dist/index.js +17 -3
- package/dist/index.spec.js +3 -16
- package/dist/loader/index.js +4 -3
- package/dist/storefront/index.js +33 -0
- package/dist/storefront/invoices.js +27 -0
- package/dist/storefront/models/base-model.js +18 -0
- package/dist/storefront/models/invoice-model.js +14 -0
- package/dist/storefront/models/plan-model.js +4 -35
- package/dist/storefront/models/product-model.js +4 -23
- package/dist/storefront/models/summary-model.js +12 -25
- package/dist/storefront/models/transaction-model.js +31 -0
- package/dist/storefront/payment-instruments.js +47 -0
- package/dist/storefront/payment-instruments.spec.js +55 -0
- package/dist/storefront/plans.js +10 -18
- package/dist/storefront/plans.spec.js +3 -13
- package/dist/storefront/products.js +10 -13
- package/dist/storefront/products.spec.js +12 -19
- package/dist/storefront/purchase.js +23 -12
- package/dist/storefront/purchase.spec.js +1 -20
- package/dist/storefront/ready-to-pay.js +18 -15
- package/dist/storefront/ready-to-pay.spec.js +2 -12
- package/dist/storefront/summary.js +21 -17
- package/dist/storefront/summary.spec.js +4 -15
- package/dist/storefront/transactions.js +27 -0
- package/dist/style/base/__snapshots__/theme.spec.js.snap +188 -45
- package/dist/style/base/default-theme.js +699 -0
- package/dist/style/base/index.js +48 -16
- package/dist/style/base/theme.js +16 -48
- package/dist/style/base/theme.spec.js +4 -15
- package/dist/style/components/address.js +3 -3
- package/dist/style/components/button.js +32 -22
- package/dist/style/components/divider.js +9 -9
- package/dist/style/components/forms/checkbox.js +12 -9
- package/dist/style/components/forms/field.js +18 -6
- package/dist/style/components/forms/form.js +2 -2
- package/dist/style/components/forms/input.js +54 -13
- package/dist/style/components/forms/label.js +39 -18
- package/dist/style/components/forms/select.js +54 -22
- package/dist/style/components/forms/validation.js +53 -6
- package/dist/style/components/icons.js +4 -4
- package/dist/style/components/loader.js +5 -3
- package/dist/style/components/methods.js +18 -15
- package/dist/style/components/overlay.js +5 -5
- package/dist/style/helpers/index.js +46 -46
- package/dist/style/index.js +3 -1
- package/dist/style/payment-instruments/payment-card.js +4 -4
- package/dist/style/utils/border.js +47 -0
- package/dist/style/utils/color-values.js +39 -3
- package/dist/style/utils/remove-empty-null.js +20 -0
- package/dist/style/vendor/framepay.js +11 -8
- package/dist/style/vendor/postmate.js +2 -2
- package/dist/style/views/confirmation.js +13 -13
- package/dist/style/views/method-selector.js +2 -2
- package/dist/style/views/modal.js +6 -6
- package/dist/style/views/result.js +4 -4
- package/dist/style/views/summary.js +26 -22
- package/dist/views/__snapshots__/summary.spec.js.snap +77 -119
- package/dist/views/common/iframe/base-iframe.js +2 -0
- package/dist/views/common/iframe/modal-iframe.js +50 -4
- package/dist/views/confirmation.js +19 -8
- package/dist/views/method-selector/generate-digital-wallet.js +12 -3
- package/dist/views/method-selector/generate-digital-wallet.spec.js +11 -0
- package/dist/views/method-selector/get-payment-methods.js +13 -2
- package/dist/views/method-selector/get-payment-methods.spec.js +21 -19
- package/dist/views/method-selector/index.js +23 -34
- package/dist/views/method-selector/method-selector.spec.js +50 -55
- package/dist/views/method-selector/mount-methods.js +5 -8
- package/dist/views/modal.js +8 -2
- package/dist/views/result.js +3 -4
- package/dist/views/summary.js +156 -97
- package/dist/views/summary.spec.js +53 -58
- package/package.json +4 -2
- package/src/events/index.js +2 -1
- package/src/functions/mount/fetch-data.js +152 -0
- package/src/functions/mount/fetch-data.spec.js +238 -0
- package/src/functions/mount/index.js +101 -158
- package/src/functions/mount/mount.spec.js +3 -5
- package/src/functions/mount/setup-element.js +26 -0
- package/src/functions/mount/setup-framepay-theme.js +82 -0
- package/src/functions/mount/setup-framepay.js +5 -1
- package/src/functions/mount/setup-i18n.js +19 -0
- package/src/functions/mount/setup-options.js +78 -48
- package/src/functions/mount/setup-options.spec.js +60 -0
- package/src/functions/mount/setup-storefront.js +6 -4
- package/src/functions/mount/setup-styles.js +4 -2
- package/src/functions/on.spec.js +1 -1
- package/src/functions/purchase.js +99 -23
- package/src/functions/purchase.spec.js +10 -10
- package/src/functions/setup.js +48 -0
- package/src/functions/setup.spec.js +98 -0
- package/src/functions/show.js +2 -4
- package/src/functions/show.spec.js +3 -4
- package/src/functions/update.js +40 -25
- package/src/functions/update.spec.js +0 -4
- package/src/i18n/en.json +5 -2
- package/src/i18n/es.json +4 -1
- package/src/index.js +9 -3
- package/src/index.spec.js +3 -21
- package/src/loader/index.js +3 -3
- package/src/storefront/index.js +28 -0
- package/src/storefront/invoices.js +11 -0
- package/src/storefront/models/base-model.js +10 -0
- package/src/storefront/models/invoice-model.js +3 -0
- package/src/storefront/models/plan-model.js +3 -35
- package/src/storefront/models/product-model.js +3 -23
- package/src/storefront/models/summary-model.js +12 -19
- package/src/storefront/models/transaction-model.js +19 -0
- package/src/storefront/payment-instruments.js +30 -0
- package/src/storefront/payment-instruments.spec.js +69 -0
- package/src/storefront/plans.js +6 -17
- package/src/storefront/plans.spec.js +4 -11
- package/src/storefront/products.js +8 -16
- package/src/storefront/products.spec.js +16 -22
- package/src/storefront/purchase.js +14 -16
- package/src/storefront/purchase.spec.js +2 -14
- package/src/storefront/ready-to-pay.js +13 -16
- package/src/storefront/ready-to-pay.spec.js +3 -10
- package/src/storefront/summary.js +19 -17
- package/src/storefront/summary.spec.js +5 -12
- package/src/storefront/transactions.js +11 -0
- package/src/style/base/__snapshots__/theme.spec.js.snap +188 -45
- package/src/style/base/default-theme.js +674 -0
- package/src/style/base/index.js +48 -16
- package/src/style/base/theme.js +17 -47
- package/src/style/base/theme.spec.js +4 -16
- package/src/style/components/address.js +3 -3
- package/src/style/components/button.js +32 -24
- package/src/style/components/divider.js +9 -9
- package/src/style/components/forms/checkbox.js +11 -11
- package/src/style/components/forms/field.js +18 -6
- package/src/style/components/forms/form.js +2 -2
- package/src/style/components/forms/input.js +54 -13
- package/src/style/components/forms/label.js +39 -18
- package/src/style/components/forms/select.js +54 -22
- package/src/style/components/forms/validation.js +53 -6
- package/src/style/components/icons.js +4 -4
- package/src/style/components/loader.js +4 -5
- package/src/style/components/methods.js +18 -15
- package/src/style/components/overlay.js +5 -5
- package/src/style/helpers/index.js +46 -46
- package/src/style/index.js +2 -1
- package/src/style/payment-instruments/payment-card.js +4 -4
- package/src/style/utils/border.js +34 -0
- package/src/style/utils/color-values.js +27 -1
- package/src/style/utils/remove-empty-null.js +10 -0
- package/src/style/vendor/framepay.js +11 -8
- package/src/style/vendor/postmate.js +2 -2
- package/src/style/views/confirmation.js +13 -13
- package/src/style/views/method-selector.js +2 -2
- package/src/style/views/modal.js +6 -6
- package/src/style/views/result.js +4 -4
- package/src/style/views/summary.js +26 -22
- package/src/views/__snapshots__/summary.spec.js.snap +77 -119
- package/src/views/common/iframe/base-iframe.js +2 -0
- package/src/views/common/iframe/modal-iframe.js +45 -3
- package/src/views/confirmation.js +15 -5
- package/src/views/method-selector/generate-digital-wallet.js +10 -3
- package/src/views/method-selector/generate-digital-wallet.spec.js +10 -0
- package/src/views/method-selector/get-payment-methods.js +7 -2
- package/src/views/method-selector/get-payment-methods.spec.js +26 -23
- package/src/views/method-selector/index.js +21 -28
- package/src/views/method-selector/method-selector.spec.js +49 -64
- package/src/views/method-selector/mount-methods.js +5 -8
- package/src/views/modal.js +6 -2
- package/src/views/result.js +4 -3
- package/src/views/summary.js +161 -117
- package/src/views/summary.spec.js +60 -75
- package/tests/mocks/rebilly-instruments-mock.js +37 -7
- package/tests/mocks/storefront-api-mock.js +8 -0
- package/tests/mocks/storefront-mock.js +17 -0
- package/dist/functions/mount/fetch-summary-data.js +0 -46
- package/dist/functions/mount/fetch-summary-data.spec.js +0 -43
- package/src/functions/mount/fetch-summary-data.js +0 -29
- package/src/functions/mount/fetch-summary-data.spec.js +0 -40
|
@@ -1,196 +1,129 @@
|
|
|
1
1
|
/* eslint-disable max-len */
|
|
2
|
-
import { collectData } from '@rebilly/risk-data-collector';
|
|
3
2
|
import { mountSummary } from '../../views/summary';
|
|
4
3
|
import { mountMethodSelector } from '../../views/method-selector';
|
|
5
|
-
import {
|
|
6
|
-
import { fetchSummaryData } from './fetch-summary-data';
|
|
4
|
+
import { fetchData } from './fetch-data';
|
|
7
5
|
import { show } from '../show';
|
|
8
6
|
import { on } from '../on';
|
|
7
|
+
import setupElement from './setup-element';
|
|
9
8
|
import setupStorefront from './setup-storefront';
|
|
10
9
|
import setupOptions from './setup-options';
|
|
11
10
|
import setupFramepay from './setup-framepay';
|
|
12
11
|
import setupStyles from './setup-styles';
|
|
12
|
+
import setupI18n from './setup-i18n';
|
|
13
|
+
import setupFramepayTheme from './setup-framepay-theme';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* @typedef {object} Item
|
|
16
17
|
* @property {string} planId - The Rebilly id of the plan.
|
|
17
18
|
* @property {number} quantity - The number of the plans to be purchased.
|
|
18
19
|
* @property {string} thumbnail - The source img for the product. Recommend 100px by 100px.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* @
|
|
23
|
-
* @property {
|
|
24
|
-
*
|
|
25
|
-
* @
|
|
26
|
-
* @property {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
* @typedef {
|
|
31
|
-
* @
|
|
32
|
-
*
|
|
33
|
-
* @param {string} buttonHeight - The value and units of the button to match other payment buttons
|
|
34
|
-
* <br>example: "44px", "1rem" etc.
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
/**
|
|
20
|
+
*
|
|
21
|
+
* @typedef {object} GooglePayDisplayOptions
|
|
22
|
+
* @property {"back" | "white"} [buttonColor=black] - Color of google pay button
|
|
23
|
+
* @property {"short" | "long"} [buttonType=short] - The length of the button
|
|
24
|
+
* @property {string} [buttonHeight=44px] - The value and units of the button to match other payment buttons
|
|
25
|
+
*
|
|
26
|
+
* @typedef {object} ApplePayDisplayOptions
|
|
27
|
+
* @property {"back" | "white"} [buttonColor=black] - Color of apple pay button
|
|
28
|
+
* @property {"short" | "long"} [buttonType=short] - The length of the button
|
|
29
|
+
* @property {string} [buttonHeight=44px] - The value and units of the button to match other payment buttons
|
|
30
|
+
*
|
|
31
|
+
* @typedef {object} ApplePayMerchantOptions
|
|
32
|
+
* @property {string} merchantName - The name of the merchant store.
|
|
33
|
+
*
|
|
38
34
|
* @typedef {object} GooglePay
|
|
39
|
-
* @
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
* @property {GooglePayDisplayOptions} displayOptions - display options for google pay instrument
|
|
36
|
+
*
|
|
37
|
+
* @typedef {object} ApplePay
|
|
38
|
+
* @property {ApplePayDisplayOptions} displayOptions - display options for apple pay instrument
|
|
39
|
+
* @property {ApplePayMerchantOptions} merchantOptions - merchant options for apple pay instrument
|
|
40
|
+
*
|
|
43
41
|
* @typedef {object} PaymentCard
|
|
44
|
-
* @
|
|
45
|
-
*
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
/**
|
|
42
|
+
* @property {boolean} [popup=true] - Show method as a button with a form popup. Otherwise the form will be mounted inline.
|
|
43
|
+
*
|
|
49
44
|
* @typedef {object} Address
|
|
50
|
-
* @
|
|
51
|
-
* @
|
|
52
|
-
* @
|
|
53
|
-
* @
|
|
54
|
-
* @
|
|
55
|
-
*
|
|
56
|
-
* <br>First name and last name are always required. Country is always required if the products require shipping.
|
|
57
|
-
*/
|
|
58
|
-
|
|
59
|
-
/**
|
|
45
|
+
* @property {string} [name=default] - One of default, combined, or stacked.
|
|
46
|
+
* @property {string} [region=default] - One of default, split, or stacked.
|
|
47
|
+
* @property {Array.<"organization" | "phoneNumber">} show - Show extra fields listed.
|
|
48
|
+
* @property {Array.<"address" | "address2" | "email | "country" | "region" | "postalCode"">} hide - Hide the listed fields.
|
|
49
|
+
* @property {Array.<"organization" | "address" | "address2" | "email" | "phoneNumber" | "country" | "region" | "postalCode">} require - Require the listed fields.
|
|
50
|
+
*
|
|
60
51
|
* @typedef {object} PaymentInstruments
|
|
61
|
-
* @
|
|
62
|
-
*
|
|
63
|
-
* @
|
|
64
|
-
* @
|
|
65
|
-
* @
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
/**
|
|
52
|
+
* @property {boolean} [compactExpressInstruments=true] - Show express methods as inline pill buttons, or list of full width button.
|
|
53
|
+
* @property {PaymentCard} paymentCard - settings for payment card instruments
|
|
54
|
+
* @property {GooglePay} googlePay - settings for google pay instruments
|
|
55
|
+
* @property {ApplePay} applePay - settings for apple pay instruments
|
|
56
|
+
* @property {Address} address - customization for address components for all payment instruments.
|
|
57
|
+
*
|
|
69
58
|
* @typedef {object} Features
|
|
70
|
-
* @
|
|
71
|
-
*
|
|
72
|
-
* <br>Can use RebillyInstruments.show('confirmation', options) to mount defautl component
|
|
73
|
-
* @param {boolean} autoResult - default: true. Show results of transaction after `purchase-completed` event is triggered
|
|
74
|
-
* <br>Will need to handle purchase result manually if set to false.
|
|
75
|
-
* <br>Can use RebillyInstruments.show('result', options) to display default component
|
|
76
|
-
*/
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* @typedef {object} Options
|
|
80
|
-
* @property {Intent} intent - The information required for purchaseing or vaulting an instrument
|
|
81
|
-
* @property {PaymentInstruments} paymentInstruments - settings for various payment instruments
|
|
82
|
-
* @property {Features} features - flags to enable and disable different features
|
|
83
|
-
* @property {string} locale - default: auto. Language to render component text
|
|
84
|
-
*/
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Mount library with configurations.
|
|
88
|
-
* @typedef {object} MountParams
|
|
89
|
-
* @property {Object} state - Global state
|
|
90
|
-
* @property {string | HTMLElement} form - The CSS class or HTML element were the form will be mounted.
|
|
91
|
-
* @property {string | HTMLElement} form - The CSS class or HTML element were the form will be mounted.
|
|
92
|
-
* @property {string | HTMLElement} summary - The CSS class or HTML element were the summary will be mounted.
|
|
93
|
-
* @property {Options} options - The configurations that are to be passed to the library for use.
|
|
59
|
+
* @property {boolean} [autoConfirmation=true] - Will mount the confirmation screen after `instrument-ready` event is triggered.
|
|
60
|
+
* @property {boolean} [autoResult=true] - Show results of transaction after `purchase-completed` event is triggered
|
|
94
61
|
*/
|
|
95
62
|
|
|
96
63
|
/**
|
|
97
64
|
* Mount library with configurations.
|
|
98
|
-
* @param {
|
|
65
|
+
* @param {object} options - The options object
|
|
66
|
+
* @param {object} options.state - Global state
|
|
67
|
+
* @param {string | HTMLElement} options.form - The CSS class or HTML element were the form will be mounted.
|
|
68
|
+
* @param {string | HTMLElement} options.summary - The CSS class or HTML element were the summary will be mounted.
|
|
69
|
+
* @param {Item[]} options.items - Which plans the customer is purchasing.
|
|
70
|
+
* @param {string} options.invoiceId - The Rebilly id of the invoice used for purchasing.
|
|
71
|
+
* @param {string} options.customerJwt - The customer token to access the invoice.
|
|
72
|
+
* @param {string} [options.countryCode=USD] - The country code for the transaction
|
|
73
|
+
* @param {PaymentInstruments} options.paymentInstruments - settings for various payment instruments
|
|
74
|
+
* @param {Features} options.features - flags to enable and disable different features
|
|
75
|
+
* @param {string} options.locale - default: auto. Language to render component text
|
|
99
76
|
*/
|
|
100
77
|
export async function mount({
|
|
101
78
|
state,
|
|
102
|
-
form = '.rebilly-instruments',
|
|
103
|
-
summary = '.rebilly-instruments-summary',
|
|
104
79
|
...options
|
|
105
80
|
} = {}) {
|
|
106
|
-
|
|
107
|
-
state.form = form;
|
|
108
|
-
state.summary = summary;
|
|
109
|
-
state.storefront = setupStorefront(options);
|
|
110
|
-
state.options = setupOptions(options);
|
|
111
|
-
state.mainStyle = await setupStyles(options);
|
|
112
|
-
state._dev = options._dev;
|
|
113
|
-
|
|
114
|
-
setupFramepay(options);
|
|
115
|
-
|
|
116
|
-
state.form = processPropertyAsDOMElement({
|
|
117
|
-
prop: state.form,
|
|
118
|
-
propName: 'form'
|
|
119
|
-
});
|
|
120
|
-
state.summary = processPropertyAsDOMElement({
|
|
121
|
-
prop: state.summary,
|
|
122
|
-
propName: 'summary',
|
|
123
|
-
isRequired: false
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
// Setup loader
|
|
127
|
-
state.loader.addDOMElement({ el: state.form });
|
|
128
|
-
state.loader.addDOMElement({ section: 'summary', el: state.summary });
|
|
129
|
-
|
|
130
81
|
try {
|
|
82
|
+
state.data = {};
|
|
83
|
+
state.options = {};
|
|
84
|
+
// Setup DOM
|
|
85
|
+
state.form = setupElement({ element: 'form', options });
|
|
86
|
+
state.summary = setupElement({ element: 'summary', options });
|
|
87
|
+
|
|
88
|
+
// Setup loader
|
|
89
|
+
state.loader.addDOMElement({ el: state.form });
|
|
90
|
+
state.loader.addDOMElement({ section: 'summary', el: state.summary });
|
|
131
91
|
state.loader.startLoading({ section: 'summary', id: 'initSummary' });
|
|
132
92
|
state.loader.startLoading({ id: 'initForm' });
|
|
133
93
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
94
|
+
// Setup state
|
|
95
|
+
state.storefront = setupStorefront({ options });
|
|
96
|
+
state.options = setupOptions({ options });
|
|
97
|
+
state.mainStyle = await setupStyles({ options });
|
|
98
|
+
state.data = await fetchData({ state });
|
|
99
|
+
state.options.themeFramepay = await setupFramepayTheme({ state, options });
|
|
100
|
+
const i18n = setupI18n({ state });
|
|
101
|
+
setupFramepay({ state });
|
|
102
|
+
|
|
103
|
+
if (state.data.transaction && state.data.transaction?.type === 'setup') {
|
|
104
|
+
state.options.transactionType = 'setup';
|
|
144
105
|
}
|
|
145
106
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const {
|
|
149
|
-
readyToPay,
|
|
150
|
-
summary: summaryData,
|
|
151
|
-
plans,
|
|
152
|
-
products
|
|
153
|
-
} = await fetchSummaryData({ riskMetadata, state });
|
|
154
|
-
|
|
155
|
-
state.hasMounted = true;
|
|
156
|
-
|
|
107
|
+
// Mount content
|
|
157
108
|
if (state.form) {
|
|
158
|
-
|
|
159
|
-
summary: summaryData,
|
|
160
|
-
mainStyle: state.mainStyle,
|
|
161
|
-
readyToPay,
|
|
162
|
-
plans,
|
|
163
|
-
products
|
|
164
|
-
};
|
|
165
|
-
mountMethodSelector({ state, formOptions });
|
|
109
|
+
mountMethodSelector({ state });
|
|
166
110
|
}
|
|
167
|
-
|
|
168
111
|
if (state.summary) {
|
|
169
|
-
|
|
170
|
-
summary: summaryData,
|
|
171
|
-
readyToPay,
|
|
172
|
-
plans,
|
|
173
|
-
products
|
|
174
|
-
};
|
|
175
|
-
mountSummary({ state, summaryOptions });
|
|
112
|
+
mountSummary({ state });
|
|
176
113
|
}
|
|
114
|
+
i18n({state});
|
|
115
|
+
state.hasMounted = true;
|
|
177
116
|
} catch (error) {
|
|
178
117
|
throw error;
|
|
179
118
|
}
|
|
180
119
|
|
|
181
|
-
state.translate.init(state.options.locale, state.options.i18n);
|
|
182
|
-
state.translate.translateItems();
|
|
183
|
-
|
|
184
120
|
if (state.options.features.autoConfirmation) {
|
|
185
121
|
on({
|
|
186
122
|
eventName: 'instrument-ready',
|
|
187
|
-
callback: (
|
|
123
|
+
callback: (payload) => {
|
|
188
124
|
show({
|
|
189
125
|
componentName: 'confirmation',
|
|
190
|
-
payload
|
|
191
|
-
instrument,
|
|
192
|
-
mainStyle: state.mainStyle
|
|
193
|
-
},
|
|
126
|
+
payload,
|
|
194
127
|
state
|
|
195
128
|
});
|
|
196
129
|
}
|
|
@@ -198,18 +131,28 @@ export async function mount({
|
|
|
198
131
|
}
|
|
199
132
|
|
|
200
133
|
if (state.options.features.autoResult) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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
|
+
}
|
|
214
157
|
}
|
|
215
158
|
}
|
|
@@ -23,9 +23,7 @@ describe('RebillyInstruments instance', () => {
|
|
|
23
23
|
}
|
|
24
24
|
],
|
|
25
25
|
theme: {
|
|
26
|
-
|
|
27
|
-
background: '#000'
|
|
28
|
-
}
|
|
26
|
+
colorBackground: '#000'
|
|
29
27
|
},
|
|
30
28
|
css: `
|
|
31
29
|
.rebilly-instruments-summary-line-item-synopsis-title {
|
|
@@ -47,8 +45,8 @@ describe('RebillyInstruments instance', () => {
|
|
|
47
45
|
const SUMMARY_CONTAINER = summarySelector.querySelector(
|
|
48
46
|
'.rebilly-instruments-content'
|
|
49
47
|
);
|
|
50
|
-
expect(getComputedStyle(SUMMARY_CONTAINER).
|
|
51
|
-
'
|
|
48
|
+
expect(getComputedStyle(SUMMARY_CONTAINER).getPropertyValue('--rebilly-colorBackground')).toEqual(
|
|
49
|
+
'#000'
|
|
52
50
|
);
|
|
53
51
|
|
|
54
52
|
// CSS config property overrides initial styles
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { processPropertyAsDOMElement } from '../../utils';
|
|
2
|
+
|
|
3
|
+
export default ({element = '', options = {}}) => {
|
|
4
|
+
if (element !== 'form' && element !== 'summary') {
|
|
5
|
+
throw new Error('element must be "form" or "summary"');
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const getProp = () => {
|
|
9
|
+
if (options[element]) {
|
|
10
|
+
return options[element]
|
|
11
|
+
}
|
|
12
|
+
switch(element) {
|
|
13
|
+
case 'summary':
|
|
14
|
+
return '.rebilly-instruments-summary'
|
|
15
|
+
case 'form':
|
|
16
|
+
default:
|
|
17
|
+
return '.rebilly-instruments'
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return processPropertyAsDOMElement({
|
|
22
|
+
prop: getProp(),
|
|
23
|
+
propName: element,
|
|
24
|
+
isRequired: ['form'].includes(element)
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import css from 'css';
|
|
2
|
+
import postcss from 'postcss';
|
|
3
|
+
import postcssCustomProperties from 'postcss-custom-properties';
|
|
4
|
+
import camelCase from 'lodash.camelcase';
|
|
5
|
+
|
|
6
|
+
const resolveCssVars = async (rawCss) => postcss([
|
|
7
|
+
postcssCustomProperties({ preserve: false })
|
|
8
|
+
])
|
|
9
|
+
.process(rawCss, { from: undefined })
|
|
10
|
+
.then(output => output.css);
|
|
11
|
+
|
|
12
|
+
const getStyleProps = (ast, selector) => {
|
|
13
|
+
const { rules } = ast.stylesheet;
|
|
14
|
+
const output = {
|
|
15
|
+
color: null,
|
|
16
|
+
fontFamily: null,
|
|
17
|
+
fontSize: null,
|
|
18
|
+
lineHeight: null,
|
|
19
|
+
fontWeight: null,
|
|
20
|
+
background: null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
for(let i = 0; i < rules.length; i += 1) {
|
|
24
|
+
const rule = rules[i];
|
|
25
|
+
|
|
26
|
+
if(rule.type === 'rule' && rule.selectors.includes(selector)) {
|
|
27
|
+
rule.declarations.forEach(decl => {
|
|
28
|
+
const propName = camelCase(decl.property);
|
|
29
|
+
if(typeof output[propName] !== 'undefined') {
|
|
30
|
+
output[propName] = decl.value;
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return output;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default async ({
|
|
39
|
+
state,
|
|
40
|
+
options = {}
|
|
41
|
+
}) => {
|
|
42
|
+
const fullCss = `
|
|
43
|
+
${state.mainStyle}
|
|
44
|
+
${options.css || ''}
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
const resolvedCss = await resolveCssVars(fullCss);
|
|
48
|
+
const cssAst = css.parse(resolvedCss);
|
|
49
|
+
|
|
50
|
+
const cssSelectors = {
|
|
51
|
+
base: '.rebilly-instruments-form-field-input',
|
|
52
|
+
baseHover: '.rebilly-instruments-form-field-input:hover',
|
|
53
|
+
baseFocus: '.rebilly-instruments-form-field-input:focus',
|
|
54
|
+
basePlaceholder: '.rebilly-instruments-form-field-input::placeholder',
|
|
55
|
+
baseSelection: '.rebilly-instruments-form-field-input::selection',
|
|
56
|
+
|
|
57
|
+
invalid: '.rebilly-instruments-form-field.is-error .rebilly-instruments-form-field-input',
|
|
58
|
+
invalidHover: '.rebilly-instruments-form-field.is-error .rebilly-instruments-form-field-input:hover',
|
|
59
|
+
invalidFocus: '.rebilly-instruments-form-field.is-error .rebilly-instruments-form-field-input:focus',
|
|
60
|
+
invalidPlaceholder: '.rebilly-instruments-form-field.is-error .rebilly-instruments-form-field-input::placeholder',
|
|
61
|
+
invalidSelection: '.rebilly-instruments-form-field.is-error .rebilly-instruments-form-field-input::selection'
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const framepayStyle = {
|
|
65
|
+
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),
|
|
71
|
+
},
|
|
72
|
+
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),
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return framepayStyle;
|
|
82
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const triggerTranslations = ({state}) => {
|
|
2
|
+
state.translate.init(state.options.locale, state.options.i18n);
|
|
3
|
+
state.translate.translateItems();
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export default ({state = {}}) => {
|
|
7
|
+
if (
|
|
8
|
+
state.options.locale === 'auto' &&
|
|
9
|
+
state.data.riskMetadata?.browserData?.language
|
|
10
|
+
) {
|
|
11
|
+
const {
|
|
12
|
+
browserData: { language }
|
|
13
|
+
} = state.data.riskMetadata;
|
|
14
|
+
state.options.locale = language;
|
|
15
|
+
}
|
|
16
|
+
state.translate.init(state.options.locale, state.options.i18n);
|
|
17
|
+
|
|
18
|
+
return triggerTranslations;
|
|
19
|
+
}
|
|
@@ -1,55 +1,75 @@
|
|
|
1
1
|
import merge from 'lodash.merge';
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
export const defaults = {
|
|
4
|
+
countryCode: 'US',
|
|
5
|
+
locale: 'auto',
|
|
6
|
+
theme: {
|
|
7
|
+
labels: 'floating'
|
|
8
|
+
},
|
|
9
|
+
paymentInstruments: {
|
|
10
|
+
address: {
|
|
11
|
+
name: 'default',
|
|
12
|
+
region: 'default',
|
|
13
|
+
hide: [],
|
|
14
|
+
show: [],
|
|
15
|
+
require: []
|
|
16
|
+
},
|
|
17
|
+
compactExpressInstruments: true,
|
|
18
|
+
googlePay: {
|
|
19
|
+
displayOptions: {
|
|
20
|
+
buttonColor: 'black',
|
|
21
|
+
buttonType: 'short',
|
|
22
|
+
buttonHeight: '44px'
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
applePay: {
|
|
26
|
+
displayOptions: {
|
|
27
|
+
buttonColor: 'black',
|
|
28
|
+
buttonType: 'plain',
|
|
29
|
+
buttonHeight: '44px'
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
paymentCard: {
|
|
33
|
+
popup: false
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
transactionType: 'purchase',
|
|
37
|
+
features: {
|
|
38
|
+
autoConfirmation: true,
|
|
39
|
+
autoResult: true
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export function validateOptions(options) {
|
|
44
|
+
// TODO: validate more options
|
|
45
|
+
const purchaseData = [
|
|
46
|
+
options.items,
|
|
47
|
+
options.invoiceId,
|
|
48
|
+
options.money,
|
|
49
|
+
options.transactionId,
|
|
50
|
+
].filter(v => v);
|
|
51
|
+
|
|
52
|
+
if (purchaseData.length === 0) {
|
|
53
|
+
throw new Error('Must provide purchase data');
|
|
54
|
+
}
|
|
7
55
|
|
|
8
|
-
|
|
56
|
+
if (purchaseData.length > 1) {
|
|
57
|
+
throw new Error('Must provide only one purchase data type');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default ({
|
|
62
|
+
options = {}
|
|
63
|
+
} = {}) => {
|
|
64
|
+
validateOptions(options);
|
|
9
65
|
|
|
10
66
|
const _computed = {
|
|
11
|
-
paymentMethodsUrl: _dev
|
|
12
|
-
? _dev.paymentMethodsUrl || 'https://forms.local.rebilly.dev:3000'
|
|
67
|
+
paymentMethodsUrl: options._dev
|
|
68
|
+
? options._dev.paymentMethodsUrl || 'https://forms.local.rebilly.dev:3000'
|
|
13
69
|
: 'https://forms.secure-payments.app'
|
|
14
70
|
};
|
|
15
71
|
|
|
16
|
-
const
|
|
17
|
-
countryCode: 'US',
|
|
18
|
-
locale: 'auto',
|
|
19
|
-
paymentInstruments: {
|
|
20
|
-
address: {
|
|
21
|
-
name: 'default',
|
|
22
|
-
region: 'default',
|
|
23
|
-
hide: [],
|
|
24
|
-
show: [],
|
|
25
|
-
require: []
|
|
26
|
-
},
|
|
27
|
-
compactExpressInstruments: true,
|
|
28
|
-
googlePay: {
|
|
29
|
-
displayOptions: {
|
|
30
|
-
buttonColor: 'black',
|
|
31
|
-
buttonType: 'short',
|
|
32
|
-
buttonHeight: '44px'
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
applePay: {
|
|
36
|
-
displayOptions: {
|
|
37
|
-
buttonColor: 'black',
|
|
38
|
-
buttonType: 'plain',
|
|
39
|
-
buttonHeight: '44px'
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
paymentCard: {
|
|
43
|
-
popup: false
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
features: {
|
|
47
|
-
autoConfirmation: true,
|
|
48
|
-
autoResult: true
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const combinedOptions = merge(defaults, {
|
|
72
|
+
const combinedOptions = merge({...defaults}, {
|
|
53
73
|
organizationId: options.organizationId,
|
|
54
74
|
publishableKey: options.publishableKey,
|
|
55
75
|
websiteId: options.websiteId,
|
|
@@ -57,17 +77,27 @@ export default (options = {}) => {
|
|
|
57
77
|
i18n: options.i18n,
|
|
58
78
|
theme: options.theme,
|
|
59
79
|
css: options.css,
|
|
60
|
-
items: options.items,
|
|
61
80
|
locale: options.locale,
|
|
62
81
|
countryCode: options.countryCode,
|
|
63
82
|
features: options.features,
|
|
64
83
|
paymentInstruments: options.paymentInstruments,
|
|
84
|
+
transactionType: options.transactionType,
|
|
65
85
|
_computed
|
|
66
86
|
});
|
|
67
87
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
88
|
+
// Add optional key's
|
|
89
|
+
[
|
|
90
|
+
'items',
|
|
91
|
+
'money',
|
|
92
|
+
'invoiceId',
|
|
93
|
+
'transactionId',
|
|
94
|
+
'customerJwt',
|
|
95
|
+
'_dev'
|
|
96
|
+
].forEach(key => {
|
|
97
|
+
if (options[key]) {
|
|
98
|
+
combinedOptions[key] = options[key];
|
|
99
|
+
}
|
|
100
|
+
});
|
|
71
101
|
|
|
72
102
|
return combinedOptions;
|
|
73
103
|
}
|