@rebilly/instruments 3.15.4-beta.0 → 3.16.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +4 -2
- package/dist/index.js +9 -9
- package/dist/index.min.js +8 -8
- package/package.json +2 -1
- package/src/functions/mount/fetch-data.js +17 -2
- package/src/functions/mount/setup-options.js +2 -1
- package/src/functions/purchase.js +18 -8
- package/src/functions/purchase.spec.js +4 -1
- package/src/storefront/summary.js +9 -0
- package/src/storefront/summary.spec.js +6 -6
- package/src/views/common/iframe/events/change-iframe-src-handler.js +6 -0
- package/src/views/common/iframe/events/dispatch-event-handler.js +8 -0
- package/src/views/common/iframe/events/resize-component-handler.js +9 -0
- package/src/views/common/iframe/events/show-error-handler.js +5 -0
- package/src/views/common/iframe/events/stop-loader-handler.js +9 -0
- package/src/views/common/iframe/events/update-coupons-handler.js +18 -0
- package/src/views/common/iframe/modal-iframe.js +8 -9
- package/src/views/common/iframe/view-iframe.js +8 -7
- package/src/views/method-selector/index.js +1 -0
- package/src/views/result.js +1 -0
- package/src/views/summary.js +1 -0
- package/src/views/common/iframe/event-listeners.js +0 -50
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebilly/instruments",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.16.0-beta.0",
|
|
4
4
|
"author": "Rebilly",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"@rollup/plugin-replace": "^3.0.0",
|
|
34
34
|
"babel-plugin-module-resolver": "^4.1.0",
|
|
35
35
|
"component-emitter": "^1.3.0",
|
|
36
|
+
"core-js": "3.23.3",
|
|
36
37
|
"jest": "^27.0.6",
|
|
37
38
|
"msw": "0.38.2",
|
|
38
39
|
"msw-when-then": "^1.5.1",
|
|
@@ -21,17 +21,20 @@ export class DataInstance {
|
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
this.money = state.options?.money || null;
|
|
24
|
+
this.couponIds = [];
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
get amountAndCurrency() {
|
|
27
28
|
let currency;
|
|
28
29
|
let amount;
|
|
30
|
+
let amountDue;
|
|
29
31
|
if (this.previewPurchase) {
|
|
30
32
|
currency = this.previewPurchase.currency;
|
|
31
33
|
amount = this.previewPurchase.total;
|
|
32
34
|
} else if (this.invoice) {
|
|
33
35
|
currency = this.invoice.currency;
|
|
34
36
|
amount = this.invoice.amount;
|
|
37
|
+
amountDue = this.invoice.amountDue;
|
|
35
38
|
} else if (this.transaction) {
|
|
36
39
|
currency = this.transaction.currency;
|
|
37
40
|
amount = this.transaction.amount;
|
|
@@ -39,10 +42,14 @@ export class DataInstance {
|
|
|
39
42
|
currency = this.money.currency;
|
|
40
43
|
amount = this.money.amount;
|
|
41
44
|
}
|
|
42
|
-
|
|
45
|
+
const amountAndCurrency = {
|
|
43
46
|
amount,
|
|
44
47
|
currency
|
|
48
|
+
};
|
|
49
|
+
if (amountDue) {
|
|
50
|
+
amountAndCurrency.amountDue = amountDue;
|
|
45
51
|
}
|
|
52
|
+
return amountAndCurrency;
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
get isPayment() {
|
|
@@ -53,6 +60,13 @@ export class DataInstance {
|
|
|
53
60
|
return this.previewPurchase;
|
|
54
61
|
}
|
|
55
62
|
|
|
63
|
+
get hasAmountDue() {
|
|
64
|
+
return !!(
|
|
65
|
+
this.amountAndCurrency.amountDue &&
|
|
66
|
+
this.amountAndCurrency.amountDue !== this.amountAndCurrency.amount
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
56
70
|
get summaryItems() {
|
|
57
71
|
const {
|
|
58
72
|
discountsAmount = null,
|
|
@@ -94,6 +108,7 @@ export class DataInstance {
|
|
|
94
108
|
amountAndCurrency: this.amountAndCurrency,
|
|
95
109
|
isPayment: this.isPayment,
|
|
96
110
|
isPurchase: this.isPurchase,
|
|
111
|
+
hasAmountDue: this.hasAmountDue,
|
|
97
112
|
summaryItems: this.summaryItems,
|
|
98
113
|
summaryLineItems: this.summaryLineItems,
|
|
99
114
|
isShippingRequired: this.isShippingRequired
|
|
@@ -186,4 +201,4 @@ export async function fetchData({
|
|
|
186
201
|
}
|
|
187
202
|
|
|
188
203
|
return new DataInstance({});
|
|
189
|
-
}
|
|
204
|
+
}
|
|
@@ -39,6 +39,10 @@ export async function makePayment({ state, payload }) {
|
|
|
39
39
|
data.currency = state.options.money.currency;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
if (state.data.couponIds && Array.isArray(state.data.couponIds)) {
|
|
43
|
+
data.couponIds = state.data.couponIds
|
|
44
|
+
}
|
|
45
|
+
|
|
42
46
|
let { fields } = await postPayment({
|
|
43
47
|
state,
|
|
44
48
|
data
|
|
@@ -57,16 +61,22 @@ export async function makePayment({ state, payload }) {
|
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
export async function makePurchase({ state, payload }) {
|
|
64
|
+
const data = {
|
|
65
|
+
websiteId: state.options.websiteId,
|
|
66
|
+
items: state.options.items,
|
|
67
|
+
paymentInstruction: {
|
|
68
|
+
token: payload._raw.id
|
|
69
|
+
},
|
|
70
|
+
...payload
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
if (state.data.couponIds && Array.isArray(state.data.couponIds)) {
|
|
74
|
+
data.couponIds = state.data.couponIds
|
|
75
|
+
}
|
|
76
|
+
|
|
60
77
|
const { fields } = await postPurchase({
|
|
61
78
|
state,
|
|
62
|
-
data
|
|
63
|
-
websiteId: state.options.websiteId,
|
|
64
|
-
items: state.options.items,
|
|
65
|
-
paymentInstruction: {
|
|
66
|
-
token: payload._raw.id
|
|
67
|
-
},
|
|
68
|
-
...payload
|
|
69
|
-
}
|
|
79
|
+
data
|
|
70
80
|
});
|
|
71
81
|
return fields;
|
|
72
82
|
}
|
|
@@ -52,6 +52,7 @@ describe('RebillyInstruments purchase', () => {
|
|
|
52
52
|
items: rebillyInstruments.state.options.items,
|
|
53
53
|
billingAddress,
|
|
54
54
|
deliveryAddress,
|
|
55
|
+
couponIds: [],
|
|
55
56
|
paymentInstruction: {
|
|
56
57
|
token: token.id
|
|
57
58
|
}
|
|
@@ -60,7 +61,9 @@ describe('RebillyInstruments purchase', () => {
|
|
|
60
61
|
await rebillyInstruments.purchase(purchasePayload);
|
|
61
62
|
|
|
62
63
|
expect(spyStorefrontPurchase).toBeCalledTimes(1);
|
|
63
|
-
expect(spyStorefrontPurchase).toBeCalledWith(
|
|
64
|
+
expect(spyStorefrontPurchase).toBeCalledWith({
|
|
65
|
+
data: expect.objectContaining(purchasePayloadParsed)
|
|
66
|
+
});
|
|
64
67
|
|
|
65
68
|
expect(Events.purchaseCompleted.dispatch).toBeCalledTimes(1);
|
|
66
69
|
|
|
@@ -13,6 +13,11 @@ export async function fetchSummary({ data = null, state = null } = {}) {
|
|
|
13
13
|
|
|
14
14
|
if (state.options?.items) {
|
|
15
15
|
payload.data.items = state.options.items;
|
|
16
|
+
} else {
|
|
17
|
+
payload.data.items = state.data.summaryLineItems.map(item => ({
|
|
18
|
+
planId: item.planId,
|
|
19
|
+
quantity: item.quantity,
|
|
20
|
+
}));
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
if (state.data?.amountAndCurrency) {
|
|
@@ -29,6 +34,10 @@ export async function fetchSummary({ data = null, state = null } = {}) {
|
|
|
29
34
|
payload.data.deliveryAddress = data.deliveryAddress;
|
|
30
35
|
}
|
|
31
36
|
|
|
37
|
+
if(state.data?.couponIds) {
|
|
38
|
+
payload.data.couponIds = state.data.couponIds;
|
|
39
|
+
}
|
|
40
|
+
|
|
32
41
|
const { fields: summaryFields } = await state.storefront.purchase.preview(
|
|
33
42
|
payload
|
|
34
43
|
);
|
|
@@ -40,10 +40,10 @@ describe('Storefront API Summary', () => {
|
|
|
40
40
|
|
|
41
41
|
expect(instance.storefront.purchase.preview).toBeCalledTimes(1);
|
|
42
42
|
expect(instance.storefront.purchase.preview).toBeCalledWith({
|
|
43
|
-
data: {
|
|
43
|
+
data: expect.objectContaining({
|
|
44
44
|
items: options.items,
|
|
45
45
|
websiteId: options.websiteId
|
|
46
|
-
}
|
|
46
|
+
})
|
|
47
47
|
});
|
|
48
48
|
expect(response).toBeInstanceOf(SummaryModel);
|
|
49
49
|
expect(response).toEqual(new SummaryModel(testSummary));
|
|
@@ -78,11 +78,11 @@ describe('Storefront API Summary', () => {
|
|
|
78
78
|
|
|
79
79
|
expect(instance.storefront.purchase.preview).toBeCalledTimes(1);
|
|
80
80
|
expect(instance.storefront.purchase.preview).toBeCalledWith({
|
|
81
|
-
data: {
|
|
81
|
+
data: expect.objectContaining({
|
|
82
82
|
items: options.items,
|
|
83
83
|
websiteId: options.websiteId,
|
|
84
84
|
billingAddress
|
|
85
|
-
}
|
|
85
|
+
})
|
|
86
86
|
});
|
|
87
87
|
});
|
|
88
88
|
|
|
@@ -115,11 +115,11 @@ describe('Storefront API Summary', () => {
|
|
|
115
115
|
|
|
116
116
|
expect(instance.storefront.purchase.preview).toBeCalledTimes(1);
|
|
117
117
|
expect(instance.storefront.purchase.preview).toBeCalledWith({
|
|
118
|
-
data: {
|
|
118
|
+
data: expect.objectContaining({
|
|
119
119
|
items: options.items,
|
|
120
120
|
websiteId: options.websiteId,
|
|
121
121
|
deliveryAddress
|
|
122
|
-
}
|
|
122
|
+
})
|
|
123
123
|
});
|
|
124
124
|
});
|
|
125
125
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import camelCase from 'lodash.camelcase';
|
|
2
|
+
import Events from '../../../../events';
|
|
3
|
+
|
|
4
|
+
export function dispatchEventHandler(iframe) {
|
|
5
|
+
iframe.component.on(`${iframe.name}-dispatch`, ({ event, detail }) => {
|
|
6
|
+
Events[camelCase(event).replace(/-/, '')].dispatch(detail);
|
|
7
|
+
});
|
|
8
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function stopLoaderHandler(iframe, data) {
|
|
2
|
+
iframe.component.on(`${iframe.name}-stop-loading`, (id) => {
|
|
3
|
+
let {section} = data;
|
|
4
|
+
if (!section) {
|
|
5
|
+
section = id.includes('summary') ? 'summary' : 'form';
|
|
6
|
+
}
|
|
7
|
+
data.loader?.stopLoading({ section, id });
|
|
8
|
+
});
|
|
9
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function updateCouponsHandler(iframe) {
|
|
2
|
+
iframe.component.on(`${iframe.name}-update-coupon`, async ({
|
|
3
|
+
couponIds,
|
|
4
|
+
previewPurchase
|
|
5
|
+
} = {}) => {
|
|
6
|
+
iframe.state.data.couponIds = couponIds;
|
|
7
|
+
iframe.state.data.previewPurchase = previewPurchase;
|
|
8
|
+
|
|
9
|
+
const updateModel = {
|
|
10
|
+
data: iframe.state.data.toPostmatesModel(),
|
|
11
|
+
options: iframe.state.options
|
|
12
|
+
}
|
|
13
|
+
if (iframe.state.iframeComponents.summary) {
|
|
14
|
+
iframe.state.iframeComponents.summary.component.call('update', updateModel);
|
|
15
|
+
}
|
|
16
|
+
iframe.state.iframeComponents.form.component.call('update', updateModel);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import BaseIframe from './base-iframe';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from './event-listeners';
|
|
2
|
+
|
|
3
|
+
import { changeIframeSrcHandler } from './events/change-iframe-src-handler';
|
|
4
|
+
import { resizeComponentHandler } from './events/resize-component-handler';
|
|
5
|
+
import { dispatchEventHandler } from './events/dispatch-event-handler';
|
|
6
|
+
import { showErrorHandler } from './events/show-error-handler';
|
|
7
|
+
import { stopLoaderHandler } from './events/stop-loader-handler';
|
|
9
8
|
|
|
10
9
|
export class ModalIframe extends BaseIframe {
|
|
11
10
|
constructor(args = {}) {
|
|
@@ -13,7 +12,7 @@ export class ModalIframe extends BaseIframe {
|
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
bindEventListeners({ close = () => {}, loader } = {}) {
|
|
16
|
-
|
|
15
|
+
dispatchEventHandler(this);
|
|
17
16
|
resizeComponentHandler(this);
|
|
18
17
|
changeIframeSrcHandler(this);
|
|
19
18
|
stopLoaderHandler(this, {
|
|
@@ -28,7 +27,7 @@ export class ModalIframe extends BaseIframe {
|
|
|
28
27
|
close(...args);
|
|
29
28
|
});
|
|
30
29
|
|
|
31
|
-
// Close modal via postMessage (specifically during
|
|
30
|
+
// Close modal via postMessage (specifically during approval url flow)
|
|
32
31
|
window.addEventListener('message', async (event) => {
|
|
33
32
|
if(event.data === 'rebilly-instruments-approval-url-close') {
|
|
34
33
|
if (this.state.options.transactionType === 'purchase') {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import BaseIframe from './base-iframe';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from './
|
|
2
|
+
|
|
3
|
+
import { resizeComponentHandler } from './events/resize-component-handler';
|
|
4
|
+
import { dispatchEventHandler } from './events/dispatch-event-handler';
|
|
5
|
+
import { updateCouponsHandler } from './events/update-coupons-handler';
|
|
6
|
+
import { showErrorHandler } from './events/show-error-handler';
|
|
7
|
+
import { stopLoaderHandler } from './events/stop-loader-handler';
|
|
8
8
|
|
|
9
9
|
export class ViewIframe extends BaseIframe {
|
|
10
10
|
constructor(args = {}) {
|
|
@@ -12,9 +12,10 @@ export class ViewIframe extends BaseIframe {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
bindEventListeners({ loader } = {}) {
|
|
15
|
-
|
|
15
|
+
dispatchEventHandler(this);
|
|
16
16
|
resizeComponentHandler(this);
|
|
17
17
|
stopLoaderHandler(this, { loader });
|
|
18
18
|
showErrorHandler(this);
|
|
19
|
+
updateCouponsHandler(this);
|
|
19
20
|
}
|
|
20
21
|
}
|
package/src/views/result.js
CHANGED
package/src/views/summary.js
CHANGED
|
@@ -10,6 +10,7 @@ export async function mountSummary({ state }) {
|
|
|
10
10
|
const { paymentMethodsUrl } = state.options._computed;
|
|
11
11
|
|
|
12
12
|
const iframe = await new ViewIframe({
|
|
13
|
+
state,
|
|
13
14
|
name: 'rebilly-instruments-summary',
|
|
14
15
|
url: `${paymentMethodsUrl}/summary`,
|
|
15
16
|
container: state.summary,
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import camelCase from 'lodash.camelcase';
|
|
2
|
-
import Events from '../../../events';
|
|
3
|
-
import { showError } from '../../errors';
|
|
4
|
-
|
|
5
|
-
export function dispatchRebillyInsturmentEventHandler(iframe) {
|
|
6
|
-
iframe.component.on(`${iframe.name}-dispatch`, ({ event, detail }) => {
|
|
7
|
-
Events[camelCase(event).replace(/-/, '')].dispatch(detail);
|
|
8
|
-
});
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function resizeComponentHandler(iframe) {
|
|
12
|
-
let prevHeight = '';
|
|
13
|
-
iframe.component.on(`${iframe.name}-resize-frame`, (height) => {
|
|
14
|
-
if (height !== prevHeight) {
|
|
15
|
-
prevHeight = height;
|
|
16
|
-
iframe.component.frame.style.height = height;
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function stopLoaderHandler(iframe, data) {
|
|
22
|
-
iframe.component.on(`${iframe.name}-stop-loading`, (id) => {
|
|
23
|
-
let {section} = data;
|
|
24
|
-
if (!section) {
|
|
25
|
-
section = id.includes('summary') ? 'summary' : 'form';
|
|
26
|
-
}
|
|
27
|
-
data.loader?.stopLoading({ section, id });
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function changeIframeSrcHandler(iframe) {
|
|
32
|
-
iframe.component.on(`${iframe.name}-change-iframe-src`, (url = null) => {
|
|
33
|
-
iframe.component.frame.src = url;
|
|
34
|
-
iframe.component.frame.style.height = '75vh';
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function displayOverlay(iframe) {
|
|
39
|
-
iframe.component.on(`${iframe.name}-change-overlay`, (showOverlay = true) => {
|
|
40
|
-
if (showOverlay) {
|
|
41
|
-
iframe.component.frame.classList.add('rebilly-instruments-iframe-overlay');
|
|
42
|
-
} else {
|
|
43
|
-
iframe.component.frame.classList.remove('rebilly-instruments-iframe-overlay');
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function showErrorHandler(iframe) {
|
|
49
|
-
iframe.component.on(`${iframe.name}-show-error`, showError);
|
|
50
|
-
}
|