@infosoftas/s4-orders-js-sdk 0.0.1-alpha2a → 0.0.1-alpha2c
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/README.md +340 -1
- package/__azurite_db_blob__.json +1 -0
- package/__azurite_db_blob_extent__.json +1 -0
- package/__azurite_db_queue__.json +1 -0
- package/__azurite_db_queue_extent__.json +1 -0
- package/__azurite_db_table__.json +1 -0
- package/__blobstorage__/6814b4e2-aa0c-49d2-9ea5-e8893c0aa38d +43 -0
- package/package.json +1 -1
- package/src/App.tsx +96 -34
- package/src/api/InvoiceApi.ts +25 -0
- package/src/assets/styles/general.scss +4 -0
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/EHFForm/EHFForm.tsx +125 -0
- package/src/components/OIOForm/OIOForm.tsx +141 -0
- package/src/components/OrderForm/OrderForm.tsx +3 -3
- package/src/enums/general.ts +12 -0
- package/src/types/general.ts +5 -1
package/README.md
CHANGED
|
@@ -1,3 +1,342 @@
|
|
|
1
1
|
# INFO-Subscription JS/TS Order SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This repository contains code for the Orders SDK usable to add orders for Tenants within INFO-Subscription.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Install the package with:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install @infosoftas/s4-orders-js-sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Available Scripts
|
|
14
|
+
|
|
15
|
+
In the project directory, you can run:
|
|
16
|
+
|
|
17
|
+
### `npm run build`
|
|
18
|
+
|
|
19
|
+
Builds the app for production to the `dist` folder.\
|
|
20
|
+
It correctly bundles React in production mode and optimizes the build for the best performance.
|
|
21
|
+
|
|
22
|
+
The build is minified and the filenames include the hashes.\
|
|
23
|
+
Your app is ready to be deployed!
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
The package needs to be configured with configuration object:
|
|
28
|
+
|
|
29
|
+
<!-- prettier-ignore -->
|
|
30
|
+
```ts
|
|
31
|
+
|
|
32
|
+
enum PaymentMethodEnum {
|
|
33
|
+
Vipps = 'Vipps',
|
|
34
|
+
MobilePay = 'MobilePay',
|
|
35
|
+
SwedbankPay = 'SwedbankPay',
|
|
36
|
+
Invoice = 'Invoice',
|
|
37
|
+
Email = 'Email',
|
|
38
|
+
EHF = 'EHF',
|
|
39
|
+
OIO = 'OIO',
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type OrderFormFiledType = {
|
|
43
|
+
name: string;
|
|
44
|
+
required?: boolean;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type PaymentMethodOptionsType = {
|
|
48
|
+
[key in PaymentMethodEnum]: {
|
|
49
|
+
generateSubscriberContact?: boolean;
|
|
50
|
+
accountId?: string;
|
|
51
|
+
orderFormFields?: OrderFormFiledType[] | never[];
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
type OrderFormInputsType = {
|
|
56
|
+
name?: string;
|
|
57
|
+
email?: string;
|
|
58
|
+
phoneNumber?: string;
|
|
59
|
+
paymentMethod?: PaymentMethodEnum;
|
|
60
|
+
country?: string;
|
|
61
|
+
city?: string;
|
|
62
|
+
address?: string;
|
|
63
|
+
zip?: string;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
type ConfigType = {
|
|
67
|
+
domElementId: string;
|
|
68
|
+
moduleTitle?: string;
|
|
69
|
+
apiKey: string;
|
|
70
|
+
apiUrl: string;
|
|
71
|
+
templatePackageId: string;
|
|
72
|
+
subscriberId: string;
|
|
73
|
+
userId: string;
|
|
74
|
+
identityProviderId: string;
|
|
75
|
+
organizationId: string;
|
|
76
|
+
redirectUrl?: string;
|
|
77
|
+
showIframe?: boolean;
|
|
78
|
+
availablePaymentMethods?: { label: string; value: PaymentMethodEnum }[];
|
|
79
|
+
paymentMethodsOptions?: PaymentMethodOptionsType;
|
|
80
|
+
language?: string;
|
|
81
|
+
merchantAgreementUrl?: string;
|
|
82
|
+
invoiceAddressSelection?: {
|
|
83
|
+
enabled?: boolean;
|
|
84
|
+
label?: string;
|
|
85
|
+
fields?: OrderFormFiledType[] | never[];
|
|
86
|
+
};
|
|
87
|
+
settings?: {
|
|
88
|
+
successText?: string;
|
|
89
|
+
failureText?: string;
|
|
90
|
+
submitButtonText?: string;
|
|
91
|
+
backButtonText?: string;
|
|
92
|
+
verifyButtonText?: string;
|
|
93
|
+
organizationNumberLabel?: string;
|
|
94
|
+
glnLabel?: string;
|
|
95
|
+
orderDefaultValues?: OrderFormInputsType;
|
|
96
|
+
paymentMethodLabel?: string;
|
|
97
|
+
errorReqMsg?: string;
|
|
98
|
+
errorInvalidEmailMsg?: string;
|
|
99
|
+
errorInvalidPhoneMsg?: string;
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Usage example OrderPlace react component:
|
|
105
|
+
|
|
106
|
+
<!-- prettier-ignore -->
|
|
107
|
+
```tsx
|
|
108
|
+
|
|
109
|
+
enum OrderModuleFiledNameEnum {
|
|
110
|
+
name = 'name',
|
|
111
|
+
email = 'email',
|
|
112
|
+
phoneNumber = 'phoneNumber',
|
|
113
|
+
address = 'address',
|
|
114
|
+
country = 'country',
|
|
115
|
+
city = 'city',
|
|
116
|
+
zip = 'zip',
|
|
117
|
+
careOf = 'careOf',
|
|
118
|
+
organizationNumber = 'organizationNumber',
|
|
119
|
+
buyerReference = 'buyerReference',
|
|
120
|
+
orderReference = 'orderReference',
|
|
121
|
+
invoiceName = 'invoiceName',
|
|
122
|
+
invoiceAddress = 'invoiceAddress',
|
|
123
|
+
invoiceCity = 'invoiceCity',
|
|
124
|
+
invoiceZip = 'invoiceZip',
|
|
125
|
+
invoiceCountry = 'invoiceCountry',
|
|
126
|
+
invoicePhone = 'invoicePhoneNumber',
|
|
127
|
+
invoiceEmail = 'invoiceEmail',
|
|
128
|
+
invoiceCareOf = 'invoiceCareOf',
|
|
129
|
+
invoiceBuyerReference ='invoiceBuyerReference',
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export const prepareConfig = ({
|
|
133
|
+
apiKey,
|
|
134
|
+
apiUrl,
|
|
135
|
+
userId,
|
|
136
|
+
subscriberId,
|
|
137
|
+
templatePackageId,
|
|
138
|
+
identityProviderId,
|
|
139
|
+
organizationId,
|
|
140
|
+
selfServiceUrl,
|
|
141
|
+
userEmail,
|
|
142
|
+
name,
|
|
143
|
+
city,
|
|
144
|
+
country,
|
|
145
|
+
postalCode,
|
|
146
|
+
streetAddress,
|
|
147
|
+
}: Props) => {
|
|
148
|
+
|
|
149
|
+
const config = {
|
|
150
|
+
moduleTitle: '',
|
|
151
|
+
domElementId: ORDER_PLACE_ID,
|
|
152
|
+
redirectUrl: window.location.href,
|
|
153
|
+
merchantAgreementUrl: selfServiceUrl,
|
|
154
|
+
showIframe: true,
|
|
155
|
+
apiKey,
|
|
156
|
+
apiUrl,
|
|
157
|
+
userId,
|
|
158
|
+
subscriberId,
|
|
159
|
+
templatePackageId,
|
|
160
|
+
identityProviderId,
|
|
161
|
+
organizationId,
|
|
162
|
+
language: 'en-US',
|
|
163
|
+
availablePaymentMethods: [
|
|
164
|
+
{ label: "Vipps", value: "Vipps" },
|
|
165
|
+
{ label: "MobilePay", value: "MobilePay" },
|
|
166
|
+
{ label: "Credit Card/Debit Card", value: "SwedbankPay" },
|
|
167
|
+
{ label: 'Invoice', translateKey: 'Invoice', value: 'Invoice' },
|
|
168
|
+
{ label: 'Email', translateKey: 'Email', value: 'Email' },
|
|
169
|
+
{ label: 'EHF', translateKey: 'EHF', value: 'EHF' },
|
|
170
|
+
{ label: 'OIO', translateKey: 'OIO', value: 'OIO' },
|
|
171
|
+
],
|
|
172
|
+
paymentMethodsOptions: {
|
|
173
|
+
Vipps: {
|
|
174
|
+
generateSubscriberContact: true,
|
|
175
|
+
orderFormFields: [],
|
|
176
|
+
},
|
|
177
|
+
SwedbankPay: {
|
|
178
|
+
orderFormFields: [
|
|
179
|
+
{
|
|
180
|
+
name: OrderModuleFiledNameEnum.name,
|
|
181
|
+
label: 'Name',
|
|
182
|
+
required: false,
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: OrderModuleFiledNameEnum.phoneNumber,
|
|
186
|
+
label: 'Phone',
|
|
187
|
+
readOnly: false,
|
|
188
|
+
required: false,
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: OrderModuleFiledNameEnum.email,
|
|
192
|
+
label: 'Email',
|
|
193
|
+
required: true,
|
|
194
|
+
readOnly: !!userEmail,
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
},
|
|
198
|
+
Invoice: {
|
|
199
|
+
orderFormFields: [
|
|
200
|
+
{
|
|
201
|
+
name: OrderModuleFiledNameEnum.address,
|
|
202
|
+
label: 'Address',
|
|
203
|
+
required: false,
|
|
204
|
+
readOnly: false,
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
},
|
|
208
|
+
Email: {
|
|
209
|
+
orderFormFields: [
|
|
210
|
+
{
|
|
211
|
+
name: OrderModuleFiledNameEnum.address,
|
|
212
|
+
label: 'Address',
|
|
213
|
+
required: false,
|
|
214
|
+
readOnly: false,
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
},
|
|
218
|
+
EHF: {
|
|
219
|
+
orderFormFields: [
|
|
220
|
+
{
|
|
221
|
+
name: OrderModuleFiledNameEnum.address,
|
|
222
|
+
label: 'Address',
|
|
223
|
+
required: false,
|
|
224
|
+
readOnly: false,
|
|
225
|
+
},
|
|
226
|
+
],
|
|
227
|
+
},
|
|
228
|
+
OIO: {
|
|
229
|
+
orderFormFields: [
|
|
230
|
+
{
|
|
231
|
+
name: OrderModuleFiledNameEnum.address,
|
|
232
|
+
label: 'Address',
|
|
233
|
+
required: false,
|
|
234
|
+
readOnly: false,
|
|
235
|
+
},
|
|
236
|
+
],
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
invoiceAddressSelection: {
|
|
240
|
+
enabled: true,
|
|
241
|
+
label: 'Invoice Address',
|
|
242
|
+
fields: [
|
|
243
|
+
{
|
|
244
|
+
name: OrderModuleFiledNameEnum.invoiceAddress,
|
|
245
|
+
label: 'Address',
|
|
246
|
+
required: false,
|
|
247
|
+
readOnly: false,
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
},
|
|
251
|
+
settings: {
|
|
252
|
+
submitButtonText: 'Continue',
|
|
253
|
+
backButtonText: 'Back',
|
|
254
|
+
verifyButtonText: 'Verify',
|
|
255
|
+
organizationNumberLabel: 'CVR',
|
|
256
|
+
glnLabel: 'GLN/EAN',
|
|
257
|
+
paymentMethodLabel: 'Select Payment Method',
|
|
258
|
+
errorReqMsg: 'This field is required!',
|
|
259
|
+
errorInvalidEmailMsg: 'Invalid email address!',
|
|
260
|
+
errorInvalidPhoneMsg: 'Invalid phone number!',
|
|
261
|
+
successText: 'Success message',
|
|
262
|
+
failureText: 'Failed message',
|
|
263
|
+
orderDefaultValues: {
|
|
264
|
+
name,
|
|
265
|
+
email: userEmail || '',
|
|
266
|
+
phoneNumber: '',
|
|
267
|
+
city,
|
|
268
|
+
country,
|
|
269
|
+
zip: postalCode,
|
|
270
|
+
address: streetAddress,
|
|
271
|
+
paymentMethod: undefined,
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
return config as ConfigType;
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
import { FC, useEffect, useRef } from 'react';
|
|
281
|
+
import { orderComponent } from '@infosoftas/s4-orders-js-sdk/src/index';
|
|
282
|
+
|
|
283
|
+
import { prepareConfig } from 'Utils/moduleConfig';
|
|
284
|
+
|
|
285
|
+
const ORDER_PLACE_ID = 'sdk-order';
|
|
286
|
+
|
|
287
|
+
const OrderPlace: FC = ({userEmail, userId, name, city, country, postalCode, streetAddress}) => {
|
|
288
|
+
const moduleMount = useRef(false);
|
|
289
|
+
|
|
290
|
+
useEffect(() => {
|
|
291
|
+
if (!moduleMount.current && idTokenClaims) {
|
|
292
|
+
moduleMount.current = true;
|
|
293
|
+
const config = prepareConfig({
|
|
294
|
+
apiKey: process.env.API_KEY || '',
|
|
295
|
+
apiUrl: process.env.ORDER_SDK_API_URL || '',
|
|
296
|
+
userId: userId || '',
|
|
297
|
+
subscriberId: userEmail || '',
|
|
298
|
+
identityProviderId: process.env.IDENTITY_PROVIDER_ID || '',
|
|
299
|
+
templatePackageId: process.env.TEMPLATE_PACKAGE_ID || '',
|
|
300
|
+
selfServiceUrl: process.env.SELF_SERVICE_URL || '',
|
|
301
|
+
organizationId: process.env.ORGANIZATION_ID || '',
|
|
302
|
+
userEmail: userEmail || '',
|
|
303
|
+
name: name,
|
|
304
|
+
city: city,
|
|
305
|
+
country: country,
|
|
306
|
+
postalCode: postalCode,
|
|
307
|
+
streetAddress: streetAddress,
|
|
308
|
+
});
|
|
309
|
+
orderComponent?.remove();
|
|
310
|
+
orderComponent?.init(config);
|
|
311
|
+
}
|
|
312
|
+
}, [userEmail, userId, name, city, country, postalCode, streetAddress]);
|
|
313
|
+
|
|
314
|
+
return (
|
|
315
|
+
<div
|
|
316
|
+
id={ORDER_PLACE_ID}
|
|
317
|
+
className="w-100 order-wrapper"
|
|
318
|
+
data-testid="order-place-id"
|
|
319
|
+
/>
|
|
320
|
+
);
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
export default OrderPlace;
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
<!-- prettier-ignore -->
|
|
327
|
+
| Option | Default | Description |
|
|
328
|
+
| --------------------- | :----------------------------------------------------------------------------: | -------------------------: |
|
|
329
|
+
| moduleTitle | '' | module title |
|
|
330
|
+
| apiKey | '' | order api key |
|
|
331
|
+
| apiUrl | '' | order api url |
|
|
332
|
+
| templatePackageId | '' | template package id |
|
|
333
|
+
| subscriberId | '' | subscriber id |
|
|
334
|
+
| identityProviderId | '' | identity provider id |
|
|
335
|
+
| organizationId | '' | organization id |
|
|
336
|
+
| redirectUrl | window.location.href | redirect url |
|
|
337
|
+
| showIframe | false | show credit card in iframe |
|
|
338
|
+
| paymentMethodsOptions | orderFormFields: [{name: 'phone, required: false, readOnly: false, label: ''}] | default form fields |
|
|
339
|
+
| availablePaymentMethods | [] | available payment methods |
|
|
340
|
+
| language | 'en-US' | language |
|
|
341
|
+
| merchantAgreementUrl | '' | vipps and MobilePay property |
|
|
342
|
+
| settings | {successText: 'Order successful completed!',failureText: 'Something went wrong!',submitButtonText: 'Start',backButtonText: 'Back',verifyButtonText: 'Verify',organizationNumberLabel: 'CVR',glnLabel: 'GLN',paymentMethodLabel:'Select Payment Method',} | label and text properties |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"filename":"C:\\Code\\repos\\s4-orders-js-sdk\\orders-module\\__azurite_db_blob__.json","collections":[{"name":"$SERVICES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{},"constraints":null,"uniqueNames":["accountName"],"transforms":{},"objType":"$SERVICES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$CONTAINERS_COLLECTION$","data":[{"accountName":"devstoreaccount1","name":"azure-webjobs-secrets","properties":{"etag":"\"0x241ECCC639EC420\"","lastModified":"2024-12-05T13:29:00.197Z","leaseStatus":"unlocked","leaseState":"available","hasImmutabilityPolicy":false,"hasLegalHold":false},"meta":{"revision":0,"created":1733405340199,"version":0},"$loki":1},{"accountName":"devstoreaccount1","name":"azure-webjobs-hosts","properties":{"etag":"\"0x21BCE1F25F7DC40\"","lastModified":"2024-12-05T13:29:06.224Z","leaseStatus":"unlocked","leaseState":"available","hasImmutabilityPolicy":false,"hasLegalHold":false},"meta":{"revision":0,"created":1733405346225,"version":0},"$loki":2}],"idIndex":null,"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[1,0]},"name":{"name":"name","dirty":false,"values":[1,0]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$CONTAINERS_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":2,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$BLOBS_COLLECTION$","data":[{"deleted":false,"accountName":"devstoreaccount1","containerName":"azure-webjobs-secrets","name":"esbbach1-505371708/host.json","properties":{"creationTime":"2024-12-05T13:29:00.786Z","lastModified":"2024-12-05T13:29:00.786Z","etag":"\"0x1F3C1FE0A326700\"","contentLength":632,"contentType":"application/octet-stream","contentMD5":{"type":"Buffer","data":[105,188,18,11,16,253,127,42,77,4,114,189,122,185,129,100]},"blobType":"BlockBlob","leaseStatus":"unlocked","leaseState":"available","serverEncrypted":true,"accessTier":"Hot","accessTierInferred":true,"accessTierChangeTime":"2024-12-05T13:29:00.786Z"},"snapshot":"","isCommitted":true,"persistency":{"id":"6814b4e2-aa0c-49d2-9ea5-e8893c0aa38d","offset":474,"count":632},"meta":{"revision":0,"created":1733405340791,"version":0},"$loki":2},{"deleted":false,"metadata":{"FunctionInstance":"000000000000000000000000ECDCC010"},"accountName":"devstoreaccount1","containerName":"azure-webjobs-hosts","name":"locks/esbbach1-505371708/host","properties":{"creationTime":"2024-12-05T13:29:27.810Z","lastModified":"2024-12-05T13:29:27.935Z","etag":"\"0x24F90CC989B1D40\"","contentLength":0,"contentType":"application/octet-stream","contentMD5":{"type":"Buffer","data":[212,29,140,217,143,0,178,4,233,128,9,152,236,248,66,126]},"blobType":"BlockBlob","leaseStatus":"locked","leaseState":"leased","serverEncrypted":true,"accessTier":"Hot","accessTierInferred":true,"accessTierChangeTime":"2024-12-05T13:29:27.810Z","leaseDuration":"fixed"},"snapshot":"","isCommitted":true,"persistency":{"id":"6814b4e2-aa0c-49d2-9ea5-e8893c0aa38d","offset":1106,"count":0},"meta":{"revision":9,"created":1733405367813,"version":0,"updated":1733405451971},"$loki":3,"leaseId":"000000000000000000000000ECDCC010","leaseExpireTime":"2024-12-05T13:31:06.970Z","leaseDurationSeconds":15}],"idIndex":[2,3],"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[1,0]},"containerName":{"name":"containerName","dirty":false,"values":[1,0]},"name":{"name":"name","dirty":false,"values":[0,1]},"snapshot":{"name":"snapshot","dirty":false,"values":[1,0]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$BLOBS_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":3,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$BLOCKS_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[]},"containerName":{"name":"containerName","dirty":false,"values":[]},"blobName":{"name":"blobName","dirty":false,"values":[]},"name":{"name":"name","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$BLOCKS_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":5000,"autosaveHandle":null,"throttledSaves":true,"options":{"persistenceMethod":"fs","autosave":true,"autosaveInterval":5000,"serializationMethod":"normal","destructureDelimiter":"$<\n"},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"filename":"C:\\Code\\repos\\s4-orders-js-sdk\\orders-module\\__azurite_db_blob_extent__.json","collections":[{"name":"$EXTENTS_COLLECTION$","data":[{"id":"6814b4e2-aa0c-49d2-9ea5-e8893c0aa38d","locationId":"Default","path":"6814b4e2-aa0c-49d2-9ea5-e8893c0aa38d","size":1106,"lastModifiedInMS":1733405340529,"meta":{"revision":2,"created":1733405340529,"version":0,"updated":1733405367812},"$loki":1,"LastModifyInMS":1733405367812}],"idIndex":[1],"binaryIndices":{"id":{"name":"id","dirty":false,"values":[0]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$EXTENTS_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":1,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":5000,"autosaveHandle":null,"throttledSaves":true,"options":{"persistenceMethod":"fs","autosave":true,"autosaveInterval":5000,"serializationMethod":"normal","destructureDelimiter":"$<\n"},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"filename":"C:\\Code\\repos\\s4-orders-js-sdk\\orders-module\\__azurite_db_queue__.json","collections":[{"name":"$SERVICES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{},"constraints":null,"uniqueNames":["accountName"],"transforms":{},"objType":"$SERVICES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$QUEUES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[]},"name":{"name":"name","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$QUEUES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$MESSAGES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"accountName":{"name":"accountName","dirty":false,"values":[]},"queueName":{"name":"queueName","dirty":false,"values":[]},"messageId":{"name":"messageId","dirty":false,"values":[]},"visibleTime":{"name":"visibleTime","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$MESSAGES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":5000,"autosaveHandle":null,"throttledSaves":true,"options":{"persistenceMethod":"fs","autosave":true,"autosaveInterval":5000,"serializationMethod":"normal","destructureDelimiter":"$<\n"},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"filename":"C:\\Code\\repos\\s4-orders-js-sdk\\orders-module\\__azurite_db_queue_extent__.json","collections":[{"name":"$EXTENTS_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"id":{"name":"id","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$EXTENTS_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":5000,"autosaveHandle":null,"throttledSaves":true,"options":{"persistenceMethod":"fs","autosave":true,"autosaveInterval":5000,"serializationMethod":"normal","destructureDelimiter":"$<\n"},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"filename":"C:\\Code\\repos\\s4-orders-js-sdk\\orders-module\\__azurite_db_table__.json","collections":[{"name":"$TABLES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{"account":{"name":"account","dirty":false,"values":[]},"table":{"name":"table","dirty":false,"values":[]}},"constraints":null,"uniqueNames":[],"transforms":{},"objType":"$TABLES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]},{"name":"$SERVICES_COLLECTION$","data":[],"idIndex":null,"binaryIndices":{},"constraints":null,"uniqueNames":["accountName"],"transforms":{},"objType":"$SERVICES_COLLECTION$","dirty":false,"cachedIndex":null,"cachedBinaryIndex":null,"cachedData":null,"adaptiveBinaryIndices":true,"transactional":false,"cloneObjects":false,"cloneMethod":"parse-stringify","asyncListeners":false,"disableMeta":false,"disableChangesApi":true,"disableDeltaChangesApi":true,"autoupdate":false,"serializableIndices":true,"disableFreeze":true,"ttl":null,"maxId":0,"DynamicViews":[],"events":{"insert":[],"update":[],"pre-insert":[],"pre-update":[],"close":[],"flushbuffer":[],"error":[],"delete":[null],"warning":[null]},"changes":[],"dirtyIds":[]}],"databaseVersion":1.5,"engineVersion":1.5,"autosave":true,"autosaveInterval":5000,"autosaveHandle":null,"throttledSaves":true,"options":{"persistenceMethod":"fs","autosave":true,"autosaveInterval":5000,"serializationMethod":"normal","destructureDelimiter":"$<\n"},"persistenceMethod":"fs","persistenceAdapter":null,"verbose":false,"events":{"init":[null],"loaded":[],"flushChanges":[],"close":[],"changes":[],"warning":[]},"ENV":"NODEJS"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"masterKey": {
|
|
3
|
+
"name": "master",
|
|
4
|
+
"value": "7wseiRzKpd7oQ1yO5r--CLVrm5sMbjHltVxtApzUCDoGAzFuC9p3Og==",
|
|
5
|
+
"encrypted": false
|
|
6
|
+
},
|
|
7
|
+
"functionKeys": [
|
|
8
|
+
{
|
|
9
|
+
"name": "default",
|
|
10
|
+
"value": "lvuTAIZSep4sDwZXlWqQklWBsEVhwCKbC3msSvs4C-TZAzFu_mt4Yg==",
|
|
11
|
+
"encrypted": false
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"systemKeys": [],
|
|
15
|
+
"hostName": "localhost:7161",
|
|
16
|
+
"instanceId": "000000000000000000000000ECDCC010",
|
|
17
|
+
"source": "runtime",
|
|
18
|
+
"decryptionKeyId": ""
|
|
19
|
+
}{
|
|
20
|
+
"masterKey": {
|
|
21
|
+
"name": "master",
|
|
22
|
+
"value": "7wseiRzKpd7oQ1yO5r--CLVrm5sMbjHltVxtApzUCDoGAzFuC9p3Og==",
|
|
23
|
+
"encrypted": false
|
|
24
|
+
},
|
|
25
|
+
"functionKeys": [
|
|
26
|
+
{
|
|
27
|
+
"name": "default",
|
|
28
|
+
"value": "lvuTAIZSep4sDwZXlWqQklWBsEVhwCKbC3msSvs4C-TZAzFu_mt4Yg==",
|
|
29
|
+
"encrypted": false
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"systemKeys": [
|
|
33
|
+
{
|
|
34
|
+
"name": "eventgrid_extension",
|
|
35
|
+
"value": "daOhefCvoXVARuY2Ho-3bfGYK21hNkbpzVVio4deylC6AzFu4jvTMA==",
|
|
36
|
+
"encrypted": false
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"hostName": "localhost:7161",
|
|
40
|
+
"instanceId": "000000000000000000000000ECDCC010",
|
|
41
|
+
"source": "runtime",
|
|
42
|
+
"decryptionKeyId": ""
|
|
43
|
+
}
|
package/package.json
CHANGED
package/src/App.tsx
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { FC, useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
FormTypeEnum,
|
|
5
|
+
MessageEventTypeEnum,
|
|
6
|
+
PaymentMethodEnum,
|
|
7
|
+
} from './enums/general';
|
|
4
8
|
import useMessageEvent from './hooks/useMessageEvent';
|
|
5
9
|
import OrderForm from './components/OrderForm/OrderForm';
|
|
10
|
+
import OIOForm from './components/OIOForm/OIOForm';
|
|
11
|
+
import EHFForm from './components/EHFForm/EHFForm';
|
|
6
12
|
import Loader from './components/Loader/Loader';
|
|
7
13
|
import MainIframe from './components/MainIframe/MainIframe';
|
|
8
14
|
import Alert from './components/Alert/Alert';
|
|
@@ -35,6 +41,11 @@ const App: FC<ConfigType> = ({
|
|
|
35
41
|
successText: 'Order successful completed!',
|
|
36
42
|
failureText: 'Something went wrong!',
|
|
37
43
|
buttonText: 'Start',
|
|
44
|
+
submitButtonText: 'Start',
|
|
45
|
+
backButtonText: 'Back',
|
|
46
|
+
verifyButtonText: 'Verify',
|
|
47
|
+
organizationNumberLabel: 'CVR',
|
|
48
|
+
glnLabel: 'GLN',
|
|
38
49
|
},
|
|
39
50
|
}) => {
|
|
40
51
|
const [loading, setLoading] = useState<boolean>(false);
|
|
@@ -46,6 +57,7 @@ const App: FC<ConfigType> = ({
|
|
|
46
57
|
const [failedMsg, setFailedMsg] = useState<string>('');
|
|
47
58
|
const [errorsMsg, setErrorsMsg] = useState<string[]>([]);
|
|
48
59
|
const [orderInfo, setOrderInfo] = useState<OrderInfoType | null>(null);
|
|
60
|
+
const [formType, setFormType] = useState(FormTypeEnum.ORDER);
|
|
49
61
|
|
|
50
62
|
useEffect(() => {
|
|
51
63
|
if (apiKey) {
|
|
@@ -108,6 +120,7 @@ const App: FC<ConfigType> = ({
|
|
|
108
120
|
setIsFailed(true);
|
|
109
121
|
setLoading(false);
|
|
110
122
|
setShowOrderForm(true);
|
|
123
|
+
setFormType(FormTypeEnum.ORDER);
|
|
111
124
|
}
|
|
112
125
|
};
|
|
113
126
|
|
|
@@ -191,18 +204,15 @@ const App: FC<ConfigType> = ({
|
|
|
191
204
|
data?.paymentMethod === PaymentMethodEnum.Email ||
|
|
192
205
|
data?.paymentMethod === PaymentMethodEnum.Invoice
|
|
193
206
|
) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
top?.location?.origin || '*'
|
|
204
|
-
);
|
|
205
|
-
}
|
|
207
|
+
messageCallback({
|
|
208
|
+
orderId: data.orderId || orderId || '',
|
|
209
|
+
agreementId: '',
|
|
210
|
+
orderInfo: data || orderInfo || null,
|
|
211
|
+
});
|
|
212
|
+
} else if (data?.paymentMethod === PaymentMethodEnum.EHF) {
|
|
213
|
+
setFormType(FormTypeEnum.EHF);
|
|
214
|
+
} else if (data?.paymentMethod === PaymentMethodEnum.OIO) {
|
|
215
|
+
setFormType(FormTypeEnum.OIO);
|
|
206
216
|
} else if (url) {
|
|
207
217
|
if (
|
|
208
218
|
showIframe &&
|
|
@@ -219,6 +229,18 @@ const App: FC<ConfigType> = ({
|
|
|
219
229
|
setIframeSrc(null);
|
|
220
230
|
};
|
|
221
231
|
|
|
232
|
+
const handleInvoiceBack = () => {
|
|
233
|
+
setFormType(FormTypeEnum.ORDER);
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const handleInvoiceForm = async () => {
|
|
237
|
+
await messageCallback({
|
|
238
|
+
orderId: orderId || '',
|
|
239
|
+
agreementId: '',
|
|
240
|
+
orderInfo: orderInfo || null,
|
|
241
|
+
});
|
|
242
|
+
};
|
|
243
|
+
|
|
222
244
|
if (window !== top) {
|
|
223
245
|
return null;
|
|
224
246
|
}
|
|
@@ -238,27 +260,67 @@ const App: FC<ConfigType> = ({
|
|
|
238
260
|
</div>
|
|
239
261
|
)}
|
|
240
262
|
{!iframeSrc && showOrderForm && (
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
263
|
+
<>
|
|
264
|
+
{formType === FormTypeEnum.OIO && (
|
|
265
|
+
<OIOForm
|
|
266
|
+
onBack={handleInvoiceBack}
|
|
267
|
+
callback={handleInvoiceForm}
|
|
268
|
+
backButtonText={settings?.backButtonText}
|
|
269
|
+
verifyButtonText={settings?.verifyButtonText}
|
|
270
|
+
organizationNumberLabel={
|
|
271
|
+
settings?.organizationNumberLabel
|
|
272
|
+
}
|
|
273
|
+
glnLabel={settings?.glnLabel}
|
|
274
|
+
/>
|
|
275
|
+
)}
|
|
276
|
+
{formType === FormTypeEnum.EHF && (
|
|
277
|
+
<EHFForm
|
|
278
|
+
onBack={handleInvoiceBack}
|
|
279
|
+
callback={handleInvoiceForm}
|
|
280
|
+
backButtonText={settings?.backButtonText}
|
|
281
|
+
verifyButtonText={settings?.verifyButtonText}
|
|
282
|
+
organizationNumberLabel={
|
|
283
|
+
settings?.organizationNumberLabel
|
|
284
|
+
}
|
|
285
|
+
/>
|
|
286
|
+
)}
|
|
287
|
+
{formType !== FormTypeEnum.OIO &&
|
|
288
|
+
formType !== FormTypeEnum.EHF && (
|
|
289
|
+
<OrderForm
|
|
290
|
+
callback={handleForm}
|
|
291
|
+
templatePackageId={templatePackageId}
|
|
292
|
+
subscriberId={subscriberId}
|
|
293
|
+
userId={userId}
|
|
294
|
+
identityProviderId={identityProviderId}
|
|
295
|
+
organizationId={organizationId}
|
|
296
|
+
paymentMethods={availablePaymentMethods}
|
|
297
|
+
submitButtonText={
|
|
298
|
+
settings?.submitButtonText
|
|
299
|
+
}
|
|
300
|
+
paymentMethodLabel={
|
|
301
|
+
settings?.paymentMethodLabel
|
|
302
|
+
}
|
|
303
|
+
errorReqMsg={settings?.errorReqMsg}
|
|
304
|
+
errorInvalidEmailMsg={
|
|
305
|
+
settings?.errorInvalidEmailMsg
|
|
306
|
+
}
|
|
307
|
+
errorInvalidPhoneMsg={
|
|
308
|
+
settings?.errorInvalidPhoneMsg
|
|
309
|
+
}
|
|
310
|
+
defaultValues={settings?.orderDefaultValues}
|
|
311
|
+
redirectUrl={redirectUrl}
|
|
312
|
+
showIframe={showIframe}
|
|
313
|
+
paymentMethodsOptions={
|
|
314
|
+
paymentMethodsOptions
|
|
315
|
+
}
|
|
316
|
+
language={language}
|
|
317
|
+
merchantAgreementUrl={merchantAgreementUrl}
|
|
318
|
+
invoiceAddressSelection={
|
|
319
|
+
invoiceAddressSelection
|
|
320
|
+
}
|
|
321
|
+
/>
|
|
322
|
+
)}
|
|
323
|
+
</>
|
|
262
324
|
)}
|
|
263
325
|
{showIframe && <MainIframe iframeSrc={iframeSrc} />}
|
|
264
326
|
{isConfirmed && (
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import fetcher from '../utils/fetcher';
|
|
2
|
+
|
|
3
|
+
type RequestInvoiceLookupType = {
|
|
4
|
+
network: string;
|
|
5
|
+
value: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
type InvoiceLookupResponseType = {
|
|
9
|
+
recievesInvoice: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const invoiceLookup = (
|
|
13
|
+
body: RequestInvoiceLookupType
|
|
14
|
+
): Promise<InvoiceLookupResponseType> =>
|
|
15
|
+
fetcher<InvoiceLookupResponseType, RequestInvoiceLookupType>({
|
|
16
|
+
method: 'POST',
|
|
17
|
+
url: '/invoicelookup',
|
|
18
|
+
headers: {
|
|
19
|
+
'S4-ORDERS-API-KEY':
|
|
20
|
+
sessionStorage.getItem('sdk_api_key') ||
|
|
21
|
+
process.env.API_KEY ||
|
|
22
|
+
'',
|
|
23
|
+
},
|
|
24
|
+
body,
|
|
25
|
+
}) as Promise<InvoiceLookupResponseType>;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { FC, useState } from 'react';
|
|
2
|
+
import { FormProvider, useForm, SubmitHandler } from 'react-hook-form';
|
|
3
|
+
|
|
4
|
+
import { invoiceLookup } from '../../api/InvoiceApi';
|
|
5
|
+
import Alert from '../Alert/Alert';
|
|
6
|
+
import Button from '../Button/Button';
|
|
7
|
+
import InputField from '../FormFields/InputField';
|
|
8
|
+
import {
|
|
9
|
+
prepareErrorMessage,
|
|
10
|
+
prepareErrorsArrayMessage,
|
|
11
|
+
} from '../../utils/helper';
|
|
12
|
+
import { InvoiceLookupNetworkEnum } from '../../enums/general';
|
|
13
|
+
import { ErrorsMsg } from '../../types/general';
|
|
14
|
+
|
|
15
|
+
type Props = {
|
|
16
|
+
callback: (value: string) => void;
|
|
17
|
+
onBack: () => void;
|
|
18
|
+
backButtonText?: string;
|
|
19
|
+
verifyButtonText?: string;
|
|
20
|
+
organizationNumberLabel?: string;
|
|
21
|
+
className?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type EHFFormInputsType = {
|
|
25
|
+
organizationNumber: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const initialData = {
|
|
29
|
+
organizationNumber: '',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const EHFForm: FC<Props> = ({
|
|
33
|
+
callback,
|
|
34
|
+
onBack,
|
|
35
|
+
backButtonText = '',
|
|
36
|
+
verifyButtonText = '',
|
|
37
|
+
organizationNumberLabel = '',
|
|
38
|
+
className = '',
|
|
39
|
+
}) => {
|
|
40
|
+
const [loading, setLoading] = useState<boolean>(false);
|
|
41
|
+
const [apiErrorMsg, setApiErrorMsg] = useState<string>('');
|
|
42
|
+
const [errorsMsg, setErrorsMsg] = useState<string[]>([]);
|
|
43
|
+
|
|
44
|
+
const methods = useForm<EHFFormInputsType>({
|
|
45
|
+
defaultValues: {
|
|
46
|
+
...initialData,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const {
|
|
51
|
+
handleSubmit,
|
|
52
|
+
formState: { errors },
|
|
53
|
+
} = methods;
|
|
54
|
+
|
|
55
|
+
const onSubmit: SubmitHandler<EHFFormInputsType> = async (
|
|
56
|
+
data
|
|
57
|
+
): Promise<void> => {
|
|
58
|
+
setApiErrorMsg('');
|
|
59
|
+
setErrorsMsg([]);
|
|
60
|
+
setLoading(true);
|
|
61
|
+
try {
|
|
62
|
+
await invoiceLookup({
|
|
63
|
+
network: InvoiceLookupNetworkEnum.EHF,
|
|
64
|
+
value: data.organizationNumber,
|
|
65
|
+
});
|
|
66
|
+
callback(data.organizationNumber);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
setApiErrorMsg(prepareErrorMessage(error as Error));
|
|
69
|
+
setErrorsMsg(
|
|
70
|
+
prepareErrorsArrayMessage(
|
|
71
|
+
(
|
|
72
|
+
error as {
|
|
73
|
+
errors: ErrorsMsg;
|
|
74
|
+
}
|
|
75
|
+
)?.errors
|
|
76
|
+
)
|
|
77
|
+
);
|
|
78
|
+
} finally {
|
|
79
|
+
setLoading(false);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const handleBack = () => {
|
|
84
|
+
onBack?.();
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<FormProvider {...methods}>
|
|
89
|
+
<form
|
|
90
|
+
className={`${className}`}
|
|
91
|
+
onSubmit={handleSubmit(onSubmit)}
|
|
92
|
+
data-testid="ehf-form-id"
|
|
93
|
+
>
|
|
94
|
+
<InputField
|
|
95
|
+
name="organizationNumber"
|
|
96
|
+
label={organizationNumberLabel}
|
|
97
|
+
required
|
|
98
|
+
readOnly={false}
|
|
99
|
+
errors={errors}
|
|
100
|
+
/>
|
|
101
|
+
<div className="d-flex justify-center flex-wrap gap-2">
|
|
102
|
+
<Button
|
|
103
|
+
type="button"
|
|
104
|
+
btnType="default"
|
|
105
|
+
disable={loading}
|
|
106
|
+
buttonText={backButtonText}
|
|
107
|
+
onClick={handleBack}
|
|
108
|
+
/>
|
|
109
|
+
|
|
110
|
+
<Button
|
|
111
|
+
type="submit"
|
|
112
|
+
loading={loading}
|
|
113
|
+
buttonText={verifyButtonText}
|
|
114
|
+
/>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
{apiErrorMsg && <Alert className="mt-2" msg={apiErrorMsg} />}
|
|
118
|
+
{errorsMsg?.length > 0 &&
|
|
119
|
+
errorsMsg.map((i) => <Alert className="mt-2" msg={i} />)}
|
|
120
|
+
</form>
|
|
121
|
+
</FormProvider>
|
|
122
|
+
);
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export default EHFForm;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { FC, useState } from 'react';
|
|
2
|
+
import { FormProvider, useForm, SubmitHandler } from 'react-hook-form';
|
|
3
|
+
|
|
4
|
+
import { invoiceLookup } from '../../api/InvoiceApi';
|
|
5
|
+
import Alert from '../Alert/Alert';
|
|
6
|
+
import Button from '../Button/Button';
|
|
7
|
+
import InputField from '../FormFields/InputField';
|
|
8
|
+
import {
|
|
9
|
+
prepareErrorMessage,
|
|
10
|
+
prepareErrorsArrayMessage,
|
|
11
|
+
} from '../../utils/helper';
|
|
12
|
+
import { InvoiceLookupNetworkEnum } from '../../enums/general';
|
|
13
|
+
import { ErrorsMsg } from '../../types/general';
|
|
14
|
+
|
|
15
|
+
type Props = {
|
|
16
|
+
callback: (value: string) => void;
|
|
17
|
+
onBack: () => void;
|
|
18
|
+
backButtonText?: string;
|
|
19
|
+
verifyButtonText?: string;
|
|
20
|
+
organizationNumberLabel?: string;
|
|
21
|
+
glnLabel?: string;
|
|
22
|
+
className?: string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type OIOFormInputsType = {
|
|
26
|
+
cvr: string;
|
|
27
|
+
gln: string;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const initialData = {
|
|
31
|
+
cvr: '',
|
|
32
|
+
gln: '',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const EHFForm: FC<Props> = ({
|
|
36
|
+
callback,
|
|
37
|
+
onBack,
|
|
38
|
+
backButtonText = '',
|
|
39
|
+
verifyButtonText = '',
|
|
40
|
+
organizationNumberLabel = '',
|
|
41
|
+
glnLabel = '',
|
|
42
|
+
className = '',
|
|
43
|
+
}) => {
|
|
44
|
+
const [loading, setLoading] = useState<boolean>(false);
|
|
45
|
+
const [apiErrorMsg, setApiErrorMsg] = useState<string>('');
|
|
46
|
+
const [errorsMsg, setErrorsMsg] = useState<string[]>([]);
|
|
47
|
+
|
|
48
|
+
const methods = useForm<OIOFormInputsType>({
|
|
49
|
+
defaultValues: {
|
|
50
|
+
...initialData,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const {
|
|
55
|
+
handleSubmit,
|
|
56
|
+
watch,
|
|
57
|
+
formState: { errors },
|
|
58
|
+
} = methods;
|
|
59
|
+
|
|
60
|
+
const cvr = watch('cvr');
|
|
61
|
+
const gln = watch('gln');
|
|
62
|
+
|
|
63
|
+
const onSubmit: SubmitHandler<OIOFormInputsType> = async (
|
|
64
|
+
data
|
|
65
|
+
): Promise<void> => {
|
|
66
|
+
setApiErrorMsg('');
|
|
67
|
+
setErrorsMsg([]);
|
|
68
|
+
setLoading(true);
|
|
69
|
+
try {
|
|
70
|
+
await invoiceLookup({
|
|
71
|
+
network: data.gln
|
|
72
|
+
? InvoiceLookupNetworkEnum.OIO_GLN
|
|
73
|
+
: InvoiceLookupNetworkEnum.OIO_Danish_CVR,
|
|
74
|
+
value: data.gln || data.cvr,
|
|
75
|
+
});
|
|
76
|
+
callback(data.gln || data.cvr);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
setApiErrorMsg(prepareErrorMessage(error as Error));
|
|
79
|
+
setErrorsMsg(
|
|
80
|
+
prepareErrorsArrayMessage(
|
|
81
|
+
(
|
|
82
|
+
error as {
|
|
83
|
+
errors: ErrorsMsg;
|
|
84
|
+
}
|
|
85
|
+
)?.errors
|
|
86
|
+
)
|
|
87
|
+
);
|
|
88
|
+
} finally {
|
|
89
|
+
setLoading(false);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const handleBack = () => {
|
|
94
|
+
onBack?.();
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<FormProvider {...methods}>
|
|
99
|
+
<form
|
|
100
|
+
className={`${className}`}
|
|
101
|
+
onSubmit={handleSubmit(onSubmit)}
|
|
102
|
+
data-testid="oio-form-id"
|
|
103
|
+
>
|
|
104
|
+
<InputField
|
|
105
|
+
name="cvr"
|
|
106
|
+
label={organizationNumberLabel}
|
|
107
|
+
required={!gln}
|
|
108
|
+
readOnly={false}
|
|
109
|
+
errors={!gln ? errors : undefined}
|
|
110
|
+
/>
|
|
111
|
+
<InputField
|
|
112
|
+
name="gln"
|
|
113
|
+
label={glnLabel}
|
|
114
|
+
required={!cvr}
|
|
115
|
+
readOnly={false}
|
|
116
|
+
errors={!cvr ? errors : undefined}
|
|
117
|
+
/>
|
|
118
|
+
<div className="d-flex justify-center flex-wrap gap-2">
|
|
119
|
+
<Button
|
|
120
|
+
type="button"
|
|
121
|
+
btnType="default"
|
|
122
|
+
disable={loading}
|
|
123
|
+
buttonText={backButtonText}
|
|
124
|
+
onClick={handleBack}
|
|
125
|
+
/>
|
|
126
|
+
|
|
127
|
+
<Button
|
|
128
|
+
type="submit"
|
|
129
|
+
loading={loading}
|
|
130
|
+
buttonText={verifyButtonText}
|
|
131
|
+
/>
|
|
132
|
+
</div>
|
|
133
|
+
{apiErrorMsg && <Alert className="mt-2" msg={apiErrorMsg} />}
|
|
134
|
+
{errorsMsg?.length > 0 &&
|
|
135
|
+
errorsMsg.map((i) => <Alert className="mt-2" msg={i} />)}
|
|
136
|
+
</form>
|
|
137
|
+
</FormProvider>
|
|
138
|
+
);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export default EHFForm;
|
|
@@ -43,7 +43,7 @@ type Props = {
|
|
|
43
43
|
paymentMethodsOptions?: PaymentMethodOptionsType;
|
|
44
44
|
defaultValues?: OrderFormInputsType;
|
|
45
45
|
paymentMethods?: { label: string; value: PaymentMethodEnum }[];
|
|
46
|
-
|
|
46
|
+
submitButtonText?: string;
|
|
47
47
|
paymentMethodLabel?: string;
|
|
48
48
|
errorReqMsg?: string;
|
|
49
49
|
errorInvalidEmailMsg?: string;
|
|
@@ -83,7 +83,7 @@ const OrderForm: FC<Props> = ({
|
|
|
83
83
|
merchantAgreementUrl,
|
|
84
84
|
paymentMethods = [],
|
|
85
85
|
invoiceAddressSelection,
|
|
86
|
-
|
|
86
|
+
submitButtonText = 'Start',
|
|
87
87
|
paymentMethodLabel = 'Select Payment Method',
|
|
88
88
|
errorReqMsg = '',
|
|
89
89
|
errorInvalidEmailMsg = '',
|
|
@@ -311,7 +311,7 @@ const OrderForm: FC<Props> = ({
|
|
|
311
311
|
<Button
|
|
312
312
|
type="submit"
|
|
313
313
|
loading={loading}
|
|
314
|
-
buttonText={
|
|
314
|
+
buttonText={submitButtonText}
|
|
315
315
|
/>
|
|
316
316
|
<Alert className="mt-2" msg={apiErrorMsg} />
|
|
317
317
|
{errorsMsg?.length > 0 &&
|
package/src/enums/general.ts
CHANGED
|
@@ -16,3 +16,15 @@ export enum MessageEventTypeEnum {
|
|
|
16
16
|
CANCEL = 'cancel',
|
|
17
17
|
COMPLETE = 'complete',
|
|
18
18
|
}
|
|
19
|
+
|
|
20
|
+
export enum InvoiceLookupNetworkEnum {
|
|
21
|
+
EHF = '0192',
|
|
22
|
+
OIO_GLN = '0088',
|
|
23
|
+
OIO_Danish_CVR = '0096',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export enum FormTypeEnum {
|
|
27
|
+
ORDER = 'order',
|
|
28
|
+
EHF = 'EHF',
|
|
29
|
+
OIO = 'OIO',
|
|
30
|
+
}
|
package/src/types/general.ts
CHANGED
|
@@ -46,7 +46,11 @@ export type ConfigType = {
|
|
|
46
46
|
settings?: {
|
|
47
47
|
successText?: string;
|
|
48
48
|
failureText?: string;
|
|
49
|
-
|
|
49
|
+
submitButtonText?: string;
|
|
50
|
+
backButtonText?: string;
|
|
51
|
+
verifyButtonText?: string;
|
|
52
|
+
organizationNumberLabel?: string;
|
|
53
|
+
glnLabel?: string;
|
|
50
54
|
orderDefaultValues?: OrderFormInputsType;
|
|
51
55
|
paymentMethodLabel?: string;
|
|
52
56
|
errorReqMsg?: string;
|