@rebilly/instruments 3.37.2 → 3.38.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/CHANGELOG.md +7 -0
- package/dist/index.js +15 -15
- package/dist/index.min.js +15 -15
- package/package.json +1 -1
- package/src/data/options-schema/schemas/options-schema.js +14 -3
- package/src/functions/mount/fetch-data.js +15 -3
- package/src/functions/mount/index.js +4 -70
- package/src/functions/mount/mount.spec.js +6 -1
- package/src/functions/mount/setup-options.js +28 -7
- package/src/functions/mount/setup-options.spec.js +3 -3
- package/src/functions/purchase.js +10 -4
- package/src/functions/show.js +3 -4
- package/src/functions/show.spec.js +0 -2
- package/src/i18n/en.json +3 -0
- package/src/i18n/es.json +3 -0
- package/src/storefront/deposit-requests.js +12 -0
- package/src/storefront/models/deposit-request-model.js +15 -0
- package/src/storefront/ready-to-pay.js +5 -0
- package/src/storefront/summary.js +1 -1
- package/src/style/base/__snapshots__/theme.spec.js.snap +1 -1
- package/src/style/base/default-theme.js +1 -1
- package/src/style/base/index.js +4 -0
- package/src/views/amount-selector.js +47 -0
- package/src/views/common/iframe/base-iframe.js +7 -1
- package/src/views/confirmation.js +14 -15
- package/src/views/form.js +52 -0
- package/src/views/method-selector/__snapshots__/method-selector.spec.js.snap +10 -59
- package/src/views/method-selector/generate-digital-wallet.js +2 -2
- package/src/views/method-selector/generate-digital-wallet.spec.js +2 -13
- package/src/views/method-selector/get-payment-methods.js +5 -5
- package/src/views/method-selector/get-payment-methods.spec.js +4 -3
- package/src/views/method-selector/index.js +151 -86
- package/src/views/method-selector/method-selector.spec.js +1 -1
- package/src/views/result.js +8 -18
- package/src/views/summary.js +11 -3
package/package.json
CHANGED
|
@@ -78,7 +78,9 @@ export default {
|
|
|
78
78
|
money: {
|
|
79
79
|
type: 'object',
|
|
80
80
|
properties: {
|
|
81
|
-
amount: {
|
|
81
|
+
amount: {
|
|
82
|
+
type: 'number'
|
|
83
|
+
},
|
|
82
84
|
currency: {
|
|
83
85
|
type: 'string',
|
|
84
86
|
minLength: 3,
|
|
@@ -105,7 +107,9 @@ export default {
|
|
|
105
107
|
minLength: 3,
|
|
106
108
|
maxLength: 3,
|
|
107
109
|
},
|
|
108
|
-
amount: {
|
|
110
|
+
amount: {
|
|
111
|
+
type: 'number'
|
|
112
|
+
},
|
|
109
113
|
buttons: {
|
|
110
114
|
type: 'array',
|
|
111
115
|
items: {
|
|
@@ -118,10 +122,17 @@ export default {
|
|
|
118
122
|
properties: {
|
|
119
123
|
minimum: {type: 'number'},
|
|
120
124
|
maximum: {type: 'number'},
|
|
121
|
-
|
|
125
|
+
multipleOf: {type: 'number'}
|
|
122
126
|
},
|
|
123
127
|
}
|
|
124
128
|
},
|
|
129
|
+
anyOf: [
|
|
130
|
+
{
|
|
131
|
+
required: ['amount'],
|
|
132
|
+
}, {
|
|
133
|
+
required: ['buttons']
|
|
134
|
+
}
|
|
135
|
+
],
|
|
125
136
|
required: ['currency']
|
|
126
137
|
}
|
|
127
138
|
]
|
|
@@ -8,6 +8,8 @@ import { fetchInvoiceAndProducts as FetchInvoiceAndProducts } from '../../storef
|
|
|
8
8
|
import { fetchTransaction as FetchTransaction } from '../../storefront/transactions';
|
|
9
9
|
import { fetchAccountAndWebsite as FetchAccountAndWebsite } from '../../storefront/account-and-website';
|
|
10
10
|
import { fetchPaymentInstrument as FetchInstruments } from '../../storefront/payment-instruments';
|
|
11
|
+
import { fetchDepositRequest as FetchDepositRequest } from '../../storefront/deposit-requests';
|
|
12
|
+
import DepositRequestModel from '../../storefront/models/deposit-request-model';
|
|
11
13
|
|
|
12
14
|
export class DataInstance {
|
|
13
15
|
constructor({
|
|
@@ -126,11 +128,22 @@ export async function fetchData({
|
|
|
126
128
|
fetchInvoiceAndProducts = FetchInvoiceAndProducts,
|
|
127
129
|
fetchTransaction = FetchTransaction,
|
|
128
130
|
fetchAccountAndWebsite = FetchAccountAndWebsite,
|
|
129
|
-
fetchInstruments = FetchInstruments
|
|
131
|
+
fetchInstruments = FetchInstruments,
|
|
132
|
+
fetchDepositRequest = FetchDepositRequest,
|
|
130
133
|
} = {}) {
|
|
131
134
|
try {
|
|
132
135
|
state.data = new DataInstance();
|
|
133
136
|
|
|
137
|
+
if (state.options?.deposit) {
|
|
138
|
+
if (state.options.deposit.depositRequestId) {
|
|
139
|
+
state.data.deposit = await fetchDepositRequest({data: {
|
|
140
|
+
id: state.options.deposit.depositRequestId,
|
|
141
|
+
}});
|
|
142
|
+
} else {
|
|
143
|
+
state.data.deposit = new DepositRequestModel(state.options.deposit);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
134
147
|
let readyToPayPromise = Promise.resolve(null);
|
|
135
148
|
|
|
136
149
|
let availableInstrumentsPromise = null;
|
|
@@ -149,8 +162,7 @@ export async function fetchData({
|
|
|
149
162
|
state.data.transaction = await fetchTransaction({
|
|
150
163
|
data: {
|
|
151
164
|
id: state.options.transactionId
|
|
152
|
-
}
|
|
153
|
-
});
|
|
165
|
+
}});
|
|
154
166
|
}
|
|
155
167
|
|
|
156
168
|
let productsPromise;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable max-len */
|
|
2
2
|
import state from '../../state';
|
|
3
3
|
import { mountSummary } from '../../views/summary';
|
|
4
|
-
import {
|
|
4
|
+
import { mountForm, determineFirstView } from '../../views/form';
|
|
5
5
|
import { fetchData } from './fetch-data';
|
|
6
6
|
import Events from '../../events';
|
|
7
7
|
import setupElement from './setup-element';
|
|
@@ -14,74 +14,7 @@ import setupFramepayTheme from './setup-framepay-theme';
|
|
|
14
14
|
import setupUserFlow from './setup-user-flow';
|
|
15
15
|
import { showError } from '../../views/errors';
|
|
16
16
|
|
|
17
|
-
/**
|
|
18
|
-
* @typedef {object} ItemQuantity - Item quantity
|
|
19
|
-
* @property {number} default - The initial quantity value
|
|
20
|
-
* @property {number} [minimum=1] - minimum allowed quantity. if minimum, maximum or multipleOf are present, quantity will be "variable"
|
|
21
|
-
* @property {number} [maximum=Number.MAX_SAFE_INTEGER] - maximum allowed quantity
|
|
22
|
-
* @property {number} [multipleOf=1]
|
|
23
|
-
*
|
|
24
|
-
* @typedef {object} Item
|
|
25
|
-
* @property {string} planId - The Rebilly id of the plan.
|
|
26
|
-
* @property {number | ItemQuantity} quantity - The number of the plans to be purchased.
|
|
27
|
-
* @property {string} thumbnail - The source img for the product. Recommend 100px by 100px.
|
|
28
|
-
*
|
|
29
|
-
* @typedef {object} GooglePayDisplayOptions
|
|
30
|
-
* @property {"back" | "white"} [buttonColor=black] - Color of google pay button
|
|
31
|
-
* @property {"book" | "buy" | "checkout" | "donate" | "order" | "pay" | "plain" | "subscribe" | "short" | "long"} [buttonType=plain] - The length of the button
|
|
32
|
-
* @property {string} [buttonHeight=48px] - The value and units of the button to match other payment buttons
|
|
33
|
-
*
|
|
34
|
-
* @typedef {object} ApplePayDisplayOptions
|
|
35
|
-
* @property {"back" | "white"} [buttonColor=black] - Color of apple pay button
|
|
36
|
-
* @property {"short" | "long"} [buttonType=short] - The length of the button
|
|
37
|
-
* @property {string} [buttonHeight=48px] - The value and units of the button to match other payment buttons
|
|
38
|
-
*
|
|
39
|
-
* @typedef {object} ApplePayMerchantOptions
|
|
40
|
-
* @property {string} merchantName - The name of the merchant store.
|
|
41
|
-
*
|
|
42
|
-
* @typedef {object} GooglePay
|
|
43
|
-
* @property {GooglePayDisplayOptions} displayOptions - display options for google pay instrument
|
|
44
|
-
*
|
|
45
|
-
* @typedef {object} ApplePay
|
|
46
|
-
* @property {ApplePayDisplayOptions} displayOptions - display options for apple pay instrument
|
|
47
|
-
* @property {ApplePayMerchantOptions} merchantOptions - merchant options for apple pay instrument
|
|
48
|
-
*
|
|
49
|
-
* @typedef {object} PaymentCard
|
|
50
|
-
* @property {boolean} [popup=true] - Show method as a button with a form popup. Otherwise the form will be mounted inline.
|
|
51
|
-
*
|
|
52
|
-
* @typedef {object} Address
|
|
53
|
-
* @property {string} [name=default] - One of default, combined, or stacked.
|
|
54
|
-
* @property {string} [region=default] - One of default, split, or stacked.
|
|
55
|
-
* @property {Array.<"organization" | "phoneNumber">} show - Show extra fields listed.
|
|
56
|
-
* @property {Array.<"address" | "address2" | "email | "country" | "region" | "postalCode"">} hide - Hide the listed fields.
|
|
57
|
-
* @property {Array.<"organization" | "address" | "address2" | "email" | "phoneNumber" | "country" | "region" | "postalCode">} require - Require the listed fields.
|
|
58
|
-
*
|
|
59
|
-
* @typedef {object} PaymentInstruments
|
|
60
|
-
* @property {boolean} [compactExpressInstruments=true] - Show express methods as inline pill buttons, or list of full width button.
|
|
61
|
-
* @property {PaymentCard} paymentCard - settings for payment card instruments
|
|
62
|
-
* @property {GooglePay} googlePay - settings for google pay instruments
|
|
63
|
-
* @property {ApplePay} applePay - settings for apple pay instruments
|
|
64
|
-
* @property {Address} address - customization for address components for all payment instruments.
|
|
65
|
-
*
|
|
66
|
-
* @typedef {object} Features
|
|
67
|
-
* @property {boolean} [autoConfirmation=true] - Will mount the confirmation screen after `instrument-ready` event is triggered.
|
|
68
|
-
* @property {boolean} [autoResult=true] - Show results of transaction after `purchase-completed` event is triggered
|
|
69
|
-
*/
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Mount library with configurations.
|
|
73
|
-
* @param {object} options - The options object
|
|
74
|
-
* @param {function} options.setupFramepayInstance - Helper for adding FramePay scripts to the DOM
|
|
75
|
-
* @param {string | HTMLElement} options.form - The CSS class or HTML element were the form will be mounted.
|
|
76
|
-
* @param {string | HTMLElement} options.summary - The CSS class or HTML element were the summary will be mounted.
|
|
77
|
-
* @param {Item[]} options.items - Which plans the customer is purchasing.
|
|
78
|
-
* @param {string} options.invoiceId - The Rebilly id of the invoice used for purchasing.
|
|
79
|
-
* @param {string} options.jwt - The customer token to access the invoice.
|
|
80
|
-
* @param {string} [options.countryCode=USD] - The country code for the transaction
|
|
81
|
-
* @param {PaymentInstruments} options.paymentInstruments - settings for various payment instruments
|
|
82
|
-
* @param {Features} options.features - flags to enable and disable different features
|
|
83
|
-
* @param {string} options.locale - default: auto. Language to render component text
|
|
84
|
-
*/
|
|
17
|
+
/** See src/data/options-schema for options structure */
|
|
85
18
|
export async function mount({
|
|
86
19
|
setupFramepay = setupFramepayInstance,
|
|
87
20
|
...options
|
|
@@ -133,7 +66,8 @@ export async function mount({
|
|
|
133
66
|
|
|
134
67
|
// Mount content
|
|
135
68
|
if (state.form) {
|
|
136
|
-
|
|
69
|
+
mountForm()
|
|
70
|
+
.then(() => determineFirstView());
|
|
137
71
|
}
|
|
138
72
|
if (state.summary) {
|
|
139
73
|
mountSummary();
|
|
@@ -35,7 +35,12 @@ describe('RebillyInstruments instance', () => {
|
|
|
35
35
|
|
|
36
36
|
// Mounts form and summary
|
|
37
37
|
const summarySelector = document.querySelector('.summary-selector');
|
|
38
|
-
|
|
38
|
+
const iframe = summarySelector.querySelector('iframe');
|
|
39
|
+
expect(iframe.getAttribute('name')).toEqual('rebilly-instruments-summary');
|
|
40
|
+
expect(iframe.getAttribute('class')).toEqual('rebilly-instruments-iframe');
|
|
41
|
+
expect(iframe.getAttribute('loading')).toEqual('lazy');
|
|
42
|
+
expect(iframe.getAttribute('allow')).toEqual('payment');
|
|
43
|
+
expect(iframe.getAttribute('src')).toEqual('https://forms.test.rebilly.dev?name=rebilly-instruments-summary');
|
|
39
44
|
|
|
40
45
|
// Theme config overrides initial styles
|
|
41
46
|
const STYLE_VARS = document.querySelectorAll('style[type="text/css"]')[0];
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import decodeJwt from 'jwt-decode';
|
|
2
2
|
import merge from 'lodash.merge';
|
|
3
3
|
import { parseQuantity } from '../../utils/quantity';
|
|
4
|
-
import { validateOptions } from '../../data/options-schema';
|
|
4
|
+
import { validateOptions, RebillyInstrumentsConfigError } from '../../data/options-schema';
|
|
5
5
|
|
|
6
6
|
export function handleComputedProperty(options) {
|
|
7
|
-
|
|
7
|
+
options._computed = {
|
|
8
8
|
paymentMethodsUrl: options._dev?.paymentMethodsUrl ?? 'https://forms.secure-payments.app'
|
|
9
9
|
};
|
|
10
|
-
options._computed = _computed;
|
|
11
10
|
return options
|
|
12
11
|
}
|
|
13
12
|
|
|
@@ -25,8 +24,24 @@ export function handleNestedPropertiesDefaultValues(options) {
|
|
|
25
24
|
buttons: [],
|
|
26
25
|
customAmount: {
|
|
27
26
|
minimum: 1,
|
|
28
|
-
maximum:
|
|
29
|
-
|
|
27
|
+
maximum: 1000000000000,
|
|
28
|
+
multipleOf: 1,
|
|
29
|
+
}
|
|
30
|
+
}, (options.deposit || {}));
|
|
31
|
+
|
|
32
|
+
// default to first deposit button if there is no deposit amount
|
|
33
|
+
if (isNaN(options.deposit.amount)) {
|
|
34
|
+
if (options.deposit.buttons.length > 0) {
|
|
35
|
+
options.deposit.amount = options.deposit.buttons[0];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
} else if (options.deposit?.depositRequestId) {
|
|
40
|
+
options.deposit = merge({
|
|
41
|
+
customAmount: {
|
|
42
|
+
minimum: 1,
|
|
43
|
+
maximum: 1000000000000,
|
|
44
|
+
multipleOf: 1,
|
|
30
45
|
}
|
|
31
46
|
}, (options.deposit || {}));
|
|
32
47
|
}
|
|
@@ -49,6 +64,7 @@ export function handleJwtDestructuring(options) {
|
|
|
49
64
|
transactionId,
|
|
50
65
|
invoiceId,
|
|
51
66
|
websiteId,
|
|
67
|
+
cashierRequestId
|
|
52
68
|
}
|
|
53
69
|
} = decodeJwt(options.jwt);
|
|
54
70
|
Object.entries({
|
|
@@ -61,6 +77,10 @@ export function handleJwtDestructuring(options) {
|
|
|
61
77
|
options[key] = value;
|
|
62
78
|
}
|
|
63
79
|
});
|
|
80
|
+
if (cashierRequestId && !options.deposit) {
|
|
81
|
+
options.deposit = {};
|
|
82
|
+
options.deposit.depositRequestId = cashierRequestId;
|
|
83
|
+
}
|
|
64
84
|
}
|
|
65
85
|
|
|
66
86
|
return options;
|
|
@@ -71,9 +91,10 @@ export default ({
|
|
|
71
91
|
} = {}) => {
|
|
72
92
|
let validOptions = validateOptions(options);
|
|
73
93
|
if (validOptions) {
|
|
74
|
-
validOptions = handleComputedProperty(validOptions);
|
|
75
|
-
validOptions = handleNestedPropertiesDefaultValues(validOptions);
|
|
76
94
|
validOptions = handleJwtDestructuring(validOptions);
|
|
95
|
+
validOptions = handleNestedPropertiesDefaultValues(validOptions);
|
|
96
|
+
validOptions = handleComputedProperty(validOptions);
|
|
77
97
|
}
|
|
98
|
+
|
|
78
99
|
return validOptions;
|
|
79
100
|
}
|
|
@@ -217,7 +217,7 @@ describe('Setup options handleNestedPropertiesDefaultValues function', () => {
|
|
|
217
217
|
buttons: [],
|
|
218
218
|
customAmount: {
|
|
219
219
|
minimum: 1,
|
|
220
|
-
maximum:
|
|
220
|
+
maximum: 1000000000000,
|
|
221
221
|
increment: 1,
|
|
222
222
|
},
|
|
223
223
|
currency: 'USD'
|
|
@@ -253,9 +253,9 @@ describe('Setup options handleNestedPropertiesDefaultValues function', () => {
|
|
|
253
253
|
items: [{
|
|
254
254
|
planId: 'plan_TEST',
|
|
255
255
|
quantity: {
|
|
256
|
-
minimum: 1,
|
|
256
|
+
minimum: 0.1,
|
|
257
257
|
maximum: Number.MAX_SAFE_INTEGER,
|
|
258
|
-
multipleOf: 1
|
|
258
|
+
multipleOf: 0.1
|
|
259
259
|
}
|
|
260
260
|
}]
|
|
261
261
|
});
|
|
@@ -27,21 +27,27 @@ export async function makePayment({ payload }) {
|
|
|
27
27
|
data.token = id;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
if (state.options
|
|
30
|
+
if (state.options?.invoiceId) {
|
|
31
31
|
data.invoiceId = state.options.invoiceId;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
if (state.options
|
|
34
|
+
if (state.options?.transactionId) {
|
|
35
35
|
data.transactionId = state.options.transactionId;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
if (state.options
|
|
38
|
+
if (state.options?.money) {
|
|
39
39
|
data.websiteId = state.options.websiteId;
|
|
40
40
|
data.amount = state.options.money.amount;
|
|
41
41
|
data.currency = state.options.money.currency;
|
|
42
42
|
}
|
|
43
|
+
|
|
44
|
+
if (state.options?.deposit) {
|
|
45
|
+
data.websiteId = state.options.websiteId;
|
|
46
|
+
data.amount = state.data.amountAndCurrency.amount;
|
|
47
|
+
data.currency = state.data.amountAndCurrency.currency;
|
|
48
|
+
}
|
|
43
49
|
|
|
44
|
-
if (state.data
|
|
50
|
+
if (state.data?.couponIds && Array.isArray(state.data.couponIds)) {
|
|
45
51
|
data.couponIds = state.data.couponIds
|
|
46
52
|
}
|
|
47
53
|
|
package/src/functions/show.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import iframes from '../state/iframes';
|
|
2
2
|
import { mountConfirmation } from '../views/confirmation';
|
|
3
3
|
import { mountResult } from '../views/result';
|
|
4
|
+
import { hideExtraUI as hideMethodSelectorUI} from '../views/method-selector'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
@typedef ShowParams
|
|
@@ -17,13 +18,11 @@ import { mountResult } from '../views/result';
|
|
|
17
18
|
export async function show({ componentName, payload }) {
|
|
18
19
|
switch (componentName) {
|
|
19
20
|
case 'result':
|
|
20
|
-
|
|
21
|
-
iframes.form.destroy();
|
|
22
|
-
iframes.form = null;
|
|
23
|
-
}
|
|
21
|
+
hideMethodSelectorUI();
|
|
24
22
|
mountResult({ payload });
|
|
25
23
|
break;
|
|
26
24
|
case 'confirmation':
|
|
25
|
+
hideMethodSelectorUI();
|
|
27
26
|
mountConfirmation({ payload });
|
|
28
27
|
break;
|
|
29
28
|
default:
|
|
@@ -12,7 +12,6 @@ describe('RebillyInstruments show', () => {
|
|
|
12
12
|
.mockReturnValue(Promise.resolve());
|
|
13
13
|
|
|
14
14
|
const instance = new RebillyInstrumentsInstance();
|
|
15
|
-
iframes.form = iframeMock;
|
|
16
15
|
|
|
17
16
|
const payload = {
|
|
18
17
|
test: 'value'
|
|
@@ -24,7 +23,6 @@ describe('RebillyInstruments show', () => {
|
|
|
24
23
|
expect(mountResult).toBeCalledWith(
|
|
25
24
|
expect.objectContaining({ payload })
|
|
26
25
|
);
|
|
27
|
-
expect(iframes.form).toEqual(null);
|
|
28
26
|
});
|
|
29
27
|
|
|
30
28
|
it('should show confirmation component', async () => {
|
package/src/i18n/en.json
CHANGED
package/src/i18n/es.json
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Endpoint } from './index';
|
|
2
|
+
import state from '../state';
|
|
3
|
+
import DepositRequestModel from './models/deposit-request-model';
|
|
4
|
+
|
|
5
|
+
export async function fetchDepositRequest({data = null}) {
|
|
6
|
+
return Endpoint(async () => {
|
|
7
|
+
state.storefront.setSessionToken(state.options.jwt);
|
|
8
|
+
const {fields} = await state.storefront.cashierRequests.get(data);
|
|
9
|
+
|
|
10
|
+
return new DepositRequestModel(fields);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import BaseModel from './base-model';
|
|
2
|
+
import merge from 'lodash.merge';
|
|
3
|
+
export default class DepositRequestModel extends BaseModel {
|
|
4
|
+
constructor(fields) {
|
|
5
|
+
super(fields);
|
|
6
|
+
this.amount = Array.isArray(fields.amount) ? fields.amount[0] : fields.amount;
|
|
7
|
+
this.buttons = fields.buttons ?? [...fields.amounts];
|
|
8
|
+
this.editable = typeof fields.editable === "boolean" ? fields.editable : Boolean(fields.customAmount);
|
|
9
|
+
this.customAmount = merge({
|
|
10
|
+
minimum: 1,
|
|
11
|
+
maximum: 1000000000000,
|
|
12
|
+
multipleOf: 1,
|
|
13
|
+
}, (fields.customAmount || {}));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -85,6 +85,11 @@ export async function fetchReadyToPay({
|
|
|
85
85
|
data.billingAddress = state.data.account.address;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
if (state.data?.deposit) {
|
|
89
|
+
data.amount = state.data.deposit.amount;
|
|
90
|
+
data.currency = state.data.deposit.currency;
|
|
91
|
+
}
|
|
92
|
+
|
|
88
93
|
const { fields: readyToPayFields } = await state.storefront.purchase.readyToPay({ data });
|
|
89
94
|
const readyToPay = Object.values(readyToPayFields);
|
|
90
95
|
|
|
@@ -16,7 +16,6 @@ export async function fetchSummary({ data = null } = {}) {
|
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
|
|
20
19
|
const isBumpOfferSummary = () => state.data.summaryLineItems.every(
|
|
21
20
|
item => bumpOfferProductsIds.includes(item.planId)
|
|
22
21
|
);
|
|
@@ -50,6 +49,7 @@ export async function fetchSummary({ data = null } = {}) {
|
|
|
50
49
|
if (data?.billingAddress) {
|
|
51
50
|
payload.data.billingAddress = data.billingAddress;
|
|
52
51
|
}
|
|
52
|
+
|
|
53
53
|
if (data?.deliveryAddress) {
|
|
54
54
|
payload.data.deliveryAddress = data.deliveryAddress;
|
|
55
55
|
}
|
|
@@ -8,7 +8,7 @@ Object {
|
|
|
8
8
|
--rebilly-colorMutedText: rgba(13, 43, 62, 0.5);
|
|
9
9
|
--rebilly-colorMutedBorder: #DCE3EA;
|
|
10
10
|
--rebilly-colorDanger: #CD5C5C;
|
|
11
|
-
--rebilly-fontFamily:
|
|
11
|
+
--rebilly-fontFamily: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial sans-serif;
|
|
12
12
|
--rebilly-fontSizeBase: 16px;
|
|
13
13
|
--rebilly-fontWeightBase: 500;
|
|
14
14
|
--rebilly-fontLineHeightBase: calc(16px * 1.5);
|
package/src/style/base/index.js
CHANGED
|
@@ -55,6 +55,10 @@ export const vars = (theme) => `
|
|
|
55
55
|
padding-top: var(--rebilly-spacingS);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
.rebilly-instruments-amount-selector {
|
|
59
|
+
padding: 2px;
|
|
60
|
+
}
|
|
61
|
+
|
|
58
62
|
/* Express Methods
|
|
59
63
|
------------------------------------------------------------ */
|
|
60
64
|
@-webkit-keyframes rebillyExpressShine {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import state from '../state';
|
|
2
|
+
import iframes from '../state/iframes';
|
|
3
|
+
import { mountMethodSelector } from './method-selector';
|
|
4
|
+
import { fetchReadyToPay } from '../storefront/ready-to-pay';
|
|
5
|
+
|
|
6
|
+
export async function mountAmountSelector() {
|
|
7
|
+
if (state.data.money) {
|
|
8
|
+
state.data.money.amount = null;
|
|
9
|
+
state.data.money.currency = null;
|
|
10
|
+
state.updateModel();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const iframe = iframes.form;
|
|
14
|
+
if (!iframe) {
|
|
15
|
+
await mountForm();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const modelSafeState = state.toModel();
|
|
19
|
+
const model = {
|
|
20
|
+
options: modelSafeState.options,
|
|
21
|
+
data: modelSafeState.data,
|
|
22
|
+
mainStyleVars: modelSafeState.mainStyleVars,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
iframe.component?.call('route', {
|
|
26
|
+
name: 'amount-selector'
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
iframe.component?.call('update', model);
|
|
30
|
+
|
|
31
|
+
iframe?.component?.on('confirm-amount', async (data) => {
|
|
32
|
+
const { amount, currency } = data;
|
|
33
|
+
state.data.money = {
|
|
34
|
+
amount,
|
|
35
|
+
currency,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const readyToPayUpdated = await fetchReadyToPay({
|
|
39
|
+
riskMetadata: state.data.riskMetadata
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
state.data.readyToPay = readyToPayUpdated;
|
|
43
|
+
|
|
44
|
+
state.updateModel();
|
|
45
|
+
mountMethodSelector();
|
|
46
|
+
});
|
|
47
|
+
}
|
|
@@ -6,7 +6,8 @@ export default class BaseIframe {
|
|
|
6
6
|
url = '',
|
|
7
7
|
model = {},
|
|
8
8
|
container = null,
|
|
9
|
-
classListArray = []
|
|
9
|
+
classListArray = [],
|
|
10
|
+
route = null,
|
|
10
11
|
} = {}) {
|
|
11
12
|
classListArray = Array.isArray(classListArray) ? classListArray : [];
|
|
12
13
|
if (!classListArray.includes('rebilly-instruments-iframe')) {
|
|
@@ -22,6 +23,11 @@ export default class BaseIframe {
|
|
|
22
23
|
|
|
23
24
|
return (async () => {
|
|
24
25
|
this.component = await this.createComponent();
|
|
26
|
+
|
|
27
|
+
if (route) {
|
|
28
|
+
this.component.call('route', route);
|
|
29
|
+
}
|
|
30
|
+
|
|
25
31
|
return this;
|
|
26
32
|
})();
|
|
27
33
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import state from '../state';
|
|
2
2
|
import iframes from '../state/iframes';
|
|
3
|
+
import { mountForm } from './form';
|
|
3
4
|
import { updateSummary } from './summary';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
'<div class="rebilly-instruments-confirmation"></div>';
|
|
5
|
+
import { purchase} from '../functions/purchase';
|
|
6
|
+
import { setup } from '../functions/setup';
|
|
7
7
|
|
|
8
8
|
export async function mountConfirmation({ payload: instrument }) {
|
|
9
9
|
if (
|
|
@@ -14,7 +14,10 @@ export async function mountConfirmation({ payload: instrument }) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const iframe = iframes.form;
|
|
17
|
-
|
|
17
|
+
if (!iframe) {
|
|
18
|
+
await mountForm();
|
|
19
|
+
}
|
|
20
|
+
|
|
18
21
|
const modelSafeState = state.toModel();
|
|
19
22
|
const model = {
|
|
20
23
|
options: modelSafeState.options,
|
|
@@ -29,15 +32,11 @@ export async function mountConfirmation({ payload: instrument }) {
|
|
|
29
32
|
|
|
30
33
|
iframe?.component?.call('update', model);
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
el.style.overflow = 'hidden';
|
|
40
|
-
el.style.height = '0px';
|
|
41
|
-
el.style.marginBottom = '0px';
|
|
42
|
-
})
|
|
35
|
+
iframe?.component?.on(`${iframe.name}-confirm-purchase`, (confirmedInstrument) => {
|
|
36
|
+
purchase({ payload: confirmedInstrument });
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
iframe?.component?.on(`${iframe.name}-confirm-setup`, (confirmedInstrument) => {
|
|
40
|
+
setup({ payload: confirmedInstrument });
|
|
41
|
+
});
|
|
43
42
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import state from '../state';
|
|
2
|
+
import iframes from '../state/iframes';
|
|
3
|
+
import { ViewIframe } from './common/iframe';
|
|
4
|
+
import { mountMethodSelector } from './method-selector';
|
|
5
|
+
import { mountAmountSelector } from './amount-selector';
|
|
6
|
+
|
|
7
|
+
export const baseMethodSelectorHTML = () => `
|
|
8
|
+
<div data-rebilly-instruments="content" class="rebilly-instruments-content">
|
|
9
|
+
<div data-rebilly-instruments="content-error" id="rebilly-instruments-error"></div>
|
|
10
|
+
<div data-rebilly-instruments="form"></div>
|
|
11
|
+
</div>
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
export async function mountForm() {
|
|
15
|
+
state.form.innerHTML += baseMethodSelectorHTML();
|
|
16
|
+
const container = document.querySelector('[data-rebilly-instruments="form"]');
|
|
17
|
+
const { paymentMethodsUrl: url } = state.options?._computed;
|
|
18
|
+
const name = 'rebilly-instruments-form';
|
|
19
|
+
|
|
20
|
+
const modelSafeState = state.toModel();
|
|
21
|
+
const model = {
|
|
22
|
+
options: modelSafeState.options,
|
|
23
|
+
data: modelSafeState.data,
|
|
24
|
+
mainStyleVars: modelSafeState.mainStyleVars,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const args = {
|
|
28
|
+
name,
|
|
29
|
+
url: `${url}?name=${name}`,
|
|
30
|
+
container,
|
|
31
|
+
model,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const iframe = await new ViewIframe(args);
|
|
35
|
+
iframe.bindEventListeners({loader: state.loader});
|
|
36
|
+
|
|
37
|
+
iframes.form = iframe;
|
|
38
|
+
|
|
39
|
+
state.loader.stopLoading({id: 'rebilly-instruments-form'});
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
then: (callback) => callback()
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function determineFirstView() {
|
|
47
|
+
if (state.options?.deposit) {
|
|
48
|
+
mountAmountSelector();
|
|
49
|
+
} else {
|
|
50
|
+
mountMethodSelector();
|
|
51
|
+
}
|
|
52
|
+
}
|