nets-service-sdk 1.1.19 → 1.1.21

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 (2) hide show
  1. package/dist/index.js +131 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -32,7 +32,9 @@ var require_utils_helper = __commonJS({
32
32
  return res.join("").toUpperCase();
33
33
  };
34
34
  String.prototype.toAsciiString = function() {
35
- return this.match(/.{1,2}/g).map(function(v) {
35
+ const matches = this.match(/.{1,2}/g);
36
+ if (!matches) return "";
37
+ return matches.map(function(v) {
36
38
  return String.fromCharCode(parseInt(v, 16));
37
39
  }).join("");
38
40
  };
@@ -280,6 +282,17 @@ var require_hexRequest = __commonJS({
280
282
  console.log("buffer", buffer);
281
283
  return { buffer, ecn: body.ecn, hexString };
282
284
  };
285
+ module2.exports.generateFunction56Request = () => {
286
+ const date = moment().format("DDMMYYHHmmss");
287
+ const paddedValue = padWithLeadingZeros(date, "12");
288
+ const hexValue = paddedValue.toHexString();
289
+ const calculated = `0018${hexValue}35363031301C03`;
290
+ const calculatedXor = xorCalculation(calculated);
291
+ const hexString = `02${calculated}` + calculatedXor;
292
+ console.log("Recovery Function 56 Request:", hexString);
293
+ const buffer = Buffer.from(hexString, "hex");
294
+ return { buffer, ecn: date };
295
+ };
283
296
  }
284
297
  });
285
298
 
@@ -447,7 +460,9 @@ var require_parser = __commonJS({
447
460
  let status = false;
448
461
  const json = {};
449
462
  for (let i = 0; i < splitted.length; i++) {
463
+ if (!splitted[i] || splitted[i].length === 0) continue;
450
464
  const ascii = splitted[i].toAsciiString();
465
+ if (!ascii) continue;
451
466
  if (ascii?.indexOf(ecn) > -1 || i === 0 && ascii.length >= 12) {
452
467
  json["ECN"] = ascii.cleanUp();
453
468
  if (ascii?.indexOf(ecn) === -1) {
@@ -477,7 +492,9 @@ var require_parser = __commonJS({
477
492
  let status = false;
478
493
  const json = {};
479
494
  for (let i = 0; i < splitted.length; i++) {
495
+ if (!splitted[i] || splitted[i].length === 0) continue;
480
496
  const ascii = splitted[i].toAsciiString();
497
+ if (!ascii) continue;
481
498
  if (ascii?.indexOf(ecn) > -1 || i === 0 && ascii.length >= 12) {
482
499
  json["ECN"] = ascii.cleanUp();
483
500
  } else {
@@ -930,6 +947,32 @@ var require_responseHandler = __commonJS({
930
947
  }
931
948
  return isMatch;
932
949
  };
950
+ module2.exports.terminalRecovery = (hexFrame) => {
951
+ const ecn = activePaymentEcn;
952
+ const parsedValue = netsPaymentParser(hexFrame, ecn);
953
+ const response = jsonProcessor(parsedValue);
954
+ if (response.translated) {
955
+ activePaymentEcn = null;
956
+ }
957
+ if (response.translated && (response.translated.category == "SUCCESS" || response.translated.status == "APPROVED")) {
958
+ logger.log({ level: "info", message: "\u2705 Recovery SUCCESS: Last transaction was APPROVED." });
959
+ sendMessage2("clientRoom", "PAYMENT_MESSAGE", {
960
+ success: true,
961
+ status: "SUCCESS",
962
+ response,
963
+ action: "COMPLETED"
964
+ });
965
+ sendPaymentResponseToCloud(response.translated);
966
+ } else {
967
+ logger.log({ level: "warn", message: "\u26A0\uFE0F Recovery FAILED: Transaction status could not be confirmed as APPROVED." });
968
+ sendMessage2("clientRoom", "PAYMENT_MESSAGE", {
969
+ status: "FAILED",
970
+ action: "CANCELLED",
971
+ message: "Payment needs verification / Failed",
972
+ reason: "RECOVERY_NOT_CONFIRMED"
973
+ });
974
+ }
975
+ };
933
976
  }
934
977
  });
935
978
 
@@ -959,13 +1002,14 @@ var require_communication = __commonJS({
959
1002
  var { initialiseRequest } = require_httpRequest();
960
1003
  var requestType;
961
1004
  var calculated;
962
- var MAX_COUNT = 3;
1005
+ var MAX_COUNT = 2;
963
1006
  var WRONG_LRC_MAX_COUNT = 3;
964
1007
  var count = MAX_COUNT;
965
1008
  var lrcCount = WRONG_LRC_MAX_COUNT;
966
1009
  var ackOrNack = null;
967
1010
  var requestPayload = null;
968
1011
  var ackTimeout = null;
1012
+ var dataTimeout = null;
969
1013
  var ACK = Buffer.alloc(1, 6, "hex");
970
1014
  var NACK = Buffer.alloc(1, 21, "hex");
971
1015
  var dataBuffer = Buffer.alloc(0);
@@ -981,6 +1025,10 @@ var require_communication = __commonJS({
981
1025
  clearTimeout(ackTimeout);
982
1026
  ackTimeout = null;
983
1027
  }
1028
+ if (dataTimeout) {
1029
+ clearTimeout(dataTimeout);
1030
+ dataTimeout = null;
1031
+ }
984
1032
  };
985
1033
  module2.exports.checkACKorNACK = () => {
986
1034
  if (ackTimeout) clearTimeout(ackTimeout);
@@ -1000,12 +1048,12 @@ var require_communication = __commonJS({
1000
1048
  message: `On ACK/NACK Listener: Terminal did not respond with ACK/NACK after max ${count} retries. Sending TERMINAL_ERROR to client.`
1001
1049
  });
1002
1050
  sendMessage2("clientRoom", "PAYMENT_MESSAGE", {
1003
- success: true,
1051
+ status: "FAILED",
1004
1052
  action: "TERMINAL_ERROR"
1005
1053
  });
1006
1054
  }
1007
1055
  }
1008
- }, 4e3);
1056
+ }, 2e3);
1009
1057
  };
1010
1058
  var resendData = () => {
1011
1059
  if (requestType == "STATUS_CHECK") {
@@ -1105,6 +1153,7 @@ var require_communication = __commonJS({
1105
1153
  clearTimeout(ackTimeout);
1106
1154
  ackTimeout = null;
1107
1155
  }
1156
+ exports2.startDataTimeout();
1108
1157
  if (byte === 21) {
1109
1158
  count--;
1110
1159
  if (count >= 0) {
@@ -1115,7 +1164,7 @@ var require_communication = __commonJS({
1115
1164
  level: "error",
1116
1165
  message: `Terminal responded with NACK multiple times. Max retries reached. Sending TERMINAL_ERROR.`
1117
1166
  });
1118
- sendMessage2("clientRoom", "PAYMENT_MESSAGE", { success: true, action: "TERMINAL_ERROR" });
1167
+ sendMessage2("clientRoom", "PAYMENT_MESSAGE", { status: "FAILED", action: "TERMINAL_ERROR" });
1119
1168
  }
1120
1169
  }
1121
1170
  continue;
@@ -1171,18 +1220,37 @@ var require_communication = __commonJS({
1171
1220
  }
1172
1221
  }
1173
1222
  };
1223
+ module2.exports.triggerRecovery = () => {
1224
+ const { generateFunction56Request } = require_hexRequest();
1225
+ exports2.reset();
1226
+ lrcCount = WRONG_LRC_MAX_COUNT;
1227
+ count = MAX_COUNT;
1228
+ const req = generateFunction56Request();
1229
+ requestType = "RECOVERY";
1230
+ calculated = req;
1231
+ logger.log({ level: "info", message: "\u{1F680} Triggering Recovery (Function 56) due to LRC failures..." });
1232
+ global.port.write(req.buffer);
1233
+ exports2.checkACKorNACK();
1234
+ };
1174
1235
  module2.exports.handleFullMessage = (fullFrame) => {
1175
- const { checkLrc: checkLrc2, terminalStatus: terminalStatus2, terminalLogon: terminalLogon2, terminalPayment: terminalPayment2, terminalCreditPayment: terminalCreditPayment2 } = require_responseHandler();
1236
+ const { checkLrc: checkLrc2, terminalStatus: terminalStatus2, terminalLogon: terminalLogon2, terminalPayment: terminalPayment2, terminalCreditPayment: terminalCreditPayment2, terminalRecovery } = require_responseHandler();
1176
1237
  if (ackTimeout) {
1177
1238
  clearTimeout(ackTimeout);
1178
1239
  ackTimeout = null;
1179
1240
  }
1241
+ if (dataTimeout) {
1242
+ clearTimeout(dataTimeout);
1243
+ dataTimeout = null;
1244
+ }
1180
1245
  ackOrNack = Buffer.from([6]);
1181
1246
  const hexFrame = fullFrame.toString("hex").toUpperCase();
1182
1247
  logger.log({ level: "info", message: `Full frame processed: ${hexFrame}` });
1183
- if (checkLrc2(hexFrame)) {
1248
+ const isLrcCorrect = checkLrc2(hexFrame);
1249
+ if (isLrcCorrect) {
1184
1250
  logger.log({ level: "info", message: `LRC Correct. Sending ACK (0x06).` });
1185
1251
  global.port.write(ACK);
1252
+ lrcCount = WRONG_LRC_MAX_COUNT;
1253
+ count = MAX_COUNT;
1186
1254
  logger.log({ level: "info", message: `requestType: ${requestType}` });
1187
1255
  if (requestType === "STATUS_CHECK") {
1188
1256
  terminalStatus2(calculated?.ecn, hexFrame);
@@ -1192,12 +1260,65 @@ var require_communication = __commonJS({
1192
1260
  terminalPayment2(hexFrame, calculated?.ecn);
1193
1261
  } else if (requestType === "CREDIT_PAYMENT") {
1194
1262
  terminalCreditPayment2(hexFrame, calculated?.ecn);
1263
+ } else if (requestType === "RECOVERY") {
1264
+ terminalRecovery(hexFrame);
1195
1265
  }
1196
1266
  } else {
1197
- logger.log({ level: "error", message: `LRC Incorrect. Sending NACK (0x15).` });
1198
- global.port.write(NACK);
1267
+ lrcCount--;
1268
+ if (lrcCount > 0) {
1269
+ logger.log({ level: "error", message: `LRC Incorrect. Sending NACK (0x15). Retries left: ${lrcCount}` });
1270
+ global.port.write(NACK);
1271
+ } else {
1272
+ if (hexFrame.indexOf("415050524F564544") > -1) {
1273
+ logger.log({ level: "info", message: "\u2705 LRC Incorrect 3 times, but APPROVED found in hex payload. Accepting with ACK." });
1274
+ global.port.write(ACK);
1275
+ lrcCount = WRONG_LRC_MAX_COUNT;
1276
+ count = MAX_COUNT;
1277
+ if (requestType === "PAYMENT") terminalPayment2(hexFrame, calculated?.ecn);
1278
+ else if (requestType === "CREDIT_PAYMENT") terminalCreditPayment2(hexFrame, calculated?.ecn);
1279
+ else if (requestType === "RECOVERY") terminalRecovery(hexFrame);
1280
+ else if (requestType === "LOGON") terminalLogon2(calculated?.ecn, hexFrame);
1281
+ else if (requestType === "STATUS_CHECK") terminalStatus2(calculated?.ecn, hexFrame);
1282
+ } else {
1283
+ logger.log({ level: "warn", message: `LRC Incorrect 3 times and NO approval found. Stopping.` });
1284
+ global.port.write(NACK);
1285
+ if (ackTimeout) {
1286
+ clearTimeout(ackTimeout);
1287
+ ackTimeout = null;
1288
+ }
1289
+ if (requestType !== "RECOVERY") {
1290
+ sendMessage2("clientRoom", "PAYMENT_MESSAGE", {
1291
+ status: "UNKNOWN",
1292
+ action: "VERIFYING_STATUS",
1293
+ message: "Payment status uncertain. Please wait while we verify...",
1294
+ reason: "LRC_FAILURE"
1295
+ });
1296
+ setTimeout(() => exports2.triggerRecovery(), 2e3);
1297
+ } else {
1298
+ sendMessage2("clientRoom", "PAYMENT_MESSAGE", {
1299
+ status: "FAILED",
1300
+ action: "CANCELLED",
1301
+ message: "Payment needs manual verification / Recovery failed.",
1302
+ reason: "RECOVERY_LRC_FAILURE"
1303
+ });
1304
+ }
1305
+ }
1306
+ }
1199
1307
  }
1200
1308
  };
1309
+ module2.exports.startDataTimeout = () => {
1310
+ if (dataTimeout) clearTimeout(dataTimeout);
1311
+ dataTimeout = setTimeout(() => {
1312
+ dataTimeout = null;
1313
+ logger.error({ level: "error", message: `Terminal response time out (60 seconds) after ACK.` });
1314
+ sendMessage2("clientRoom", "PAYMENT_MESSAGE", {
1315
+ status: "FAILED",
1316
+ action: "TERMINAL_ERROR",
1317
+ message: "Terminal response time out (60 seconds)"
1318
+ });
1319
+ exports2.reset();
1320
+ }, 6e4);
1321
+ };
1201
1322
  module2.exports.checkPortConnection = async () => {
1202
1323
  const portPath = config.simulation ? config.simulationPort : config.com;
1203
1324
  try {
@@ -1300,7 +1421,7 @@ var require_package = __commonJS({
1300
1421
  "package.json"(exports2, module2) {
1301
1422
  module2.exports = {
1302
1423
  name: "nets-service-sdk",
1303
- version: "1.1.19",
1424
+ version: "1.1.21",
1304
1425
  description: "Utility functions for Nets Service",
1305
1426
  source: "src/index.js",
1306
1427
  main: "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nets-service-sdk",
3
- "version": "1.1.19",
3
+ "version": "1.1.21",
4
4
  "description": "Utility functions for Nets Service",
5
5
  "source": "src/index.js",
6
6
  "main": "dist/index.js",