@medipass/checkout-sdk 2.1.0 → 3.0.0-alpha.1
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 +40 -0
- package/CONTRIBUTING.md +21 -0
- package/{lib/style.css → dist/cjs/assets/index-e17dd0fd.css} +1 -1
- package/dist/cjs/constants.d.ts +27 -0
- package/dist/cjs/index.d.ts +32 -0
- package/dist/cjs/index.js +9 -0
- package/dist/cjs/initialiseWindow.d.ts +4 -0
- package/dist/cjs/overlay.d.ts +21 -0
- package/dist/cjs/requestUpdatePaymentDetails.d.ts +21 -0
- package/dist/cjs/updatePaymentOverlay.d.ts +21 -0
- package/dist/cjs/utils/object-to-css.d.ts +2 -0
- package/dist/esm/assets/index-e17dd0fd.css +1 -0
- package/dist/esm/constants.d.ts +27 -0
- package/dist/esm/index.d.ts +32 -0
- package/dist/esm/index.js +9 -0
- package/dist/esm/initialiseWindow.d.ts +4 -0
- package/dist/esm/overlay.d.ts +21 -0
- package/dist/esm/requestUpdatePaymentDetails.d.ts +21 -0
- package/dist/esm/updatePaymentOverlay.d.ts +21 -0
- package/dist/esm/utils/object-to-css.d.ts +2 -0
- package/dist/umd/assets/index.min-e17dd0fd.css +1 -0
- package/dist/umd/constants.d.ts +27 -0
- package/dist/umd/index.d.ts +32 -0
- package/dist/umd/index.min.js +17 -0
- package/dist/umd/initialiseWindow.d.ts +4 -0
- package/dist/umd/overlay.d.ts +21 -0
- package/dist/umd/requestUpdatePaymentDetails.d.ts +21 -0
- package/dist/umd/updatePaymentOverlay.d.ts +21 -0
- package/dist/umd/utils/object-to-css.d.ts +2 -0
- package/package.json +33 -15
- package/rollup.config.mjs +35 -0
- package/src/constants.ts +31 -0
- package/src/index.ts +244 -0
- package/src/initialiseWindow.ts +46 -0
- package/src/overlay.ts +272 -0
- package/src/requestUpdatePaymentDetails.ts +190 -0
- package/{es → src}/style.css +1 -1
- package/src/updatePaymentOverlay.ts +247 -0
- package/{es/utils/object-to-css.js → src/utils/object-to-css.ts} +4 -2
- package/tsconfig.json +32 -0
- package/es/constants.js +0 -23
- package/es/index.js +0 -264
- package/es/initialiseWindow.js +0 -34
- package/es/overlay.js +0 -184
- package/es/requestUpdatePaymentDetails.js +0 -232
- package/es/updatePaymentOverlay.js +0 -184
- package/lib/constants.js +0 -33
- package/lib/index.js +0 -280
- package/lib/initialiseWindow.js +0 -42
- package/lib/overlay.js +0 -196
- package/lib/requestUpdatePaymentDetails.js +0 -244
- package/lib/updatePaymentOverlay.js +0 -196
- package/lib/utils/object-to-css.js +0 -11
- package/umd/checkout-sdk.js +0 -50414
- package/umd/checkout-sdk.min.js +0 -31
- package/umd/checkout-sdk.min.js.map +0 -1
- package/umd/main.3a4213e0.css +0 -2
- package/umd/main.3a4213e0.css.map +0 -1
package/src/overlay.ts
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { ROOT_ELEMENT_ID } from './constants';
|
|
2
|
+
import toCss from './utils/object-to-css';
|
|
3
|
+
import _get from 'lodash/get';
|
|
4
|
+
|
|
5
|
+
const SUBHEADING_ELEMENT_ID = 'medipass-checkout-sdk-subheading';
|
|
6
|
+
|
|
7
|
+
function createElement({
|
|
8
|
+
window,
|
|
9
|
+
element,
|
|
10
|
+
text,
|
|
11
|
+
id,
|
|
12
|
+
styles,
|
|
13
|
+
onClick,
|
|
14
|
+
}: {
|
|
15
|
+
window: Window;
|
|
16
|
+
element: string;
|
|
17
|
+
text?: string;
|
|
18
|
+
id?: string;
|
|
19
|
+
styles?: Record<string, string>;
|
|
20
|
+
onClick?: () => void;
|
|
21
|
+
}) {
|
|
22
|
+
if (!window) return null;
|
|
23
|
+
|
|
24
|
+
const newElement = window.document.createElement(element);
|
|
25
|
+
|
|
26
|
+
if (text) {
|
|
27
|
+
newElement.innerHTML = text;
|
|
28
|
+
}
|
|
29
|
+
if (id) {
|
|
30
|
+
newElement.id = id;
|
|
31
|
+
}
|
|
32
|
+
if (styles) {
|
|
33
|
+
newElement.style.cssText = toCss(styles);
|
|
34
|
+
}
|
|
35
|
+
if (_get(newElement, 'addEventListener') && onClick) {
|
|
36
|
+
newElement.addEventListener('click', () => {
|
|
37
|
+
onClick();
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return newElement;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface Overlay {
|
|
45
|
+
contentElement: HTMLElement | null;
|
|
46
|
+
removeOverlay: () => void;
|
|
47
|
+
createOverlay: ({
|
|
48
|
+
window,
|
|
49
|
+
onClickRelaunch,
|
|
50
|
+
onClickCancel,
|
|
51
|
+
}: {
|
|
52
|
+
window: Window;
|
|
53
|
+
onClickRelaunch: () => void;
|
|
54
|
+
onClickCancel: () => void;
|
|
55
|
+
}) => void;
|
|
56
|
+
createSubHeading: ({
|
|
57
|
+
window,
|
|
58
|
+
onClickRelaunch,
|
|
59
|
+
onClickCancel,
|
|
60
|
+
}: {
|
|
61
|
+
window: Window;
|
|
62
|
+
onClickRelaunch: () => void;
|
|
63
|
+
onClickCancel: () => void;
|
|
64
|
+
}) => HTMLElement | null;
|
|
65
|
+
updateSubHeading: ({
|
|
66
|
+
window,
|
|
67
|
+
onClickRelaunch,
|
|
68
|
+
onClickCancel,
|
|
69
|
+
}: {
|
|
70
|
+
window: Window;
|
|
71
|
+
onClickRelaunch: () => void;
|
|
72
|
+
onClickCancel: () => void;
|
|
73
|
+
}) => void;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const overlay: Overlay = {
|
|
77
|
+
contentElement: null,
|
|
78
|
+
|
|
79
|
+
removeOverlay() {
|
|
80
|
+
const containerDiv = document.getElementById(ROOT_ELEMENT_ID);
|
|
81
|
+
if (!containerDiv) return;
|
|
82
|
+
containerDiv.remove();
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
createOverlay({
|
|
86
|
+
window,
|
|
87
|
+
onClickRelaunch,
|
|
88
|
+
onClickCancel,
|
|
89
|
+
}: {
|
|
90
|
+
window: Window;
|
|
91
|
+
onClickRelaunch: () => void;
|
|
92
|
+
onClickCancel: () => void;
|
|
93
|
+
}) {
|
|
94
|
+
if (!window) return;
|
|
95
|
+
|
|
96
|
+
const containerDiv = createElement({
|
|
97
|
+
window,
|
|
98
|
+
element: 'div',
|
|
99
|
+
id: ROOT_ELEMENT_ID,
|
|
100
|
+
styles: {
|
|
101
|
+
'z-index': '2147483100',
|
|
102
|
+
position: 'fixed',
|
|
103
|
+
top: '0',
|
|
104
|
+
left: '0',
|
|
105
|
+
width: '100%',
|
|
106
|
+
height: '100%',
|
|
107
|
+
'background-color': 'rgba(0, 0, 0, 0.8)',
|
|
108
|
+
'font-family': 'Lato',
|
|
109
|
+
color: 'white',
|
|
110
|
+
display: 'flex',
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const content = createElement({
|
|
115
|
+
window,
|
|
116
|
+
element: 'div',
|
|
117
|
+
styles: {
|
|
118
|
+
'max-width': '360px',
|
|
119
|
+
'margin-left': 'auto',
|
|
120
|
+
'margin-right': 'auto',
|
|
121
|
+
'margin-top': 'auto',
|
|
122
|
+
'margin-bottom': 'auto',
|
|
123
|
+
'text-align': 'center',
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
this.contentElement = content;
|
|
128
|
+
|
|
129
|
+
////////////////////////////////////////////////////////////
|
|
130
|
+
|
|
131
|
+
const heading = createElement({
|
|
132
|
+
window,
|
|
133
|
+
element: 'div',
|
|
134
|
+
text: 'Secure Medipass payment in progress',
|
|
135
|
+
styles: {
|
|
136
|
+
color: 'white',
|
|
137
|
+
'font-size': '35px',
|
|
138
|
+
'font-weight': '600',
|
|
139
|
+
'margin-bottom': '30px',
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
////////////////////////////////////////////////////////////
|
|
144
|
+
|
|
145
|
+
const subHeading = this.createSubHeading({ window, onClickRelaunch, onClickCancel });
|
|
146
|
+
|
|
147
|
+
////////////////////////////////////////////////////////////
|
|
148
|
+
|
|
149
|
+
if (!content) return;
|
|
150
|
+
if (!containerDiv) return;
|
|
151
|
+
|
|
152
|
+
if (heading) {
|
|
153
|
+
content.appendChild(heading);
|
|
154
|
+
}
|
|
155
|
+
if (subHeading) {
|
|
156
|
+
content.appendChild(subHeading);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
containerDiv.appendChild(content);
|
|
160
|
+
|
|
161
|
+
////////////////////////////////////////////////////////////
|
|
162
|
+
|
|
163
|
+
window.document.body.appendChild(containerDiv);
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
createSubHeading({
|
|
167
|
+
window,
|
|
168
|
+
onClickRelaunch,
|
|
169
|
+
onClickCancel,
|
|
170
|
+
}: {
|
|
171
|
+
window: Window;
|
|
172
|
+
onClickRelaunch: () => void;
|
|
173
|
+
onClickCancel: () => void;
|
|
174
|
+
}) {
|
|
175
|
+
if (!window) return null;
|
|
176
|
+
|
|
177
|
+
const subHeadingContainer = createElement({
|
|
178
|
+
window,
|
|
179
|
+
id: SUBHEADING_ELEMENT_ID,
|
|
180
|
+
element: 'div',
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const subHeading1 = createElement({
|
|
184
|
+
window,
|
|
185
|
+
element: 'div',
|
|
186
|
+
text: "Don't see the payment window?",
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const link1 = createElement({
|
|
190
|
+
window,
|
|
191
|
+
element: 'a',
|
|
192
|
+
text: 'Click here',
|
|
193
|
+
onClick: onClickRelaunch,
|
|
194
|
+
styles: {
|
|
195
|
+
'text-decoration': 'underline',
|
|
196
|
+
cursor: 'pointer',
|
|
197
|
+
'font-weight': '600',
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
const subHeading2 = createElement({
|
|
201
|
+
window,
|
|
202
|
+
element: 'span',
|
|
203
|
+
text: ' to relaunch and complete your payment.',
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const subHeading3 = createElement({
|
|
207
|
+
window,
|
|
208
|
+
element: 'div',
|
|
209
|
+
text: 'OR',
|
|
210
|
+
styles: {
|
|
211
|
+
'margin-top': '20px',
|
|
212
|
+
'margin-bottom': '20px',
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
const link2 = createElement({
|
|
217
|
+
window,
|
|
218
|
+
element: 'a',
|
|
219
|
+
text: 'Click here to cancel the payment.',
|
|
220
|
+
onClick: onClickCancel,
|
|
221
|
+
styles: {
|
|
222
|
+
'text-decoration': 'underline',
|
|
223
|
+
cursor: 'pointer',
|
|
224
|
+
'font-weight': '600',
|
|
225
|
+
},
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
if (!subHeadingContainer) return null;
|
|
229
|
+
|
|
230
|
+
if (subHeading1) {
|
|
231
|
+
subHeadingContainer.appendChild(subHeading1);
|
|
232
|
+
}
|
|
233
|
+
if (link1) {
|
|
234
|
+
subHeadingContainer.appendChild(link1);
|
|
235
|
+
}
|
|
236
|
+
if (subHeading2) {
|
|
237
|
+
subHeadingContainer.appendChild(subHeading2);
|
|
238
|
+
}
|
|
239
|
+
if (subHeading3) {
|
|
240
|
+
subHeadingContainer.appendChild(subHeading3);
|
|
241
|
+
}
|
|
242
|
+
if (link2) {
|
|
243
|
+
subHeadingContainer.appendChild(link2);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return subHeadingContainer;
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
updateSubHeading({
|
|
250
|
+
window,
|
|
251
|
+
onClickRelaunch,
|
|
252
|
+
onClickCancel,
|
|
253
|
+
}: {
|
|
254
|
+
window: Window;
|
|
255
|
+
onClickRelaunch: () => void;
|
|
256
|
+
onClickCancel: () => void;
|
|
257
|
+
}) {
|
|
258
|
+
if (!window) return null;
|
|
259
|
+
|
|
260
|
+
const subheaderElement = document.getElementById(SUBHEADING_ELEMENT_ID);
|
|
261
|
+
if (subheaderElement) {
|
|
262
|
+
subheaderElement.remove();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const newSubheading = this.createSubHeading({ window, onClickRelaunch, onClickCancel });
|
|
266
|
+
if (this.contentElement && this?.contentElement?.appendChild && newSubheading) {
|
|
267
|
+
this.contentElement.appendChild(newSubheading);
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
export default overlay;
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import _get from 'lodash/get';
|
|
2
|
+
import updatePaymentOverlay from './updatePaymentOverlay';
|
|
3
|
+
import { ENVS, EVENTS, ERROR_MESSAGES, ORIGINS } from './constants';
|
|
4
|
+
import coreSDK from '@medipass/web-sdk';
|
|
5
|
+
import initialiseWindow from './initialiseWindow';
|
|
6
|
+
|
|
7
|
+
if (!coreSDK.hasInit) {
|
|
8
|
+
coreSDK.setup();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface UpdatePaymentDetailsBase {
|
|
12
|
+
patientRefId: string;
|
|
13
|
+
env: typeof ENVS[keyof typeof ENVS];
|
|
14
|
+
onSuccess: () => void;
|
|
15
|
+
onFailure: () => void;
|
|
16
|
+
onCancel: () => void;
|
|
17
|
+
onClose: () => void;
|
|
18
|
+
callbackOrigin: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface UpdatePaymentDetailsWithApiKey extends UpdatePaymentDetailsBase {
|
|
22
|
+
apiKey: string;
|
|
23
|
+
token?: never;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface UpdatePaymentDetailsWithToken extends UpdatePaymentDetailsBase {
|
|
27
|
+
token: string;
|
|
28
|
+
apiKey?: never;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type UpdatePaymentDetails = UpdatePaymentDetailsWithApiKey | UpdatePaymentDetailsWithToken;
|
|
32
|
+
|
|
33
|
+
const updatePaymentDetails = async ({
|
|
34
|
+
apiKey,
|
|
35
|
+
token,
|
|
36
|
+
patientRefId,
|
|
37
|
+
env,
|
|
38
|
+
onSuccess,
|
|
39
|
+
onFailure,
|
|
40
|
+
onCancel,
|
|
41
|
+
onClose,
|
|
42
|
+
callbackOrigin,
|
|
43
|
+
}: UpdatePaymentDetails) => {
|
|
44
|
+
if (!apiKey && !token) throw new Error(ERROR_MESSAGES.NO_API_KEY_OR_NO_TOKEN);
|
|
45
|
+
if (!patientRefId) throw new Error(ERROR_MESSAGES.NO_PATIENT_REF_ID);
|
|
46
|
+
if (!env) throw new Error(ERROR_MESSAGES.NO_ENVIROMENT_SET);
|
|
47
|
+
if (!callbackOrigin) throw new Error(ERROR_MESSAGES.NO_CALLBACK_ORIGIN);
|
|
48
|
+
|
|
49
|
+
let isSessionComplete = false;
|
|
50
|
+
const sdkConfig: { env: typeof ENVS[keyof typeof ENVS] | 'staging' } = { env };
|
|
51
|
+
if (env === ENVS.LOCAL) {
|
|
52
|
+
sdkConfig.env = ENVS.DEV;
|
|
53
|
+
}
|
|
54
|
+
if (env === ENVS.STG) {
|
|
55
|
+
sdkConfig.env = 'staging';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Set Medipass web-sdk config
|
|
59
|
+
coreSDK.setConfig(sdkConfig);
|
|
60
|
+
|
|
61
|
+
if (apiKey || token) {
|
|
62
|
+
coreSDK.setToken(`Bearer ${apiKey || token}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let windowReferenceObject = initialiseWindow({ url: '' });
|
|
66
|
+
|
|
67
|
+
const handleClose = () => {
|
|
68
|
+
updatePaymentOverlay.removeOverlay();
|
|
69
|
+
|
|
70
|
+
if (!isSessionComplete) {
|
|
71
|
+
onClose && onClose();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!windowReferenceObject) return;
|
|
75
|
+
windowReferenceObject.close();
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const onClickRelaunch = () => {
|
|
79
|
+
if (!windowReferenceObject) {
|
|
80
|
+
windowReferenceObject = initialiseWindow({ url: '' });
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
windowReferenceObject.focus();
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const checkWindowClosed = () => {
|
|
87
|
+
if (_get(windowReferenceObject, 'closed')) {
|
|
88
|
+
clearInterval(timer);
|
|
89
|
+
handleClose();
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const onClickCancel = () => {
|
|
94
|
+
updatePaymentOverlay.removeOverlay();
|
|
95
|
+
if (windowReferenceObject) {
|
|
96
|
+
windowReferenceObject.close();
|
|
97
|
+
}
|
|
98
|
+
clearInterval(timer);
|
|
99
|
+
onClose && onClose();
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// This creates the gray overlay covering the client's screen while patient update their payment information.
|
|
103
|
+
updatePaymentOverlay.createOverlay({ window, onClickRelaunch, onClickCancel });
|
|
104
|
+
|
|
105
|
+
// Check the window every 0.5 seconds to see if it has been closed.
|
|
106
|
+
const timer = setInterval(checkWindowClosed, 500);
|
|
107
|
+
|
|
108
|
+
const myBusinesses = await coreSDK.businesses.getMyBusinesses();
|
|
109
|
+
const myBusiness = myBusinesses.items[0];
|
|
110
|
+
const myBusinessId = _get(myBusiness, '_id');
|
|
111
|
+
|
|
112
|
+
const patient = await coreSDK.patients.getBusinessPatientByRefId(myBusinessId, patientRefId);
|
|
113
|
+
const patientId = _get(patient, '_id');
|
|
114
|
+
|
|
115
|
+
const requestPaymentMethodResponse = await coreSDK.patients.requestUpdatePatientPaymentMethod(
|
|
116
|
+
myBusinessId,
|
|
117
|
+
patientId,
|
|
118
|
+
{
|
|
119
|
+
sms: { sendToPatientRecordMobile: false, mobile: patient.mobile },
|
|
120
|
+
callbackOrigin: callbackOrigin,
|
|
121
|
+
},
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
const paymentMethodUpdateLink = _get(requestPaymentMethodResponse, 'paymentMethodUpdateLink');
|
|
125
|
+
|
|
126
|
+
const openWindow = () => {
|
|
127
|
+
// windowReferenceObject may not be defined if browser blocks the pop-up.
|
|
128
|
+
if (!windowReferenceObject) {
|
|
129
|
+
windowReferenceObject = initialiseWindow({ url: paymentMethodUpdateLink });
|
|
130
|
+
} else {
|
|
131
|
+
windowReferenceObject.location.replace(paymentMethodUpdateLink);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (!windowReferenceObject) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Start listening for incoming messages
|
|
139
|
+
window.addEventListener('message', e => onReceiveMessage(e));
|
|
140
|
+
|
|
141
|
+
const onReceiveMessage = (e: MessageEvent<any>) => {
|
|
142
|
+
if (!e) return;
|
|
143
|
+
getMessage(e);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const getMessage = (e: MessageEvent<any>) => {
|
|
147
|
+
const origin = ORIGINS[env];
|
|
148
|
+
|
|
149
|
+
if (!e || !origin) return;
|
|
150
|
+
|
|
151
|
+
// Ensure the message is coming from the correct origin.
|
|
152
|
+
if (_get(e, 'origin') !== origin) return;
|
|
153
|
+
|
|
154
|
+
const event = _get(e, 'data.event');
|
|
155
|
+
|
|
156
|
+
if (!event) return;
|
|
157
|
+
|
|
158
|
+
if (event === EVENTS.SUCCESS) {
|
|
159
|
+
isSessionComplete = true;
|
|
160
|
+
// Give 1.5 seconds for the user to see the success page before auto-closing the pop-up.
|
|
161
|
+
setTimeout(() => {
|
|
162
|
+
onSuccess && onSuccess();
|
|
163
|
+
if (windowReferenceObject) {
|
|
164
|
+
windowReferenceObject.close();
|
|
165
|
+
}
|
|
166
|
+
}, 1500);
|
|
167
|
+
}
|
|
168
|
+
if (event === EVENTS.fAILURE) {
|
|
169
|
+
isSessionComplete = true;
|
|
170
|
+
onFailure && onFailure();
|
|
171
|
+
}
|
|
172
|
+
if (event === EVENTS.CANCEL) {
|
|
173
|
+
isSessionComplete = true;
|
|
174
|
+
// Give 1.5 seconds for the user to see the reject page before auto-closing the pop-up.
|
|
175
|
+
setTimeout(() => {
|
|
176
|
+
onCancel && onCancel();
|
|
177
|
+
if (windowReferenceObject) {
|
|
178
|
+
windowReferenceObject.close();
|
|
179
|
+
}
|
|
180
|
+
}, 1500);
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
return windowReferenceObject;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
openWindow();
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
export default updatePaymentDetails;
|
package/{es → src}/style.css
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
@import url("https://fonts.googleapis.com/css?family=Lato:400,700");
|
|
1
|
+
@import url("https://fonts.googleapis.com/css?family=Lato:400,700");
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { ROOT_ELEMENT_ID } from './constants';
|
|
2
|
+
import toCss from './utils/object-to-css';
|
|
3
|
+
import _get from 'lodash/get';
|
|
4
|
+
|
|
5
|
+
const SUBHEADING_ELEMENT_ID = 'medipass-checkout-sdk-subheading';
|
|
6
|
+
|
|
7
|
+
function createElement({
|
|
8
|
+
window,
|
|
9
|
+
element,
|
|
10
|
+
text,
|
|
11
|
+
id,
|
|
12
|
+
styles,
|
|
13
|
+
onClick,
|
|
14
|
+
}: {
|
|
15
|
+
window: Window;
|
|
16
|
+
element: string;
|
|
17
|
+
text?: string;
|
|
18
|
+
id?: string;
|
|
19
|
+
styles?: Record<string, string>;
|
|
20
|
+
onClick?: () => void;
|
|
21
|
+
}) {
|
|
22
|
+
if (!window) return null;
|
|
23
|
+
|
|
24
|
+
const newElement = window.document.createElement(element);
|
|
25
|
+
|
|
26
|
+
if (text) {
|
|
27
|
+
newElement.innerHTML = text;
|
|
28
|
+
}
|
|
29
|
+
if (id) {
|
|
30
|
+
newElement.id = id;
|
|
31
|
+
}
|
|
32
|
+
if (styles) {
|
|
33
|
+
newElement.style.cssText = toCss(styles);
|
|
34
|
+
}
|
|
35
|
+
if (_get(newElement, 'addEventListener') && onClick) {
|
|
36
|
+
newElement.addEventListener('click', () => {
|
|
37
|
+
onClick();
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return newElement;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface Overlay {
|
|
45
|
+
contentElement: HTMLElement | null;
|
|
46
|
+
removeOverlay: () => void;
|
|
47
|
+
createOverlay: ({
|
|
48
|
+
window,
|
|
49
|
+
onClickRelaunch,
|
|
50
|
+
onClickCancel,
|
|
51
|
+
}: {
|
|
52
|
+
window: Window;
|
|
53
|
+
onClickRelaunch: () => void;
|
|
54
|
+
onClickCancel: () => void;
|
|
55
|
+
}) => void;
|
|
56
|
+
createSubHeading: ({
|
|
57
|
+
window,
|
|
58
|
+
onClickRelaunch,
|
|
59
|
+
onClickCancel,
|
|
60
|
+
}: {
|
|
61
|
+
window: Window;
|
|
62
|
+
onClickRelaunch: () => void;
|
|
63
|
+
onClickCancel: () => void;
|
|
64
|
+
}) => HTMLElement | null;
|
|
65
|
+
updateSubHeading: ({
|
|
66
|
+
window,
|
|
67
|
+
onClickRelaunch,
|
|
68
|
+
onClickCancel,
|
|
69
|
+
}: {
|
|
70
|
+
window: Window;
|
|
71
|
+
onClickRelaunch: () => void;
|
|
72
|
+
onClickCancel: () => void;
|
|
73
|
+
}) => void;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const overlay: Overlay = {
|
|
77
|
+
contentElement: null,
|
|
78
|
+
|
|
79
|
+
removeOverlay() {
|
|
80
|
+
const containerDiv = document.getElementById(ROOT_ELEMENT_ID);
|
|
81
|
+
if (!containerDiv) return;
|
|
82
|
+
containerDiv.remove();
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
createOverlay({ window, onClickRelaunch, onClickCancel }) {
|
|
86
|
+
if (!window) return null;
|
|
87
|
+
|
|
88
|
+
const containerDiv = createElement({
|
|
89
|
+
window,
|
|
90
|
+
element: 'div',
|
|
91
|
+
id: ROOT_ELEMENT_ID,
|
|
92
|
+
styles: {
|
|
93
|
+
'z-index': '2147483100',
|
|
94
|
+
position: 'fixed',
|
|
95
|
+
top: '0',
|
|
96
|
+
left: '0',
|
|
97
|
+
width: '100%',
|
|
98
|
+
height: '100%',
|
|
99
|
+
'background-color': 'rgba(0, 0, 0, 0.8)',
|
|
100
|
+
'font-family': 'Lato',
|
|
101
|
+
color: 'white',
|
|
102
|
+
display: 'flex',
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const content = createElement({
|
|
107
|
+
window,
|
|
108
|
+
element: 'div',
|
|
109
|
+
styles: {
|
|
110
|
+
'max-width': '360px',
|
|
111
|
+
'margin-left': 'auto',
|
|
112
|
+
'margin-right': 'auto',
|
|
113
|
+
'margin-top': 'auto',
|
|
114
|
+
'margin-bottom': 'auto',
|
|
115
|
+
'text-align': 'center',
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
this.contentElement = content;
|
|
120
|
+
|
|
121
|
+
////////////////////////////////////////////////////////////
|
|
122
|
+
|
|
123
|
+
const heading = createElement({
|
|
124
|
+
window,
|
|
125
|
+
element: 'div',
|
|
126
|
+
text: 'Updates to patient payment information are in progress',
|
|
127
|
+
styles: {
|
|
128
|
+
color: 'white',
|
|
129
|
+
'font-size': '35px',
|
|
130
|
+
'font-weight': '600',
|
|
131
|
+
'margin-bottom': '30px',
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
////////////////////////////////////////////////////////////
|
|
136
|
+
|
|
137
|
+
const subHeading = this.createSubHeading({ window, onClickRelaunch, onClickCancel });
|
|
138
|
+
|
|
139
|
+
////////////////////////////////////////////////////////////
|
|
140
|
+
|
|
141
|
+
if (!content) return;
|
|
142
|
+
if (!containerDiv) return;
|
|
143
|
+
|
|
144
|
+
if (heading) {
|
|
145
|
+
content.appendChild(heading);
|
|
146
|
+
}
|
|
147
|
+
if (subHeading) {
|
|
148
|
+
content.appendChild(subHeading);
|
|
149
|
+
}
|
|
150
|
+
containerDiv.appendChild(content);
|
|
151
|
+
|
|
152
|
+
////////////////////////////////////////////////////////////
|
|
153
|
+
|
|
154
|
+
window.document.body.appendChild(containerDiv);
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
createSubHeading({ window, onClickRelaunch, onClickCancel }) {
|
|
158
|
+
if (!window) return null;
|
|
159
|
+
|
|
160
|
+
const subHeadingContainer = createElement({
|
|
161
|
+
window,
|
|
162
|
+
id: SUBHEADING_ELEMENT_ID,
|
|
163
|
+
element: 'div',
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const subHeading1 = createElement({
|
|
167
|
+
window,
|
|
168
|
+
element: 'div',
|
|
169
|
+
text: "Don't see the window?",
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const link1 = createElement({
|
|
173
|
+
window,
|
|
174
|
+
element: 'a',
|
|
175
|
+
text: 'Click here',
|
|
176
|
+
onClick: onClickRelaunch,
|
|
177
|
+
styles: {
|
|
178
|
+
'text-decoration': 'underline',
|
|
179
|
+
cursor: 'pointer',
|
|
180
|
+
'font-weight': '600',
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
const subHeading2 = createElement({
|
|
184
|
+
window,
|
|
185
|
+
element: 'span',
|
|
186
|
+
text: ' to relaunch and complete updating patient payment details.',
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const subHeading3 = createElement({
|
|
190
|
+
window,
|
|
191
|
+
element: 'div',
|
|
192
|
+
text: 'OR',
|
|
193
|
+
styles: {
|
|
194
|
+
'margin-top': '20px',
|
|
195
|
+
'margin-bottom': '20px',
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const link2 = createElement({
|
|
200
|
+
window,
|
|
201
|
+
element: 'a',
|
|
202
|
+
text: 'Click here to cancel this request.',
|
|
203
|
+
onClick: onClickCancel,
|
|
204
|
+
styles: {
|
|
205
|
+
'text-decoration': 'underline',
|
|
206
|
+
cursor: 'pointer',
|
|
207
|
+
'font-weight': '600',
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
if (!subHeadingContainer) return null;
|
|
212
|
+
|
|
213
|
+
if (subHeading1) {
|
|
214
|
+
subHeadingContainer.appendChild(subHeading1);
|
|
215
|
+
}
|
|
216
|
+
if (link1) {
|
|
217
|
+
subHeadingContainer.appendChild(link1);
|
|
218
|
+
}
|
|
219
|
+
if (subHeading2) {
|
|
220
|
+
subHeadingContainer.appendChild(subHeading2);
|
|
221
|
+
}
|
|
222
|
+
if (subHeading3) {
|
|
223
|
+
subHeadingContainer.appendChild(subHeading3);
|
|
224
|
+
}
|
|
225
|
+
if (link2) {
|
|
226
|
+
subHeadingContainer.appendChild(link2);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return subHeadingContainer;
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
updateSubHeading({ window, onClickRelaunch, onClickCancel }) {
|
|
233
|
+
if (!window) return null;
|
|
234
|
+
|
|
235
|
+
const subheaderElement = document.getElementById(SUBHEADING_ELEMENT_ID);
|
|
236
|
+
if (subheaderElement) {
|
|
237
|
+
subheaderElement.remove();
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const newSubheading = this.createSubHeading({ window, onClickRelaunch, onClickCancel });
|
|
241
|
+
if (this.contentElement && this?.contentElement?.appendChild && newSubheading) {
|
|
242
|
+
this.contentElement.appendChild(newSubheading);
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
export default overlay;
|