@infosoftas/s4-orders-js-sdk 0.0.1-alpha1b → 0.0.1-alpha1e
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/.release-it.json +6 -0
- package/package.json +6 -5
- package/src/App.scss +2 -2
- package/src/App.tsx +97 -18
- package/src/api/OrdersApi.ts +15 -2
- package/src/api/SubscribeApi.ts +5 -1
- package/src/assets/styles/forms.scss +1 -1
- package/src/assets/styles/general.scss +2 -2
- package/src/components/Alert/alert.scss +1 -1
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/Button/button.scss +1 -1
- package/src/components/FormFields/AddressField.tsx +52 -0
- package/src/components/FormFields/EmailField.tsx +5 -1
- package/src/components/FormFields/FormFields.helper.ts +5 -1
- package/src/components/FormFields/FormFieldsMapper.ts +9 -3
- package/src/components/FormFields/InputField.tsx +51 -0
- package/src/components/FormFields/NameField.tsx +5 -1
- package/src/components/FormFields/PhoneField.tsx +5 -1
- package/src/components/Loader/loader.scss +1 -1
- package/src/components/MainIframe/MainIframe.tsx +1 -1
- package/src/components/OrderForm/OrderForm.tsx +73 -17
- package/src/components/OrderForm/orderForm.scss +1 -1
- package/src/constants/index.ts +1 -1
- package/src/enums/general.ts +2 -0
- package/src/hooks/useMessageEvent.tsx +3 -2
- package/src/index.tsx +8 -7
- package/src/types/api.ts +1 -1
- package/src/types/general.ts +6 -1
- package/src/types/order.ts +6 -1
- package/src/utils/fetcher.ts +11 -7
- package/src/utils/helper.ts +29 -1
- package/src/utils/order.helper.ts +29 -9
- package/tsconfig.json +41 -0
package/.release-it.json
ADDED
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infosoftas/s4-orders-js-sdk",
|
|
3
|
-
"version": "0.0.1-
|
|
3
|
+
"version": "0.0.1-alpha1e",
|
|
4
4
|
"scripts": {
|
|
5
|
-
"build": "rimraf
|
|
5
|
+
"build": "rimraf lib && webpack --env mode=production"
|
|
6
6
|
},
|
|
7
7
|
"eslintConfig": {
|
|
8
8
|
"extends": [
|
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
"prop-types": "^15.8.1",
|
|
14
14
|
"react": "^18.3.1",
|
|
15
15
|
"react-dom": "^18.3.1",
|
|
16
|
-
"react-hook-form": "^7.53.0"
|
|
17
|
-
"rimraf": "^6.0.1"
|
|
16
|
+
"react-hook-form": "^7.53.0"
|
|
18
17
|
},
|
|
19
18
|
"devDependencies": {
|
|
20
19
|
"@babel/core": "^7.24.3",
|
|
@@ -25,6 +24,7 @@
|
|
|
25
24
|
"@types/react-dom": "^18.0.6",
|
|
26
25
|
"babel-loader": "^8.3.0",
|
|
27
26
|
"css-loader": "^7.1.2",
|
|
27
|
+
"copy-webpack-plugin": "^12.0.2",
|
|
28
28
|
"dotenv-webpack": "^8.1.0",
|
|
29
29
|
"mini-css-extract-plugin": "^2.9.1",
|
|
30
30
|
"sass": "^1.79.2",
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"ts-loader": "^9.5.1",
|
|
34
34
|
"typescript": "^5.6.2",
|
|
35
35
|
"webpack": "^5.95.0",
|
|
36
|
-
"webpack-cli": "^5.1.4"
|
|
36
|
+
"webpack-cli": "^5.1.4",
|
|
37
|
+
"rimraf": "^6.0.1"
|
|
37
38
|
},
|
|
38
39
|
"publishConfig": {
|
|
39
40
|
"access": "restricted"
|
package/src/App.scss
CHANGED
package/src/App.tsx
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { FC, useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
|
-
import { MessageEventTypeEnum, PaymentMethodEnum } from '
|
|
4
|
-
import useMessageEvent from '
|
|
5
|
-
import OrderForm from '
|
|
6
|
-
import Loader from '
|
|
7
|
-
import MainIframe from '
|
|
8
|
-
import Alert from '
|
|
9
|
-
import { ConfigType } from '
|
|
10
|
-
import { CompleteOrderParamsType, OrderInfoType } from '
|
|
11
|
-
import { orderComplete } from '
|
|
12
|
-
import { prepareErrorMessage } from '
|
|
3
|
+
import { MessageEventTypeEnum, PaymentMethodEnum } from './enums/general';
|
|
4
|
+
import useMessageEvent from './hooks/useMessageEvent';
|
|
5
|
+
import OrderForm from './components/OrderForm/OrderForm';
|
|
6
|
+
import Loader from './components/Loader/Loader';
|
|
7
|
+
import MainIframe from './components/MainIframe/MainIframe';
|
|
8
|
+
import Alert from './components/Alert/Alert';
|
|
9
|
+
import { ConfigType, ErrorsMsg } from './types/general';
|
|
10
|
+
import { CompleteOrderParamsType, OrderInfoType } from './types/order';
|
|
11
|
+
import { orderComplete, orderDelete } from './api/OrdersApi';
|
|
12
|
+
import { prepareErrorMessage, prepareErrorsArrayMessage } from './utils/helper';
|
|
13
13
|
|
|
14
14
|
import ErrorBoundary from './ErrorBoundary';
|
|
15
15
|
|
|
@@ -18,6 +18,7 @@ import './App.scss';
|
|
|
18
18
|
const App: FC<ConfigType> = ({
|
|
19
19
|
moduleTitle,
|
|
20
20
|
apiKey,
|
|
21
|
+
apiUrl,
|
|
21
22
|
templatePackageId,
|
|
22
23
|
subscriberId,
|
|
23
24
|
userId,
|
|
@@ -42,6 +43,7 @@ const App: FC<ConfigType> = ({
|
|
|
42
43
|
const [isConfirmed, setIsConfirmed] = useState<boolean>(false);
|
|
43
44
|
const [isFailed, setIsFailed] = useState<boolean>(false);
|
|
44
45
|
const [failedMsg, setFailedMsg] = useState<string>('');
|
|
46
|
+
const [errorsMsg, setErrorsMsg] = useState<string[]>([]);
|
|
45
47
|
const [orderInfo, setOrderInfo] = useState<OrderInfoType | null>(null);
|
|
46
48
|
|
|
47
49
|
useEffect(() => {
|
|
@@ -50,6 +52,12 @@ const App: FC<ConfigType> = ({
|
|
|
50
52
|
}
|
|
51
53
|
}, [apiKey]);
|
|
52
54
|
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (apiUrl) {
|
|
57
|
+
sessionStorage.setItem('sdk_api_url', apiUrl);
|
|
58
|
+
}
|
|
59
|
+
}, [apiUrl]);
|
|
60
|
+
|
|
53
61
|
const messageCallback = async (
|
|
54
62
|
data: CompleteOrderParamsType
|
|
55
63
|
): Promise<void> => {
|
|
@@ -57,6 +65,8 @@ const App: FC<ConfigType> = ({
|
|
|
57
65
|
setIframeSrc(null);
|
|
58
66
|
setShowOrderForm(false);
|
|
59
67
|
setIsFailed(false);
|
|
68
|
+
setFailedMsg('');
|
|
69
|
+
setErrorsMsg([]);
|
|
60
70
|
try {
|
|
61
71
|
await orderComplete(orderId || data.orderId || '');
|
|
62
72
|
setIsConfirmed(true);
|
|
@@ -73,23 +83,83 @@ const App: FC<ConfigType> = ({
|
|
|
73
83
|
}
|
|
74
84
|
} catch (error) {
|
|
75
85
|
console.log(error);
|
|
86
|
+
if (
|
|
87
|
+
(error as { status: number }).status === 409 &&
|
|
88
|
+
(data.paymentMethod === PaymentMethodEnum.Vipps ||
|
|
89
|
+
data.paymentMethod === PaymentMethodEnum.MobilePay)
|
|
90
|
+
) {
|
|
91
|
+
handleOrderDelete(orderId || data.orderId);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
76
95
|
setFailedMsg(
|
|
77
96
|
prepareErrorMessage(error as Error, settings?.failureText)
|
|
78
97
|
);
|
|
98
|
+
setErrorsMsg(
|
|
99
|
+
prepareErrorsArrayMessage(
|
|
100
|
+
(
|
|
101
|
+
error as {
|
|
102
|
+
errors: ErrorsMsg;
|
|
103
|
+
}
|
|
104
|
+
)?.errors
|
|
105
|
+
)
|
|
106
|
+
);
|
|
79
107
|
setIsFailed(true);
|
|
80
108
|
setLoading(false);
|
|
81
109
|
setShowOrderForm(true);
|
|
82
110
|
}
|
|
83
111
|
};
|
|
84
112
|
|
|
85
|
-
const
|
|
113
|
+
const handleOrderDelete = async (id: string) => {
|
|
114
|
+
try {
|
|
115
|
+
await orderDelete(id);
|
|
116
|
+
if (window === top) {
|
|
117
|
+
top.postMessage(
|
|
118
|
+
{
|
|
119
|
+
type: MessageEventTypeEnum.ORDER_FLOW_CANCEL,
|
|
120
|
+
isCanceled: true,
|
|
121
|
+
orderInfo: orderInfo,
|
|
122
|
+
},
|
|
123
|
+
top?.location?.origin || '*'
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
setIsFailed(false);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.log(error);
|
|
129
|
+
setFailedMsg(
|
|
130
|
+
prepareErrorMessage(error as Error, settings?.failureText)
|
|
131
|
+
);
|
|
132
|
+
setErrorsMsg(
|
|
133
|
+
prepareErrorsArrayMessage(
|
|
134
|
+
(
|
|
135
|
+
error as {
|
|
136
|
+
errors: ErrorsMsg;
|
|
137
|
+
}
|
|
138
|
+
)?.errors
|
|
139
|
+
)
|
|
140
|
+
);
|
|
141
|
+
setIsFailed(true);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
setLoading(false);
|
|
145
|
+
setShowOrderForm(true);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const handleMessageEvent = async (type: MessageEventTypeEnum) => {
|
|
86
149
|
if (type === MessageEventTypeEnum.CANCEL) {
|
|
150
|
+
try {
|
|
151
|
+
if (orderId) {
|
|
152
|
+
await handleOrderDelete(orderId);
|
|
153
|
+
}
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.log(error);
|
|
156
|
+
}
|
|
157
|
+
|
|
87
158
|
setLoading(false);
|
|
88
159
|
setOrderId(null);
|
|
89
160
|
setOrderInfo(null);
|
|
90
161
|
setIframeSrc(null);
|
|
91
162
|
setIsConfirmed(false);
|
|
92
|
-
setIsFailed(false);
|
|
93
163
|
setShowOrderForm(true);
|
|
94
164
|
}
|
|
95
165
|
};
|
|
@@ -106,6 +176,16 @@ const App: FC<ConfigType> = ({
|
|
|
106
176
|
setIsFailed(false);
|
|
107
177
|
setOrderId(data?.orderId || null);
|
|
108
178
|
setOrderInfo(data || null);
|
|
179
|
+
if (window === top) {
|
|
180
|
+
top.postMessage(
|
|
181
|
+
{
|
|
182
|
+
type: MessageEventTypeEnum.ORDER_UPDATE_INFO,
|
|
183
|
+
isUpdate: true,
|
|
184
|
+
orderInfo: data || null,
|
|
185
|
+
},
|
|
186
|
+
top?.location?.origin || '*'
|
|
187
|
+
);
|
|
188
|
+
}
|
|
109
189
|
if (url) {
|
|
110
190
|
if (
|
|
111
191
|
showIframe &&
|
|
@@ -155,12 +235,8 @@ const App: FC<ConfigType> = ({
|
|
|
155
235
|
errorInvalidEmailMsg={settings?.errorInvalidEmailMsg}
|
|
156
236
|
errorInvalidPhoneMsg={settings?.errorInvalidPhoneMsg}
|
|
157
237
|
defaultValues={settings?.orderDefaultValues}
|
|
158
|
-
redirectUrl={
|
|
159
|
-
|
|
160
|
-
? window.location.href.split('?')[0]
|
|
161
|
-
: redirectUrl ||
|
|
162
|
-
window.location.href.split('?')[0]
|
|
163
|
-
}
|
|
238
|
+
redirectUrl={redirectUrl}
|
|
239
|
+
showIframe={showIframe}
|
|
164
240
|
paymentMethodsOptions={paymentMethodsOptions}
|
|
165
241
|
language={language}
|
|
166
242
|
merchantAgreementUrl={merchantAgreementUrl}
|
|
@@ -176,6 +252,9 @@ const App: FC<ConfigType> = ({
|
|
|
176
252
|
)}
|
|
177
253
|
|
|
178
254
|
{isFailed && <Alert className="mt-2" msg={failedMsg} />}
|
|
255
|
+
{isFailed &&
|
|
256
|
+
errorsMsg?.length > 0 &&
|
|
257
|
+
errorsMsg.map((i) => <Alert className="mt-2" msg={i} />)}
|
|
179
258
|
</div>
|
|
180
259
|
</ErrorBoundary>
|
|
181
260
|
);
|
package/src/api/OrdersApi.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AgreementsType } from '
|
|
2
|
-
import fetcher from '
|
|
1
|
+
import { AgreementsType } from '../types/order';
|
|
2
|
+
import fetcher from '../utils/fetcher';
|
|
3
3
|
|
|
4
4
|
type RequestOrderStartType = {
|
|
5
5
|
subscriberId?: string;
|
|
@@ -42,3 +42,16 @@ export const orderComplete = (id: string): Promise<OrderResponseType> =>
|
|
|
42
42
|
},
|
|
43
43
|
body: null,
|
|
44
44
|
}) as Promise<OrderResponseType>;
|
|
45
|
+
|
|
46
|
+
export const orderDelete = (id: string): Promise<OrderResponseType> =>
|
|
47
|
+
fetcher<OrderResponseType, null>({
|
|
48
|
+
method: 'DELETE',
|
|
49
|
+
url: `/order/${id}`,
|
|
50
|
+
headers: {
|
|
51
|
+
'S4-ORDERS-API-KEY':
|
|
52
|
+
sessionStorage.getItem('sdk_api_key') ||
|
|
53
|
+
process.env.API_KEY ||
|
|
54
|
+
'',
|
|
55
|
+
},
|
|
56
|
+
body: null,
|
|
57
|
+
}) as Promise<OrderResponseType>;
|
package/src/api/SubscribeApi.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import fetcher from '
|
|
1
|
+
import fetcher from '../utils/fetcher';
|
|
2
2
|
|
|
3
3
|
type CreateSubscriberRequestType = {
|
|
4
4
|
name?: string;
|
|
5
5
|
email?: string;
|
|
6
6
|
phone?: string;
|
|
7
|
+
country?: string;
|
|
8
|
+
city?: string;
|
|
9
|
+
addressLines?: string[];
|
|
10
|
+
zip?: string;
|
|
7
11
|
};
|
|
8
12
|
|
|
9
13
|
type CreateSubscriberResponseType = {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { useFormContext } from 'react-hook-form';
|
|
3
|
+
|
|
4
|
+
import { uuidv4 } from '../../utils/helper';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
name: string;
|
|
8
|
+
required: boolean;
|
|
9
|
+
readOnly: boolean;
|
|
10
|
+
label?: string;
|
|
11
|
+
errorReqMsg?: string;
|
|
12
|
+
errors?: {
|
|
13
|
+
address?: {
|
|
14
|
+
message?: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const AddressField: FC<Props> = ({
|
|
20
|
+
required = false,
|
|
21
|
+
readOnly = false,
|
|
22
|
+
label = 'Address',
|
|
23
|
+
errorReqMsg = 'This field is required!',
|
|
24
|
+
errors,
|
|
25
|
+
}) => {
|
|
26
|
+
const { register } = useFormContext();
|
|
27
|
+
const id = uuidv4();
|
|
28
|
+
return (
|
|
29
|
+
<div className="field-wrapper" data-testid="sdk-address-field-id">
|
|
30
|
+
<textarea
|
|
31
|
+
id={id}
|
|
32
|
+
autoComplete="address"
|
|
33
|
+
placeholder=" "
|
|
34
|
+
readOnly={readOnly}
|
|
35
|
+
className={`input-control ${readOnly ? 'read-only' : ''}`}
|
|
36
|
+
{...register('address', {
|
|
37
|
+
required: required ? errorReqMsg : false,
|
|
38
|
+
})}
|
|
39
|
+
/>
|
|
40
|
+
<label className="label-control" htmlFor={id}>
|
|
41
|
+
{label} {required && <span className="text-error">*</span>}
|
|
42
|
+
</label>
|
|
43
|
+
{errors && errors.address && (
|
|
44
|
+
<div className="text-error caption">
|
|
45
|
+
{errors.address.message}
|
|
46
|
+
</div>
|
|
47
|
+
)}
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default AddressField;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
2
|
import { useFormContext } from 'react-hook-form';
|
|
3
3
|
|
|
4
|
+
import { uuidv4 } from '../../utils/helper';
|
|
5
|
+
|
|
4
6
|
type Props = {
|
|
5
7
|
name: string;
|
|
6
8
|
required: boolean;
|
|
@@ -24,9 +26,11 @@ const EmailField: FC<Props> = ({
|
|
|
24
26
|
errors,
|
|
25
27
|
}) => {
|
|
26
28
|
const { register } = useFormContext();
|
|
29
|
+
const id = uuidv4();
|
|
27
30
|
return (
|
|
28
31
|
<div className="field-wrapper" data-testid="sdk-email-field-id">
|
|
29
32
|
<input
|
|
33
|
+
id={id}
|
|
30
34
|
autoComplete="email"
|
|
31
35
|
placeholder=" "
|
|
32
36
|
className={`input-control ${readOnly ? 'read-only' : ''}`}
|
|
@@ -40,7 +44,7 @@ const EmailField: FC<Props> = ({
|
|
|
40
44
|
},
|
|
41
45
|
})}
|
|
42
46
|
/>
|
|
43
|
-
<label className="label-control">
|
|
47
|
+
<label className="label-control" htmlFor={id}>
|
|
44
48
|
{label} {required && <span className="text-error">*</span>}
|
|
45
49
|
</label>
|
|
46
50
|
{errors && errors.email && (
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { OrderFormFiledType } from '
|
|
1
|
+
import { OrderFormFiledType } from '../../types/general';
|
|
2
2
|
|
|
3
3
|
export const FIELD_TYPES = {
|
|
4
4
|
PHONE: 'phoneNumber',
|
|
5
5
|
EMAIL: 'email',
|
|
6
6
|
NAME: 'name',
|
|
7
|
+
COUNTRY: 'country',
|
|
8
|
+
CITY: 'city',
|
|
9
|
+
ADDRESS: 'address',
|
|
10
|
+
ZIP: 'zip',
|
|
7
11
|
};
|
|
8
12
|
|
|
9
13
|
export const DEFAULT_ORDER_FORM_FIELDS: OrderFormFiledType[] = [
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import EmailField from '
|
|
2
|
-
import PhoneField from '
|
|
3
|
-
import NameField from '
|
|
1
|
+
import EmailField from './EmailField';
|
|
2
|
+
import PhoneField from './PhoneField';
|
|
3
|
+
import NameField from './NameField';
|
|
4
|
+
import AddressField from './AddressField';
|
|
5
|
+
import InputField from './InputField';
|
|
4
6
|
|
|
5
7
|
import { FIELD_TYPES } from './FormFields.helper';
|
|
6
8
|
|
|
@@ -8,6 +10,10 @@ const formFieldsMapper = {
|
|
|
8
10
|
[FIELD_TYPES.PHONE]: PhoneField,
|
|
9
11
|
[FIELD_TYPES.NAME]: NameField,
|
|
10
12
|
[FIELD_TYPES.EMAIL]: EmailField,
|
|
13
|
+
[FIELD_TYPES.ADDRESS]: AddressField,
|
|
14
|
+
[FIELD_TYPES.COUNTRY]: InputField,
|
|
15
|
+
[FIELD_TYPES.CITY]: InputField,
|
|
16
|
+
[FIELD_TYPES.ZIP]: InputField,
|
|
11
17
|
};
|
|
12
18
|
|
|
13
19
|
export default formFieldsMapper;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { useFormContext } from 'react-hook-form';
|
|
3
|
+
|
|
4
|
+
import { uuidv4 } from '../../utils/helper';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
name: string;
|
|
8
|
+
required: boolean;
|
|
9
|
+
readOnly: boolean;
|
|
10
|
+
label?: string;
|
|
11
|
+
errorReqMsg?: string;
|
|
12
|
+
errors?: {
|
|
13
|
+
[key: string]: {
|
|
14
|
+
message?: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const NameField: FC<Props> = ({
|
|
20
|
+
name,
|
|
21
|
+
required = false,
|
|
22
|
+
readOnly = false,
|
|
23
|
+
label = '',
|
|
24
|
+
errorReqMsg = 'This field is required!',
|
|
25
|
+
errors,
|
|
26
|
+
}) => {
|
|
27
|
+
const { register } = useFormContext();
|
|
28
|
+
const id = uuidv4();
|
|
29
|
+
return (
|
|
30
|
+
<div className="field-wrapper" data-testid={`sdk-${name}-field-id`}>
|
|
31
|
+
<input
|
|
32
|
+
id={id}
|
|
33
|
+
autoComplete={name}
|
|
34
|
+
placeholder=" "
|
|
35
|
+
readOnly={readOnly}
|
|
36
|
+
className={`input-control ${readOnly ? 'read-only' : ''}`}
|
|
37
|
+
{...register(name, {
|
|
38
|
+
required: required ? errorReqMsg : false,
|
|
39
|
+
})}
|
|
40
|
+
/>
|
|
41
|
+
<label className="label-control" htmlFor={id}>
|
|
42
|
+
{label} {required && <span className="text-error">*</span>}
|
|
43
|
+
</label>
|
|
44
|
+
{errors && errors[name] && (
|
|
45
|
+
<div className="text-error caption">{errors[name].message}</div>
|
|
46
|
+
)}
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default NameField;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
2
|
import { useFormContext } from 'react-hook-form';
|
|
3
3
|
|
|
4
|
+
import { uuidv4 } from '../../utils/helper';
|
|
5
|
+
|
|
4
6
|
type Props = {
|
|
5
7
|
name: string;
|
|
6
8
|
required: boolean;
|
|
@@ -22,9 +24,11 @@ const NameField: FC<Props> = ({
|
|
|
22
24
|
errors,
|
|
23
25
|
}) => {
|
|
24
26
|
const { register } = useFormContext();
|
|
27
|
+
const id = uuidv4();
|
|
25
28
|
return (
|
|
26
29
|
<div className="field-wrapper" data-testid="sdk-name-field-id">
|
|
27
30
|
<input
|
|
31
|
+
id={id}
|
|
28
32
|
autoComplete="name"
|
|
29
33
|
placeholder=" "
|
|
30
34
|
readOnly={readOnly}
|
|
@@ -33,7 +37,7 @@ const NameField: FC<Props> = ({
|
|
|
33
37
|
required: required ? errorReqMsg : false,
|
|
34
38
|
})}
|
|
35
39
|
/>
|
|
36
|
-
<label className="label-control">
|
|
40
|
+
<label className="label-control" htmlFor={id}>
|
|
37
41
|
{label} {required && <span className="text-error">*</span>}
|
|
38
42
|
</label>
|
|
39
43
|
{errors && errors.name && (
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
2
|
import { useFormContext } from 'react-hook-form';
|
|
3
3
|
|
|
4
|
+
import { uuidv4 } from '../../utils/helper';
|
|
5
|
+
|
|
4
6
|
type Props = {
|
|
5
7
|
name: string;
|
|
6
8
|
required: boolean;
|
|
@@ -24,9 +26,11 @@ const PhoneFiled: FC<Props> = ({
|
|
|
24
26
|
errors,
|
|
25
27
|
}) => {
|
|
26
28
|
const { register } = useFormContext();
|
|
29
|
+
const id = uuidv4();
|
|
27
30
|
return (
|
|
28
31
|
<div className="field-wrapper" data-testid="sdk-phone-field-id">
|
|
29
32
|
<input
|
|
33
|
+
id={id}
|
|
30
34
|
autoComplete="tel"
|
|
31
35
|
className={`input-control ${readOnly ? 'read-only' : ''}`}
|
|
32
36
|
placeholder=" "
|
|
@@ -40,7 +44,7 @@ const PhoneFiled: FC<Props> = ({
|
|
|
40
44
|
},
|
|
41
45
|
})}
|
|
42
46
|
/>
|
|
43
|
-
<label className="label-control">
|
|
47
|
+
<label className="label-control" htmlFor={id}>
|
|
44
48
|
{label} {required && <span className="text-error">*</span>}
|
|
45
49
|
</label>
|
|
46
50
|
{errors && errors.phoneNumber && (
|
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import { FC, ChangeEvent, Suspense, useState } from 'react';
|
|
2
2
|
import { FormProvider, useForm, SubmitHandler } from 'react-hook-form';
|
|
3
3
|
|
|
4
|
-
import { createSubscriber, mapSubscriberToUser } from '
|
|
5
|
-
import { orderStart } from '
|
|
6
|
-
import { PaymentMethodEnum } from '
|
|
7
|
-
import { WRONG_MSG, PAYMENT_METHOD_DEFAULT } from '
|
|
8
|
-
import Alert from '
|
|
9
|
-
import Button from '
|
|
10
|
-
import formFieldsMapper from '
|
|
11
|
-
import { DEFAULT_ORDER_FORM_FIELDS } from '
|
|
12
|
-
import { OrderFormInputsType, OrderInfoType } from '
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
import { createSubscriber, mapSubscriberToUser } from '../../api/SubscribeApi';
|
|
5
|
+
import { orderStart } from '../../api/OrdersApi';
|
|
6
|
+
import { PaymentMethodEnum } from '../../enums/general';
|
|
7
|
+
import { WRONG_MSG, PAYMENT_METHOD_DEFAULT } from '../../constants/index';
|
|
8
|
+
import Alert from '../Alert/Alert';
|
|
9
|
+
import Button from '../Button/Button';
|
|
10
|
+
import formFieldsMapper from '../FormFields/FormFieldsMapper';
|
|
11
|
+
import { DEFAULT_ORDER_FORM_FIELDS } from '../FormFields/FormFields.helper';
|
|
12
|
+
import { OrderFormInputsType, OrderInfoType } from '../../types/order';
|
|
13
|
+
import {
|
|
14
|
+
PaymentMethodOptionsType,
|
|
15
|
+
OrderFormFiledType,
|
|
16
|
+
ErrorsMsg,
|
|
17
|
+
} from '../../types/general';
|
|
18
|
+
import { prepareAgreementModel } from '../../utils/order.helper';
|
|
19
|
+
import {
|
|
20
|
+
prepareErrorMessage,
|
|
21
|
+
prepareErrorsArrayMessage,
|
|
22
|
+
} from '../../utils/helper';
|
|
16
23
|
|
|
17
24
|
import './orderForm.scss';
|
|
18
25
|
|
|
@@ -23,7 +30,8 @@ type Props = {
|
|
|
23
30
|
userId?: string;
|
|
24
31
|
identityProviderId?: string;
|
|
25
32
|
organizationId: string;
|
|
26
|
-
redirectUrl
|
|
33
|
+
redirectUrl?: string;
|
|
34
|
+
showIframe?: boolean;
|
|
27
35
|
language: string;
|
|
28
36
|
merchantAgreementUrl: string;
|
|
29
37
|
paymentMethodsOptions?: PaymentMethodOptionsType;
|
|
@@ -40,6 +48,10 @@ const initialData = {
|
|
|
40
48
|
name: '',
|
|
41
49
|
email: '',
|
|
42
50
|
phoneNumber: '',
|
|
51
|
+
country: '',
|
|
52
|
+
city: '',
|
|
53
|
+
address: '',
|
|
54
|
+
zip: '',
|
|
43
55
|
paymentMethod: PAYMENT_METHOD_DEFAULT,
|
|
44
56
|
};
|
|
45
57
|
|
|
@@ -51,6 +63,7 @@ const OrderForm: FC<Props> = ({
|
|
|
51
63
|
identityProviderId,
|
|
52
64
|
organizationId,
|
|
53
65
|
redirectUrl,
|
|
66
|
+
showIframe,
|
|
54
67
|
paymentMethodsOptions,
|
|
55
68
|
defaultValues,
|
|
56
69
|
language,
|
|
@@ -64,6 +77,7 @@ const OrderForm: FC<Props> = ({
|
|
|
64
77
|
}) => {
|
|
65
78
|
const [loading, setLoading] = useState<boolean>(false);
|
|
66
79
|
const [apiErrorMsg, setApiErrorMsg] = useState<string>('');
|
|
80
|
+
const [errorsMsg, setErrorsMsg] = useState<string[]>([]);
|
|
67
81
|
const [orderFields, setOrderFields] = useState<OrderFormFiledType[]>(
|
|
68
82
|
paymentMethodsOptions?.[PAYMENT_METHOD_DEFAULT]?.orderFormFields ??
|
|
69
83
|
DEFAULT_ORDER_FORM_FIELDS
|
|
@@ -87,15 +101,40 @@ const OrderForm: FC<Props> = ({
|
|
|
87
101
|
data
|
|
88
102
|
): Promise<void> => {
|
|
89
103
|
setApiErrorMsg('');
|
|
104
|
+
setErrorsMsg([]);
|
|
90
105
|
|
|
91
106
|
setLoading(true);
|
|
92
107
|
try {
|
|
93
108
|
let id: string | undefined = subscriberId;
|
|
94
109
|
if (!subscriberId) {
|
|
95
110
|
const response = await createSubscriber({
|
|
96
|
-
name:
|
|
97
|
-
|
|
98
|
-
|
|
111
|
+
name: orderFields.find((i) => i.name === 'name')
|
|
112
|
+
? data.name?.trim() || undefined
|
|
113
|
+
: undefined,
|
|
114
|
+
email: orderFields.find((i) => i.name === 'email')
|
|
115
|
+
? data.email?.trim() || undefined
|
|
116
|
+
: undefined,
|
|
117
|
+
phone: orderFields.find((i) => i.name === 'phoneNumber')
|
|
118
|
+
? data.phoneNumber?.trim() || undefined
|
|
119
|
+
: undefined,
|
|
120
|
+
country: orderFields.find((i) => i.name === 'country')
|
|
121
|
+
? data.country?.trim() || undefined
|
|
122
|
+
: undefined,
|
|
123
|
+
city: orderFields.find((i) => i.name === 'city')
|
|
124
|
+
? data.city?.trim() || undefined
|
|
125
|
+
: undefined,
|
|
126
|
+
addressLines: orderFields.find((i) => i.name === 'address')
|
|
127
|
+
? data.address?.trim()
|
|
128
|
+
? data.address
|
|
129
|
+
?.trim()
|
|
130
|
+
.replace(/\r\n/g, '\n')
|
|
131
|
+
.split('\n')
|
|
132
|
+
.filter((line) => line)
|
|
133
|
+
: undefined
|
|
134
|
+
: undefined,
|
|
135
|
+
zip: orderFields.find((i) => i.name === 'zip')
|
|
136
|
+
? data.zip?.trim() || undefined
|
|
137
|
+
: undefined,
|
|
99
138
|
});
|
|
100
139
|
id = response.id;
|
|
101
140
|
|
|
@@ -114,7 +153,12 @@ const OrderForm: FC<Props> = ({
|
|
|
114
153
|
const agreements = prepareAgreementModel({
|
|
115
154
|
paymentMethod,
|
|
116
155
|
redirectUrl,
|
|
117
|
-
|
|
156
|
+
showIframe,
|
|
157
|
+
phoneNumber: orderFields.find(
|
|
158
|
+
(i) => i.name === 'phoneNumber'
|
|
159
|
+
)
|
|
160
|
+
? data.phoneNumber?.trim() || undefined
|
|
161
|
+
: undefined,
|
|
118
162
|
language,
|
|
119
163
|
merchantAgreementUrl,
|
|
120
164
|
generateSubscriberContact:
|
|
@@ -143,9 +187,19 @@ const OrderForm: FC<Props> = ({
|
|
|
143
187
|
}
|
|
144
188
|
callback(null);
|
|
145
189
|
setApiErrorMsg(WRONG_MSG);
|
|
190
|
+
setErrorsMsg([]);
|
|
146
191
|
} catch (error) {
|
|
147
192
|
console.error(error);
|
|
148
193
|
setApiErrorMsg(prepareErrorMessage(error as Error));
|
|
194
|
+
setErrorsMsg(
|
|
195
|
+
prepareErrorsArrayMessage(
|
|
196
|
+
(
|
|
197
|
+
error as {
|
|
198
|
+
errors: ErrorsMsg;
|
|
199
|
+
}
|
|
200
|
+
)?.errors
|
|
201
|
+
)
|
|
202
|
+
);
|
|
149
203
|
callback(null);
|
|
150
204
|
} finally {
|
|
151
205
|
setLoading(false);
|
|
@@ -227,6 +281,8 @@ const OrderForm: FC<Props> = ({
|
|
|
227
281
|
buttonText={buttonText}
|
|
228
282
|
/>
|
|
229
283
|
<Alert className="mt-2" msg={apiErrorMsg} />
|
|
284
|
+
{errorsMsg?.length > 0 &&
|
|
285
|
+
errorsMsg.map((i) => <Alert className="mt-2" msg={i} />)}
|
|
230
286
|
</form>
|
|
231
287
|
</FormProvider>
|
|
232
288
|
);
|
package/src/constants/index.ts
CHANGED
package/src/enums/general.ts
CHANGED
|
@@ -6,6 +6,8 @@ export enum PaymentMethodEnum {
|
|
|
6
6
|
|
|
7
7
|
export enum MessageEventTypeEnum {
|
|
8
8
|
ORDER_FLOW_COMPLETE = 'orderFlowComplete',
|
|
9
|
+
ORDER_FLOW_CANCEL = 'orderFlowCancel',
|
|
10
|
+
ORDER_UPDATE_INFO = 'orderUpdateInfo',
|
|
9
11
|
VIPPS_COMPLETE = 'completeOrder',
|
|
10
12
|
CANCEL = 'cancel',
|
|
11
13
|
COMPLETE = 'complete',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useCallback } from 'react';
|
|
2
2
|
|
|
3
|
-
import { MessageEventTypeEnum } from '
|
|
4
|
-
import { CompleteOrderParamsType, OrderInfoType } from '
|
|
3
|
+
import { MessageEventTypeEnum, PaymentMethodEnum } from '../enums/general';
|
|
4
|
+
import { CompleteOrderParamsType, OrderInfoType } from '../types/order';
|
|
5
5
|
import useQueryParams from './useQueryParams';
|
|
6
6
|
|
|
7
7
|
const useMessageEvent = (
|
|
@@ -76,6 +76,7 @@ const useMessageEvent = (
|
|
|
76
76
|
orderId: queryParams.get('orderId') || '',
|
|
77
77
|
agreementId: queryParams.get('agreementId') || '',
|
|
78
78
|
orderInfo: orderInfo || null,
|
|
79
|
+
paymentMethod: PaymentMethodEnum.Vipps,
|
|
79
80
|
});
|
|
80
81
|
}
|
|
81
82
|
}, [
|
package/src/index.tsx
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { createRoot, Root } from 'react-dom/client';
|
|
2
2
|
import { createElement } from 'react';
|
|
3
3
|
|
|
4
|
-
import { ConfigType } from '
|
|
5
|
-
import { createSubscriber, mapSubscriberToUser } from '
|
|
4
|
+
import { ConfigType } from './types/general';
|
|
5
|
+
import { createSubscriber, mapSubscriberToUser } from './api/SubscribeApi';
|
|
6
6
|
import App from './App';
|
|
7
7
|
|
|
8
|
-
let root: Root;
|
|
9
|
-
|
|
10
8
|
export const orderComponent = {
|
|
9
|
+
root: null as Root | null,
|
|
11
10
|
init: function (config: ConfigType) {
|
|
12
11
|
const domNode = document.getElementById(config.domElementId);
|
|
13
|
-
root = createRoot(
|
|
12
|
+
orderComponent.root = createRoot(
|
|
13
|
+
domNode || document.createElement('div')
|
|
14
|
+
);
|
|
14
15
|
const reactElement = createElement(App, config);
|
|
15
|
-
root.render(reactElement);
|
|
16
|
+
orderComponent.root.render(reactElement);
|
|
16
17
|
},
|
|
17
18
|
remove: function () {
|
|
18
|
-
(root as Root)?.unmount();
|
|
19
|
+
(orderComponent.root as Root)?.unmount();
|
|
19
20
|
},
|
|
20
21
|
createSubscriber,
|
|
21
22
|
mapSubscriberToUser,
|
package/src/types/api.ts
CHANGED
package/src/types/general.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PaymentMethodEnum } from '
|
|
1
|
+
import { PaymentMethodEnum } from '../enums/general';
|
|
2
2
|
import { OrderFormInputsType } from './order';
|
|
3
3
|
|
|
4
4
|
declare global {
|
|
@@ -31,6 +31,7 @@ export type ConfigType = {
|
|
|
31
31
|
identityProviderId: string;
|
|
32
32
|
organizationId: string;
|
|
33
33
|
apiKey?: string;
|
|
34
|
+
apiUrl?: string;
|
|
34
35
|
redirectUrl?: string;
|
|
35
36
|
showIframe?: boolean;
|
|
36
37
|
availablePaymentMethods?: { label: string; value: PaymentMethodEnum }[];
|
|
@@ -48,3 +49,7 @@ export type ConfigType = {
|
|
|
48
49
|
errorInvalidPhoneMsg?: string;
|
|
49
50
|
};
|
|
50
51
|
};
|
|
52
|
+
|
|
53
|
+
export type ErrorsMsg = {
|
|
54
|
+
[key: string]: string[];
|
|
55
|
+
};
|
package/src/types/order.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { PaymentMethodEnum } from '
|
|
1
|
+
import { PaymentMethodEnum } from '../enums/general';
|
|
2
2
|
|
|
3
3
|
export type OrderFormInputsType = {
|
|
4
4
|
name?: string;
|
|
5
5
|
email?: string;
|
|
6
6
|
phoneNumber?: string;
|
|
7
7
|
paymentMethod?: PaymentMethodEnum;
|
|
8
|
+
country?: string;
|
|
9
|
+
city?: string;
|
|
10
|
+
address?: string;
|
|
11
|
+
zip?: string;
|
|
8
12
|
};
|
|
9
13
|
|
|
10
14
|
export type VippsMobilePay = {
|
|
@@ -38,4 +42,5 @@ export type CompleteOrderParamsType = {
|
|
|
38
42
|
orderId: string;
|
|
39
43
|
agreementId: string;
|
|
40
44
|
orderInfo: OrderInfoType | null;
|
|
45
|
+
paymentMethod?: PaymentMethodEnum | null;
|
|
41
46
|
};
|
package/src/utils/fetcher.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { HttpStatusCode } from '
|
|
2
|
-
import { ApiResponseType } from '
|
|
3
|
-
import { BASE_API } from '
|
|
1
|
+
import { HttpStatusCode } from '../enums/api';
|
|
2
|
+
import { ApiResponseType } from '../types/api';
|
|
3
|
+
import { BASE_API } from '../constants/index';
|
|
4
4
|
|
|
5
5
|
export type Method =
|
|
6
6
|
| 'GET'
|
|
@@ -42,7 +42,8 @@ async function fetcher<ResponseType, BodyType = void>(
|
|
|
42
42
|
): Promise<ApiResponseType<ResponseType> | ResponseType> {
|
|
43
43
|
const { url, method, headers, body, params } = createHeader(options);
|
|
44
44
|
|
|
45
|
-
const
|
|
45
|
+
const apiUrl = sessionStorage.getItem('sdk_api_url');
|
|
46
|
+
const endpoint = new URL(`${apiUrl || BASE_API}${url}`);
|
|
46
47
|
|
|
47
48
|
if (params) {
|
|
48
49
|
Object.entries(params).forEach(([key, value]) => {
|
|
@@ -68,12 +69,15 @@ async function fetcher<ResponseType, BodyType = void>(
|
|
|
68
69
|
} else if (response.status === HttpStatusCode.FORBIDDEN) {
|
|
69
70
|
reject({ message: 'Something Wrong with permission!' });
|
|
70
71
|
} else {
|
|
71
|
-
const data = await response?.json();
|
|
72
72
|
if (response.ok) {
|
|
73
|
-
|
|
73
|
+
response
|
|
74
|
+
.json()
|
|
75
|
+
.then((data) => resolve(data))
|
|
76
|
+
.catch(() => resolve(null as ResponseType));
|
|
74
77
|
} else {
|
|
78
|
+
const data = await response?.json();
|
|
75
79
|
const message =
|
|
76
|
-
data.
|
|
80
|
+
data.details || data.message || data.title;
|
|
77
81
|
reject({ ...data, message });
|
|
78
82
|
}
|
|
79
83
|
}
|
package/src/utils/helper.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { WRONG_MSG } from '
|
|
1
|
+
import { WRONG_MSG } from '../constants/index';
|
|
2
|
+
import { ErrorsMsg } from '../types/general';
|
|
2
3
|
|
|
3
4
|
export const prepareErrorMessage = (error: Error, defaultMsg?: string) => {
|
|
4
5
|
if (typeof error === 'string') {
|
|
@@ -16,3 +17,30 @@ export const prepareErrorMessage = (error: Error, defaultMsg?: string) => {
|
|
|
16
17
|
);
|
|
17
18
|
}
|
|
18
19
|
};
|
|
20
|
+
|
|
21
|
+
export const prepareErrorsArrayMessage = (errors: ErrorsMsg | null) => {
|
|
22
|
+
const msg: string[] = [];
|
|
23
|
+
|
|
24
|
+
if (errors) {
|
|
25
|
+
Object.entries(errors).forEach(([_, values]) => {
|
|
26
|
+
if (values?.length > 0) {
|
|
27
|
+
values.forEach((i) => {
|
|
28
|
+
msg.push(i);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return msg;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export function uuidv4() {
|
|
38
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
|
|
39
|
+
/[xy]/g,
|
|
40
|
+
function (c) {
|
|
41
|
+
const r = (Math.random() * 16) | 0;
|
|
42
|
+
const v = c == 'x' ? r : (r & 0x3) | 0x8;
|
|
43
|
+
return v.toString(16);
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { MessageEventTypeEnum, PaymentMethodEnum } from '
|
|
2
|
-
import {
|
|
1
|
+
import { MessageEventTypeEnum, PaymentMethodEnum } from '../enums/general';
|
|
2
|
+
import { AgreementsType } from '../types/order';
|
|
3
3
|
|
|
4
4
|
type AgreementModelType = {
|
|
5
5
|
paymentMethod: PaymentMethodEnum;
|
|
6
|
-
redirectUrl
|
|
7
|
-
|
|
6
|
+
redirectUrl?: string;
|
|
7
|
+
showIframe?: boolean;
|
|
8
|
+
phoneNumber?: string;
|
|
8
9
|
generateSubscriberContact: boolean;
|
|
9
10
|
language: string;
|
|
10
11
|
merchantAgreementUrl: string;
|
|
@@ -14,7 +15,8 @@ type AgreementModelType = {
|
|
|
14
15
|
export const prepareAgreementModel = ({
|
|
15
16
|
paymentMethod,
|
|
16
17
|
redirectUrl,
|
|
17
|
-
|
|
18
|
+
showIframe,
|
|
19
|
+
phoneNumber,
|
|
18
20
|
generateSubscriberContact,
|
|
19
21
|
language,
|
|
20
22
|
merchantAgreementUrl,
|
|
@@ -23,11 +25,29 @@ export const prepareAgreementModel = ({
|
|
|
23
25
|
const model: AgreementsType = {
|
|
24
26
|
paymentProvider: paymentMethod,
|
|
25
27
|
};
|
|
28
|
+
const existUrl = new URL(window.location.href);
|
|
29
|
+
const journey = existUrl.searchParams.get('journey');
|
|
30
|
+
const url = showIframe
|
|
31
|
+
? window.location.href.split('?')[0]
|
|
32
|
+
: redirectUrl || window.location.href;
|
|
33
|
+
const cancelUrl = new URL(url);
|
|
34
|
+
cancelUrl.searchParams.append('action', `${MessageEventTypeEnum.CANCEL}`);
|
|
35
|
+
if (journey) {
|
|
36
|
+
cancelUrl.searchParams.append('journey', journey);
|
|
37
|
+
}
|
|
38
|
+
const confirmUrl = new URL(url);
|
|
39
|
+
confirmUrl.searchParams.append(
|
|
40
|
+
'action',
|
|
41
|
+
`${MessageEventTypeEnum.COMPLETE}`
|
|
42
|
+
);
|
|
43
|
+
if (journey) {
|
|
44
|
+
confirmUrl.searchParams.append('journey', journey);
|
|
45
|
+
}
|
|
26
46
|
|
|
27
47
|
if (paymentMethod === PaymentMethodEnum.SwedbankPay) {
|
|
28
48
|
model.swedbankPay = {
|
|
29
|
-
cancelUrl: `${
|
|
30
|
-
completeUrl: `${
|
|
49
|
+
cancelUrl: `${cancelUrl}`,
|
|
50
|
+
completeUrl: `${confirmUrl}`,
|
|
31
51
|
language,
|
|
32
52
|
accountId,
|
|
33
53
|
};
|
|
@@ -41,8 +61,8 @@ export const prepareAgreementModel = ({
|
|
|
41
61
|
generateSubscriberContact,
|
|
42
62
|
merchantAgreementUrl,
|
|
43
63
|
accountId,
|
|
44
|
-
phoneNumber
|
|
45
|
-
merchantRedirectUrl: redirectUrl,
|
|
64
|
+
phoneNumber,
|
|
65
|
+
merchantRedirectUrl: redirectUrl || window.location.href,
|
|
46
66
|
},
|
|
47
67
|
};
|
|
48
68
|
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es5",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"downlevelIteration": true,
|
|
6
|
+
"allowJs": true,
|
|
7
|
+
"checkJs": false,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"allowSyntheticDefaultImports": true,
|
|
11
|
+
"strict": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"noFallthroughCasesInSwitch": true,
|
|
14
|
+
"module": "esnext",
|
|
15
|
+
"moduleResolution": "node",
|
|
16
|
+
"resolveJsonModule": true,
|
|
17
|
+
"isolatedModules": false,
|
|
18
|
+
"noEmit": false,
|
|
19
|
+
"noImplicitAny": true,
|
|
20
|
+
"jsx": "react-jsx",
|
|
21
|
+
"baseUrl": "src",
|
|
22
|
+
"sourceMap": true,
|
|
23
|
+
"inlineSources": true,
|
|
24
|
+
"sourceRoot": "/",
|
|
25
|
+
"paths": {
|
|
26
|
+
"*": ["*"],
|
|
27
|
+
"API": ["api"],
|
|
28
|
+
"API/*": ["api/*"],
|
|
29
|
+
"Component/*": ["components/*"],
|
|
30
|
+
"Utils/*": ["utils/*"],
|
|
31
|
+
"Hooks/*": ["hooks/*"],
|
|
32
|
+
"Models/*": ["models/*"],
|
|
33
|
+
"Types/*": ["types/*"],
|
|
34
|
+
"Enums/*": ["enums/*"],
|
|
35
|
+
"Constants/*": ["constants/*"],
|
|
36
|
+
"Assets/*": ["assets/*"]
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"include": ["src"],
|
|
40
|
+
"exclude": ["node_modules"]
|
|
41
|
+
}
|