@rebilly/instruments 3.15.6-beta.0 → 3.16.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/.eslintrc.js +7 -0
- package/dist/index.js +10 -10
- package/dist/index.min.js +10 -10
- package/package.json +6 -4
- package/service/prefetch/config.mjs +8 -0
- package/service/prefetch/metadata.mjs +35 -0
- package/service/prefetch/prefetch.mjs +9 -0
- package/src/data/payment-methods.json +2886 -0
- package/src/functions/mount/fetch-data.js +2 -8
- package/src/functions/mount/mount.spec.js +1 -1
- package/src/functions/mount/setup-options.js +31 -19
- package/src/functions/mount/setup-options.spec.js +66 -1
- package/src/functions/purchase.js +18 -8
- package/src/functions/purchase.spec.js +4 -1
- package/src/storefront/ready-to-pay.js +2 -2
- package/src/storefront/ready-to-pay.spec.js +6 -1
- package/src/storefront/summary.js +9 -0
- package/src/storefront/summary.spec.js +6 -6
- package/src/views/common/iframe/base-iframe.js +0 -1
- 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/get-payment-methods.js +1 -1
- 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
|
@@ -21,6 +21,7 @@ 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() {
|
|
@@ -139,11 +140,6 @@ export async function fetchData({
|
|
|
139
140
|
availableInstrumentsPromise = fetchInstruments({state});
|
|
140
141
|
}
|
|
141
142
|
|
|
142
|
-
const paymentMethodsMetadataPromise =
|
|
143
|
-
state.storefront.rebilly.paymentMethods.getAll().then(
|
|
144
|
-
({ items }) => items.map(({fields}) => fields)
|
|
145
|
-
);
|
|
146
|
-
|
|
147
143
|
if (state.options?.transactionId) {
|
|
148
144
|
state.data.transaction = await fetchTransaction({data: {
|
|
149
145
|
id: state.options.transactionId
|
|
@@ -162,9 +158,7 @@ export async function fetchData({
|
|
|
162
158
|
}
|
|
163
159
|
|
|
164
160
|
const readyToPayPromise = state.data?.readyToPay ??
|
|
165
|
-
accountPromise.then(() => fetchReadyToPay({
|
|
166
|
-
riskMetadata, state, paymentMethodsMetadataPromise
|
|
167
|
-
}));
|
|
161
|
+
accountPromise.then(() => fetchReadyToPay({riskMetadata, state}));
|
|
168
162
|
|
|
169
163
|
const previewPurchasePromise = state.options.items ?
|
|
170
164
|
fetchSummary({ state }) : null;
|
|
@@ -37,7 +37,7 @@ describe('RebillyInstruments instance', () => {
|
|
|
37
37
|
|
|
38
38
|
// Mounts form and summary
|
|
39
39
|
const summarySelector = document.querySelector('.summary-selector');
|
|
40
|
-
expect(summarySelector.innerHTML).toContain('<iframe name="rebilly-instruments-summary" class="rebilly-instruments-iframe" loading="lazy" allow="payment"
|
|
40
|
+
expect(summarySelector.innerHTML).toContain('<iframe name="rebilly-instruments-summary" class="rebilly-instruments-iframe" loading="lazy" allow="payment" src="https://forms.local.rebilly.dev:3000/summary"></iframe>');
|
|
41
41
|
|
|
42
42
|
// Theme config overrides initial styles
|
|
43
43
|
const STYLE_VARS = document.querySelectorAll('style[type="text/css"]')[0];
|
|
@@ -40,10 +40,20 @@ export const defaults = {
|
|
|
40
40
|
transactionType: 'purchase',
|
|
41
41
|
features: {
|
|
42
42
|
autoConfirmation: true,
|
|
43
|
-
autoResult: true
|
|
43
|
+
autoResult: true,
|
|
44
|
+
showCoupons: null,
|
|
44
45
|
}
|
|
45
46
|
};
|
|
46
47
|
|
|
48
|
+
export function sanitizeOptions(options) {
|
|
49
|
+
// TODO: Additional sanitization
|
|
50
|
+
|
|
51
|
+
// cast options to be only json object
|
|
52
|
+
return JSON.parse(
|
|
53
|
+
JSON.stringify(options)
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
47
57
|
export function validateOptions(options) {
|
|
48
58
|
// TODO: validate more options
|
|
49
59
|
const purchaseData = [
|
|
@@ -71,37 +81,39 @@ export default ({
|
|
|
71
81
|
options = {}
|
|
72
82
|
} = {}) => {
|
|
73
83
|
|
|
74
|
-
|
|
84
|
+
const sanitizedOptions = sanitizeOptions(options)
|
|
85
|
+
|
|
86
|
+
validateOptions(sanitizedOptions);
|
|
75
87
|
|
|
76
88
|
const _computed = {
|
|
77
|
-
paymentMethodsUrl:
|
|
78
|
-
?
|
|
89
|
+
paymentMethodsUrl: sanitizedOptions._dev
|
|
90
|
+
? sanitizedOptions._dev.paymentMethodsUrl || 'https://forms.local.rebilly.dev:3000'
|
|
79
91
|
: 'https://forms.secure-payments.app'
|
|
80
92
|
};
|
|
81
93
|
|
|
82
94
|
const combinedOptions = merge({...defaults}, {
|
|
83
|
-
apiMode:
|
|
84
|
-
i18n:
|
|
85
|
-
theme:
|
|
86
|
-
css:
|
|
87
|
-
locale:
|
|
88
|
-
countryCode:
|
|
89
|
-
features:
|
|
90
|
-
paymentInstruments:
|
|
91
|
-
transactionType:
|
|
95
|
+
apiMode: sanitizedOptions.apiMode,
|
|
96
|
+
i18n: sanitizedOptions.i18n,
|
|
97
|
+
theme: sanitizedOptions.theme,
|
|
98
|
+
css: sanitizedOptions.css,
|
|
99
|
+
locale: sanitizedOptions.locale,
|
|
100
|
+
countryCode: sanitizedOptions.countryCode,
|
|
101
|
+
features: sanitizedOptions.features,
|
|
102
|
+
paymentInstruments: sanitizedOptions.paymentInstruments,
|
|
103
|
+
transactionType: sanitizedOptions.transactionType,
|
|
92
104
|
_computed
|
|
93
105
|
});
|
|
94
106
|
|
|
95
|
-
if (
|
|
107
|
+
if (sanitizedOptions.publishableKey) {
|
|
96
108
|
Object.entries({
|
|
97
|
-
organizationId:
|
|
98
|
-
publishableKey:
|
|
99
|
-
websiteId:
|
|
109
|
+
organizationId: sanitizedOptions.organizationId,
|
|
110
|
+
publishableKey: sanitizedOptions.publishableKey,
|
|
111
|
+
websiteId: sanitizedOptions.websiteId,
|
|
100
112
|
}).forEach(([key, value]) => {
|
|
101
113
|
combinedOptions[key] = value;
|
|
102
114
|
});
|
|
103
|
-
} else if (
|
|
104
|
-
combinedOptions.jwt =
|
|
115
|
+
} else if (sanitizedOptions.jwt) {
|
|
116
|
+
combinedOptions.jwt = sanitizedOptions.jwt;
|
|
105
117
|
const {
|
|
106
118
|
merchant: organizationId,
|
|
107
119
|
claims: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RenderMockRebillyInstruments } from 'tests/mocks/rebilly-instruments-mock';
|
|
2
|
-
import setupOptions, {validateOptions, defaults} from './setup-options';
|
|
2
|
+
import setupOptions, {validateOptions, defaults, sanitizeOptions} from './setup-options';
|
|
3
3
|
|
|
4
4
|
describe('Setup mount options', () => {
|
|
5
5
|
it("should fill with default options", () => {
|
|
@@ -56,4 +56,69 @@ describe('Validate mount options', () => {
|
|
|
56
56
|
}
|
|
57
57
|
expect(error.message).toBe('Must provide only one purchase data type');
|
|
58
58
|
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('sanitize mount options', () => {
|
|
62
|
+
it('should make into object', () => {
|
|
63
|
+
class options {
|
|
64
|
+
constructor() {
|
|
65
|
+
this.items = [
|
|
66
|
+
{
|
|
67
|
+
planId: "test-plan-id",
|
|
68
|
+
quantity: 1
|
|
69
|
+
}
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
expect(setupOptions({
|
|
75
|
+
options: new options()
|
|
76
|
+
})).toMatchObject(defaults);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should merge class and default object', () => {
|
|
80
|
+
class options {
|
|
81
|
+
constructor() {
|
|
82
|
+
this.items = [
|
|
83
|
+
{
|
|
84
|
+
planId: "test-plan-id",
|
|
85
|
+
quantity: 1
|
|
86
|
+
}
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
this.features = {
|
|
90
|
+
showCoupons: ['summary'],
|
|
91
|
+
other: 'key'
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
expect(setupOptions({
|
|
97
|
+
options: new options()
|
|
98
|
+
})).toMatchObject(
|
|
99
|
+
expect.objectContaining({
|
|
100
|
+
features: expect.objectContaining({
|
|
101
|
+
...defaults.features,
|
|
102
|
+
showCoupons: ['summary'],
|
|
103
|
+
other: 'key'
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it ('should sanitize class to object', () => {
|
|
110
|
+
class OptionsClass {
|
|
111
|
+
constructor() {
|
|
112
|
+
this.key = "value"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const newOptions = new OptionsClass();
|
|
117
|
+
|
|
118
|
+
expect(sanitizeOptions(newOptions)).toMatchObject({
|
|
119
|
+
key: 'value'
|
|
120
|
+
});
|
|
121
|
+
expect(sanitizeOptions(newOptions)).toBeInstanceOf(Object);
|
|
122
|
+
expect(sanitizeOptions(newOptions)).not.toBeInstanceOf(OptionsClass);
|
|
123
|
+
})
|
|
59
124
|
});
|
|
@@ -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
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { collectData } from '@rebilly/risk-data-collector';
|
|
2
|
+
import paymentMethodsFile from '../data/payment-methods.json';
|
|
2
3
|
import ReadyToPayModel from './models/ready-to-pay-model';
|
|
3
4
|
import { Endpoint } from './index';
|
|
4
5
|
|
|
5
6
|
export async function fetchReadyToPay({
|
|
6
7
|
state,
|
|
7
8
|
riskMetadata = null,
|
|
8
|
-
paymentMethodsMetadataPromise = Promise.resolve([])
|
|
9
9
|
}) {
|
|
10
10
|
return Endpoint({state}, async () => {
|
|
11
11
|
if (!riskMetadata) {
|
|
@@ -42,7 +42,7 @@ export async function fetchReadyToPay({
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
const { fields: readyToPayFields } = await state.storefront.purchase.readyToPay({ data });
|
|
45
|
-
const paymentMethodsMetadata =
|
|
45
|
+
const paymentMethodsMetadata = [...paymentMethodsFile];
|
|
46
46
|
|
|
47
47
|
return Object.values(readyToPayFields)
|
|
48
48
|
// Remove result for "old" paypal method
|
|
@@ -5,6 +5,8 @@ import { storefrontURL } from 'tests/mocks/storefront-api-mock';
|
|
|
5
5
|
import { fetchReadyToPay } from './ready-to-pay';
|
|
6
6
|
import ReadyToPayModel from './models/ready-to-pay-model';
|
|
7
7
|
import { expectConfigurationError } from 'tests/async-utilities';
|
|
8
|
+
import PaymentMetadataModel from './models/payment-metadata';
|
|
9
|
+
import paymentMethodsFile from '@/data/payment-methods.json';
|
|
8
10
|
|
|
9
11
|
describe('Storefront API Ready to Pay', () => {
|
|
10
12
|
it('can fetch ready to pay', async () => {
|
|
@@ -26,6 +28,8 @@ describe('Storefront API Ready to Pay', () => {
|
|
|
26
28
|
]
|
|
27
29
|
};
|
|
28
30
|
|
|
31
|
+
const paymentCardMetadata = [...paymentMethodsFile].find(method => method.apiName === 'payment-card');
|
|
32
|
+
|
|
29
33
|
when(post(`${storefrontURL}/ready-to-pay`)).thenReturn(
|
|
30
34
|
ok(readyToPayPayload)
|
|
31
35
|
);
|
|
@@ -52,7 +56,8 @@ describe('Storefront API Ready to Pay', () => {
|
|
|
52
56
|
expect(response).toEqual([
|
|
53
57
|
new ReadyToPayModel({
|
|
54
58
|
index: 0,
|
|
55
|
-
...readyToPayPayload[0]
|
|
59
|
+
...readyToPayPayload[0],
|
|
60
|
+
metadata: new PaymentMetadataModel(paymentCardMetadata),
|
|
56
61
|
})
|
|
57
62
|
]);
|
|
58
63
|
});
|
|
@@ -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
|
|
|
@@ -45,7 +45,6 @@ export default class BaseIframe {
|
|
|
45
45
|
appendChild: (iframe) => {
|
|
46
46
|
iframe.setAttribute('loading', 'lazy');
|
|
47
47
|
iframe.setAttribute('allow', 'payment');
|
|
48
|
-
iframe.setAttribute('scrolling', 'no');
|
|
49
48
|
iframe.allowPaymentRequest = true;
|
|
50
49
|
this.container.appendChild(iframe);
|
|
51
50
|
},
|
|
@@ -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
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const SUPPORTED_EXPRESS_METHODS = ['Google Pay', 'Apple Pay', 'paypal'];
|
|
2
2
|
|
|
3
|
-
export const SUPPORTED_METHODS = ['payment-card', 'ach'];
|
|
3
|
+
export const SUPPORTED_METHODS = ['payment-card', 'ach', 'cryptocurrency'];
|
|
4
4
|
|
|
5
5
|
const isExpressMethod = ({ method, feature }) => (
|
|
6
6
|
SUPPORTED_EXPRESS_METHODS.includes(method) ||
|
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
|
-
}
|