quivio-transaction-processor 1.23.2 → 1.23.3-beta

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.
Files changed (27) hide show
  1. package/dist/emvPaymentProvider/EMVPaymentProvider.js +144 -63
  2. package/dist/emvPaymentProvider/EMVPaymentProvider.js.map +1 -1
  3. package/dist/emvPaymentProvider/types.d.ts +5 -2
  4. package/dist/example/EMVPaymentScreen.d.ts +4 -1
  5. package/dist/example/EMVPaymentScreen.js +101 -8
  6. package/dist/example/EMVPaymentScreen.js.map +1 -1
  7. package/dist/example/EMVSettingsScreen.js +4 -6
  8. package/dist/example/EMVSettingsScreen.js.map +1 -1
  9. package/dist/example/ExternalSystemsScreen.js +123 -3
  10. package/dist/example/ExternalSystemsScreen.js.map +1 -1
  11. package/dist/example/MainScreen.js +1 -1
  12. package/dist/example/MainScreen.js.map +1 -1
  13. package/dist/example/helper/deviceStore.d.ts +11 -0
  14. package/dist/example/helper/deviceStore.js +37 -0
  15. package/dist/example/helper/deviceStore.js.map +1 -0
  16. package/libs/emvCardReaderLib/src/main/java/com/rohan/emvcardreaderlib/POSTransactionExecutor.kt +29 -25
  17. package/libs/emvCardReaderLib/src/main/java/com/rohan/emvcardreaderlib/builder/DsiEMVRequestBuilder.kt +14 -7
  18. package/libs/emvCardReaderLib/src/main/java/com/rohan/emvcardreaderlib/manager/EMVPaymentManager.kt +28 -20
  19. package/libs/emvNative/src/main/java/com/quivio_transaction_processor/EMVPaymentManagerModule.kt +16 -7
  20. package/package.json +1 -1
  21. package/src/emvPaymentProvider/EMVPaymentProvider.tsx +105 -64
  22. package/src/emvPaymentProvider/types.ts +5 -2
  23. package/src/example/EMVPaymentScreen.tsx +75 -18
  24. package/src/example/EMVSettingsScreen.tsx +3 -5
  25. package/src/example/ExternalSystemsScreen.tsx +116 -27
  26. package/src/example/MainScreen.tsx +1 -1
  27. package/src/example/helper/deviceStore.ts +40 -0
@@ -34,9 +34,21 @@ const EMVPaymentProvider: React.FC<{ children: React.ReactNode }> = ({
34
34
  'onTransactionCancelled',
35
35
  ];
36
36
 
37
+ // Initialization Flag
38
+ const [isLibraryInitialized, setIsInitialzed] = useState(false);
39
+
37
40
  // Device Connected State
38
41
  const { isDeviceConnected } = useUSBDevice();
39
42
 
43
+ const [deviceSerialNumber, setDeviceSerialNumber] = useState('');
44
+
45
+ // Buffered Device Connection Flag
46
+ const [isIDTECHConnected, setIDTECHConnected] = useState(isDeviceConnected);
47
+
48
+ const disconnectTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(
49
+ null,
50
+ );
51
+
40
52
  // Show Display Message Cache
41
53
  const [displayMessage, setDisplayMessage] = useState('');
42
54
 
@@ -62,55 +74,59 @@ const EMVPaymentProvider: React.FC<{ children: React.ReactNode }> = ({
62
74
  Map<EMVEventName, Set<(payload: any) => void>>
63
75
  >(new Map());
64
76
 
65
- // Ref to maintain timeout during configuration
66
- // Because after a successfull EMVParamDownload
67
- // Device reboots which leads to USB disconnection
68
- // and connection
69
- const unconfigureTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(
70
- null,
71
- );
77
+ const clearDisconnectTimeout = () => {
78
+ if (disconnectTimeoutRef.current) {
79
+ clearTimeout(disconnectTimeoutRef.current);
80
+ disconnectTimeoutRef.current = null;
81
+ }
82
+ };
72
83
 
73
- // Ref to maintain device connection/disconnection
74
- const isDeviceConnectedRef = useRef<boolean>(isDeviceConnected);
84
+ useEffect(() => {
85
+ pushLog('PAYMENT LIBRARY', `SERIAL NUMBER: ${deviceSerialNumber}`);
86
+ }, [deviceSerialNumber]);
75
87
 
76
88
  useEffect(() => {
77
- // Always sync ref first
78
- isDeviceConnectedRef.current = isDeviceConnected;
89
+ // Stop already running timeout
90
+ clearDisconnectTimeout();
91
+
92
+ // If device connects -> update immediately
93
+ if (isDeviceConnected) {
94
+ setIDTECHConnected(true);
95
+ return;
96
+ }
79
97
 
80
- // Handle disconnect logic
81
- if (!isDeviceConnected) {
82
- unconfigureDevice(false);
98
+ // If device disconnects -> delay 1500ms
99
+ disconnectTimeoutRef.current = setTimeout(() => {
100
+ setIDTECHConnected(false);
101
+ }, 2000);
102
+
103
+ return () => {
104
+ clearDisconnectTimeout();
105
+ };
106
+ }, [isDeviceConnected]);
107
+
108
+ useEffect(() => {
109
+ if (!isIDTECHConnected) {
110
+ setIsConfigured(false);
83
111
  setConfigurationInProgress(false);
84
112
  setTransactionCurrentlyRunning(false);
85
113
  setCancellationRunning(false);
114
+ setDeviceSerialNumber('');
115
+ setDisplayMessage('');
86
116
  }
87
- }, [isDeviceConnected]);
117
+ }, [isIDTECHConnected]);
88
118
 
89
119
  // Logging helper
90
120
  const pushLog = (type: string, payload: any) => {
91
121
  setLogs(prev => [...prev, { type, payload, timestamp: Date.now() }]);
92
122
  };
93
123
 
94
- // Exposed Method to unconfigure Device
95
- const unconfigureDevice = (immediate: boolean = false) => {
96
- // Cancel any pending delayed unconfigure
97
- if (unconfigureTimeoutRef.current) {
98
- clearTimeout(unconfigureTimeoutRef.current);
99
- unconfigureTimeoutRef.current = null;
100
- }
101
-
102
- if (immediate) {
103
- setIsConfigured(false);
104
- return;
105
- }
106
-
107
- // Delayed unconfigure (handles IDTECH reboot)
108
- unconfigureTimeoutRef.current = setTimeout(() => {
109
- if (!isDeviceConnectedRef.current) {
110
- setIsConfigured(false);
111
- }
112
- }, 2000);
113
- };
124
+ // Clean up timeout references
125
+ useEffect(() => {
126
+ return () => {
127
+ clearDisconnectTimeout();
128
+ };
129
+ }, []);
114
130
 
115
131
  // Native to Provider EMV event listening
116
132
  useEffect(() => {
@@ -142,7 +158,7 @@ const EMVPaymentProvider: React.FC<{ children: React.ReactNode }> = ({
142
158
  if (TRANSACTION_RESPONSE_EVENTS.includes(eventName)) {
143
159
  setTransactionCurrentlyRunning(false);
144
160
  setCancellationRunning(false);
145
- setDisplayMessage("")
161
+ setDisplayMessage('');
146
162
  }
147
163
 
148
164
  const callbacks = subscriptionsRef.current.get(eventName);
@@ -159,7 +175,7 @@ const EMVPaymentProvider: React.FC<{ children: React.ReactNode }> = ({
159
175
  // Exposed method to run EMV configuration
160
176
  const runConfiguration = (config: EMVConfig) => {
161
177
  const title = 'CONFIGURATION DENIED';
162
- const message = !isDeviceConnected
178
+ const message = !isIDTECHConnected
163
179
  ? 'IDTECH device is not connected via USB'
164
180
  : config.merchantID == ''
165
181
  ? 'Merchant ID not found'
@@ -167,6 +183,8 @@ const EMVPaymentProvider: React.FC<{ children: React.ReactNode }> = ({
167
183
  ? 'Operator ID not Found'
168
184
  : config.secureDeviceName == '' || config.posPackageID == ''
169
185
  ? 'Some configuration parameters are missing'
186
+ : !isLibraryInitialized
187
+ ? 'Payment Library not initialized. Call initializePaymentLib() first'
170
188
  : '';
171
189
 
172
190
  if (message != '') {
@@ -175,54 +193,82 @@ const EMVPaymentProvider: React.FC<{ children: React.ReactNode }> = ({
175
193
  }
176
194
 
177
195
  setConfigurationInProgress(true);
178
- console.log(
179
- 'Initialising::: ConfugurationProgress:',
180
- isConfigurationInProgress,
181
- 'isDeviceConnected: ',
182
- isDeviceConnected,
183
- );
184
- DsiEMVManagerBridge.clearTransactionListener();
185
- DsiEMVManagerBridge.initialize(config);
196
+ DsiEMVManagerBridge.setMerchantDetails(config);
186
197
  DsiEMVManagerBridge.configureDevice();
187
198
  };
188
199
 
200
+ const setMerchantDetails = (config: EMVConfig) => {
201
+ DsiEMVManagerBridge.setMerchantDetails(config);
202
+ };
203
+ // Initialize payment library
204
+ const initializePaymentLib = () => {
205
+ if (!isLibraryInitialized) {
206
+ DsiEMVManagerBridge.initializeLib();
207
+ setIsInitialzed(true);
208
+ pushLog('PAYMENT LIBRARY', 'Payment library has been initialised!');
209
+ } else {
210
+ pushLog('PAYMENT LIBRARY', 'Already initialized!');
211
+ }
212
+ };
189
213
  // Exposed method to run EMV CC Sale
190
214
  const creditCardSale = (amount: string) => {
191
- if (!isDeviceConnected || !isConfigured) return;
215
+ if (!isIDTECHConnected || !isConfigured) return;
192
216
 
193
217
  setTransactionCurrentlyRunning(true);
194
218
  DsiEMVManagerBridge.runSaleTransaction(amount);
219
+ pushLog('EMV TRANSACTION', 'Credit card sale transaction initiated');
195
220
  };
196
221
 
197
222
  // Exposed method to run In House/ Prepaid Card Read
198
223
  const prepaidCardRead = () => {
199
- if (!isDeviceConnected || !isConfigured) return;
224
+ if (!isIDTECHConnected || !isConfigured) return;
200
225
 
201
226
  setTransactionCurrentlyRunning(true);
202
227
  DsiEMVManagerBridge.collectCardDetails();
228
+ pushLog('PREPAID TRANSACTION', 'Prepaid card read initiated');
203
229
  };
204
230
 
205
231
  // Exposed method to run EMV CC Sale for Sale
206
232
  const creditCardRecurringSale = (amount: string) => {
207
- if (!isDeviceConnected || !isConfigured) return;
233
+ if (!isIDTECHConnected || !isConfigured) return;
208
234
 
209
235
  setTransactionCurrentlyRunning(true);
210
236
  DsiEMVManagerBridge.runRecurringTransaction(amount);
237
+ pushLog(
238
+ 'EMV TRANSACTION',
239
+ 'Credit card sale transaction for recurring initiated',
240
+ );
211
241
  };
212
242
 
213
243
  // Exposed method to run EMV CC Zero Auth
214
244
  const zeroAuthTransaction = () => {
215
- if (!isDeviceConnected || !isConfigured) return;
245
+ if (!isIDTECHConnected || !isConfigured) return;
216
246
 
217
247
  setTransactionCurrentlyRunning(true);
218
248
  DsiEMVManagerBridge.replaceCardInRecurring();
249
+ pushLog('EMV TRANSACTION', 'Zero auth transaction has been initiated');
219
250
  };
220
251
 
221
252
  // Exposed method to fetch device details
222
- const getDeviceDetails = () => {
223
- if (!isDeviceConnected) return;
224
- DsiEMVManagerBridge.getDeviceDetails();
225
- };
253
+ const getDeviceDetails = async (): Promise<string | null> => {
254
+ if (!isIDTECHConnected) return null;
255
+
256
+ try {
257
+ if (!deviceSerialNumber?.trim()) {
258
+ const extractedSerialNumber = await DsiEMVManagerBridge.getDeviceDetails();
259
+
260
+ setDeviceSerialNumber(extractedSerialNumber ?? "");
261
+ pushLog('PAYMENT LIBRARY', 'Retrieving IDTECH device details');
262
+
263
+ return extractedSerialNumber;
264
+ }
265
+ return deviceSerialNumber;
266
+
267
+ } catch (error) {
268
+ pushLog('PAYMENT LIBRARY', `Error fetching device details: ${error}`);
269
+ return null;
270
+ }
271
+ };
226
272
 
227
273
  // Exposed method to cancel transaction
228
274
  const cancelOperation = () => {
@@ -230,6 +276,7 @@ const EMVPaymentProvider: React.FC<{ children: React.ReactNode }> = ({
230
276
  setConfigurationInProgress(false);
231
277
  setCancellationRunning(true);
232
278
  DsiEMVManagerBridge.cancelTransaction();
279
+ pushLog('PAYMENT LIBRARY', 'Current Transaction cancelled by User');
233
280
  };
234
281
 
235
282
  // Exposed method to remove all attached listener
@@ -267,25 +314,19 @@ const EMVPaymentProvider: React.FC<{ children: React.ReactNode }> = ({
267
314
  [],
268
315
  );
269
316
 
270
- // Cleanup on unmount
271
- useEffect(() => {
272
- return () => {
273
- if (unconfigureTimeoutRef.current) {
274
- clearTimeout(unconfigureTimeoutRef.current);
275
- }
276
- };
277
- }, []);
278
-
279
317
  // Context value builder
280
318
  const value: EMVPaymentContextType = {
281
319
  logs,
282
- isDeviceConnected,
320
+ isDeviceConnected: isIDTECHConnected,
283
321
  isConfigured,
322
+ deviceSerialNumber,
284
323
  isTransactionCurrentlyRunning,
285
324
  isConfigurationInProgress,
286
325
  isCancellationRunning,
287
326
  displayMessage,
288
- unconfigureDevice,
327
+ setIsConfigured,
328
+ setMerchantDetails,
329
+ initializePaymentLib,
289
330
  creditCardSale,
290
331
  prepaidCardRead,
291
332
  creditCardRecurringSale,
@@ -24,17 +24,20 @@ export interface CallbackLog {
24
24
  export interface EMVPaymentHook {
25
25
  logs: CallbackLog[];
26
26
  isDeviceConnected: boolean;
27
+ deviceSerialNumber: string,
27
28
  isConfigured: boolean;
28
29
  isTransactionCurrentlyRunning: boolean,
29
30
  isConfigurationInProgress: boolean,
30
31
  isCancellationRunning: boolean,
31
32
  displayMessage: string,
32
- unconfigureDevice: (immediate: boolean) => void,
33
+ setMerchantDetails: (config: EMVConfig) => void,
34
+ setIsConfigured: (isConfigured: boolean) => void,
35
+ initializePaymentLib: () => void,
33
36
  creditCardSale: (amount: string) => void;
34
37
  prepaidCardRead: () => void;
35
38
  creditCardRecurringSale: (amount: string) => void;
36
39
  zeroAuthTransaction: () => void;
37
- getDeviceDetails: () => void;
40
+ getDeviceDetails: () => Promise<string | null>;
38
41
  runConfiguration: (config: EMVConfig) => void;
39
42
  removeAllListeners: () => void;
40
43
  cancelOperation: () => void;
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import {
3
3
  View,
4
4
  Text,
@@ -16,12 +16,14 @@ import { USBDeviceProvider } from '../usb/USBDeviceContext';
16
16
  import { EMVPaymentProvider } from '../emvPaymentProvider/EMVPaymentProvider';
17
17
  import { useEMVPayment } from '../emvPaymentProvider/useEMVPayment';
18
18
  import { EMVConfig } from '../emvPaymentProvider/types';
19
+ import { getDeviceBySerial } from './helper/deviceStore';
19
20
 
20
21
  type IconCallback = {
21
22
  onPress: () => void;
22
23
  };
23
24
 
24
25
  type PaymentScreenIconsCallback = {
26
+ config: EMVConfig | null;
25
27
  onPressExternalSystem: () => void;
26
28
  onPressSettings: () => void;
27
29
  };
@@ -46,8 +48,8 @@ const CrossIcon = () => (
46
48
  <Text style={{ color: 'red', fontSize: 18, marginRight: 6 }}>❌</Text>
47
49
  );
48
50
 
49
- const EMVPaymentScreenExample = () => {
50
- const [config, setConfig] = useState<EMVConfig | null>(null);
51
+ const EMVPaymentScreenExample = ({ posConfig }: { posConfig: EMVConfig }) => {
52
+ const [config, setConfig] = useState<EMVConfig | null>(posConfig);
51
53
  const [showSettingsScreen, setShowSettingsScreen] = useState(false);
52
54
  const [showExternalSystemScreen, setShowExternalSystemScreen] =
53
55
  useState(false);
@@ -81,6 +83,7 @@ const EMVPaymentScreenExample = () => {
81
83
 
82
84
  return (
83
85
  <ExampleContent
86
+ config={config}
84
87
  onPressSettings={toggleSettingsScreen}
85
88
  onPressExternalSystem={toggleExternalSystemScreen}
86
89
  />
@@ -95,22 +98,77 @@ const EMVPaymentScreenExample = () => {
95
98
  };
96
99
 
97
100
  const ExampleContent = ({
101
+ config,
98
102
  onPressExternalSystem,
99
103
  onPressSettings,
100
104
  }: PaymentScreenIconsCallback) => {
101
105
  const [infoVisible, setInfoVisible] = useState(false);
102
106
  const {
103
107
  logs,
108
+ isDeviceConnected,
109
+ deviceSerialNumber,
110
+ initializePaymentLib,
111
+ setMerchantDetails,
104
112
  isConfigured,
105
113
  creditCardSale,
106
114
  prepaidCardRead,
107
115
  creditCardRecurringSale,
108
116
  zeroAuthTransaction,
109
117
  cancelOperation,
118
+ setIsConfigured,
110
119
  getDeviceDetails,
111
120
  isTransactionCurrentlyRunning,
112
- displayMessage
121
+ displayMessage,
113
122
  } = useEMVPayment();
123
+ //Device Connected -> Serial Received -> Lookup Local Config -> Auto Configure -> Enable Transactions
124
+ // useEffect(() => {
125
+ // if (deviceSerialNumber) {
126
+ // const matchedDevice = getDeviceBySerial(deviceSerialNumber);
127
+
128
+ // if (matchedDevice?.isConfigured) {
129
+ // setIsConfigured(true);
130
+ // } else {
131
+ // setIsConfigured(false);
132
+ // }
133
+ // } else {
134
+ // setIsConfigured(false);
135
+ // }
136
+ // }, [deviceSerialNumber]);
137
+
138
+ useEffect(() => {
139
+ const fetchDeviceDetails = async () => {
140
+ if (isDeviceConnected) {
141
+ if (!isConfigured) {
142
+ if (!deviceSerialNumber.trim()) {
143
+ const serialNumber = await getDeviceDetails();
144
+ console.log('EXTRACTED SERIAL NUMBER:::: ', serialNumber);
145
+ if (serialNumber) {
146
+ const storedDevice = getDeviceBySerial(serialNumber);
147
+ console.log('STORED DEVICE DETAILS::::', serialNumber);
148
+
149
+ if (storedDevice?.isConfigured) {
150
+ setIsConfigured(true);
151
+ console.log('SERIAL NUMBER ALREADY EXISTS');
152
+ } else {
153
+ setIsConfigured(false);
154
+ console.log("SERIAL NUMBER DOESN'T EXISTS");
155
+ }
156
+ } else {
157
+ setIsConfigured(false);
158
+ console.log('NOT ABLE TO EXTRACT SERIAL NUMBER');
159
+ }
160
+ }
161
+ }
162
+ }
163
+ };
164
+ fetchDeviceDetails();
165
+ }, [isDeviceConnected]);
166
+
167
+ // Library initialisation and Param sent
168
+ useEffect(() => {
169
+ initializePaymentLib();
170
+ if (config != null) setMerchantDetails(config);
171
+ }, []);
114
172
 
115
173
  const showAlertIfNotConfigured = () => {
116
174
  if (isConfigured) return false;
@@ -140,7 +198,6 @@ const ExampleContent = ({
140
198
 
141
199
  {/** Button Row 1 */}
142
200
  <View style={styles.buttonRow}>
143
-
144
201
  <TouchableOpacity
145
202
  style={[
146
203
  styles.ctaButton,
@@ -164,10 +221,9 @@ const ExampleContent = ({
164
221
  : styles.ctaButtonEnabled,
165
222
  ]}
166
223
  onPress={() => {
167
- if(!showAlertIfNotConfigured())
168
- creditCardRecurringSale('1.50')
169
- }}
170
- disabled={isTransactionCurrentlyRunning }
224
+ if (!showAlertIfNotConfigured()) creditCardRecurringSale('1.50');
225
+ }}
226
+ disabled={isTransactionCurrentlyRunning}
171
227
  >
172
228
  <Text style={styles.ctaButtonText}>CC Sale (Recurring)</Text>
173
229
  </TouchableOpacity>
@@ -182,7 +238,7 @@ const ExampleContent = ({
182
238
  onPress={() => {
183
239
  if (!showAlertIfNotConfigured()) prepaidCardRead();
184
240
  }}
185
- disabled={isTransactionCurrentlyRunning }
241
+ disabled={isTransactionCurrentlyRunning}
186
242
  >
187
243
  <Text style={styles.ctaButtonText}>Read Prepaid Card</Text>
188
244
  </TouchableOpacity>
@@ -197,11 +253,10 @@ const ExampleContent = ({
197
253
  ? styles.ctaButtonDisabled
198
254
  : styles.ctaButtonEnabled,
199
255
  ]}
200
- onPress={()=> {
201
- if(!showAlertIfNotConfigured())
202
- zeroAuthTransaction()
256
+ onPress={() => {
257
+ if (!showAlertIfNotConfigured()) zeroAuthTransaction();
203
258
  }}
204
- disabled={isTransactionCurrentlyRunning }
259
+ disabled={isTransactionCurrentlyRunning}
205
260
  >
206
261
  <Text style={styles.ctaButtonText}>CC $0 Auth</Text>
207
262
  </TouchableOpacity>
@@ -213,8 +268,8 @@ const ExampleContent = ({
213
268
  ? styles.ctaButtonDisabled
214
269
  : styles.ctaButtonEnabled,
215
270
  ]}
216
- onPress={()=> {
217
- getDeviceDetails()
271
+ onPress={() => {
272
+ getDeviceDetails();
218
273
  }}
219
274
  disabled={isTransactionCurrentlyRunning}
220
275
  >
@@ -232,7 +287,9 @@ const ExampleContent = ({
232
287
  <View style={styles.modalOverlay}>
233
288
  <View style={styles.modalContent}>
234
289
  <ActivityIndicator size="large" color="#007AFF" />
235
- <Text style={styles.modalText}>Processing...\n{displayMessage}</Text>
290
+ <Text style={styles.modalText}>
291
+ Processing...\n{displayMessage}
292
+ </Text>
236
293
  <TouchableOpacity
237
294
  style={styles.cancelButton}
238
295
  onPress={cancelOperation}
@@ -451,7 +508,7 @@ const styles = StyleSheet.create({
451
508
  paddingVertical: 8,
452
509
  paddingHorizontal: 14,
453
510
  borderRadius: 6,
454
- }
511
+ },
455
512
  });
456
513
 
457
514
  export default EMVPaymentScreenExample;
@@ -8,7 +8,6 @@ import {
8
8
  TouchableOpacity,
9
9
  } from 'react-native';
10
10
 
11
- import { useEMVPayment } from '../emvPaymentProvider/useEMVPayment';
12
11
  import { EMVConfig } from '../emvPaymentProvider/types';
13
12
 
14
13
  type ConfigUpdateCallback = {
@@ -17,9 +16,8 @@ type ConfigUpdateCallback = {
17
16
  };
18
17
 
19
18
  const EMVSettingsScreen = ({ onConfigUpdate, data }: ConfigUpdateCallback) => {
20
- const { unconfigureDevice } = useEMVPayment();
21
- const [paymentMID, setPaymentMID] = useState('');
22
- const [operatorID, setOperatorID] = useState('');
19
+ const [paymentMID, setPaymentMID] = useState(data?.merchantID ?? "");
20
+ const [operatorID, setOperatorID] = useState(data?.operatorID ?? "");
23
21
  const [secureDeviceName] = useState('EMV_VP3350_DATACAP');
24
22
  const [isSandbox, setIsSandbox] = useState(true);
25
23
 
@@ -31,7 +29,7 @@ const handleApplyChanges = () => {
31
29
  operatorID,
32
30
  posPackageID: 'test.package.id',
33
31
  };
34
- unconfigureDevice(true);
32
+
35
33
  onConfigUpdate(config);
36
34
  };
37
35