nets-service-sdk 1.0.2 → 1.1.0
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 +78 -2
- package/dist/index.js +397 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# NETS Service SDK
|
|
2
2
|
|
|
3
|
-
A utility library for integrating with NETS payment terminals and handling related operations. This SDK provides tools for serial communication, message parsing, configuration management, and common utility functions.
|
|
3
|
+
A utility library for integrating with NETS payment terminals and handling related operations. This SDK provides tools for serial communication, message parsing, configuration management, transaction storage, and common utility functions.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔌 Serial communication with NETS payment terminals
|
|
8
|
+
- 💾 SQLite-based transaction storage with automatic purging
|
|
9
|
+
- 📝 Comprehensive logging with Winston
|
|
10
|
+
- 🔧 Configuration management
|
|
11
|
+
- 🛠️ Utility functions for payment processing
|
|
4
12
|
|
|
5
13
|
## Installation
|
|
6
14
|
|
|
@@ -53,10 +61,67 @@ communication.sentToTerminal('STATUS_CHECK', {});
|
|
|
53
61
|
// For Payment
|
|
54
62
|
communication.sentToTerminal('PAYMENT', {
|
|
55
63
|
amount: 1000, // Amount in cents
|
|
56
|
-
reference: 'ORDER123'
|
|
64
|
+
reference: 'ORDER123',
|
|
65
|
+
ecn: '040126003000'
|
|
57
66
|
});
|
|
58
67
|
```
|
|
59
68
|
|
|
69
|
+
### Transaction Storage (New in v1.1.0)
|
|
70
|
+
|
|
71
|
+
All terminal requests and responses are automatically stored in a SQLite database.
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
const sdk = require('nets-service-sdk');
|
|
75
|
+
|
|
76
|
+
// Query specific transaction by ECN
|
|
77
|
+
const transaction = sdk.getTransactionByEcn('040126003000');
|
|
78
|
+
console.log(transaction);
|
|
79
|
+
// {
|
|
80
|
+
// ecn: '040126003000',
|
|
81
|
+
// request_type: 'PAYMENT',
|
|
82
|
+
// request_payload: { amount: 10.50, reference: 'ORDER123' },
|
|
83
|
+
// response_data: { status: 'APPROVED', ... },
|
|
84
|
+
// status: 'APPROVED',
|
|
85
|
+
// ...
|
|
86
|
+
// }
|
|
87
|
+
|
|
88
|
+
// Get recent transactions
|
|
89
|
+
const recent = sdk.getRecentTransactions(50);
|
|
90
|
+
|
|
91
|
+
// Query by status
|
|
92
|
+
const approved = sdk.getTransactionsByStatus('APPROVED', 100);
|
|
93
|
+
const pending = sdk.getTransactionsByStatus('PENDING', 100);
|
|
94
|
+
|
|
95
|
+
// Manual cleanup (delete old transactions)
|
|
96
|
+
const deleted = sdk.cleanupOldTransactions(90); // Keep last 90 days
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Automatic Data Purging (New in v1.1.0)
|
|
100
|
+
|
|
101
|
+
The SDK automatically purges old transaction data weekly.
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
const sdk = require('nets-service-sdk');
|
|
105
|
+
|
|
106
|
+
// Auto-purge is enabled by default
|
|
107
|
+
// Default: Every Sunday at 2 AM, keeps last 7 days
|
|
108
|
+
|
|
109
|
+
// Start with custom settings
|
|
110
|
+
sdk.startAutoPurge(14, '0 3 * * *'); // Keep 14 days, run daily at 3 AM
|
|
111
|
+
|
|
112
|
+
// Stop auto-purge
|
|
113
|
+
sdk.stopAutoPurge();
|
|
114
|
+
|
|
115
|
+
// Check if auto-purge is running
|
|
116
|
+
const isRunning = sdk.isAutoPurgeRunning();
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Cron Schedule Examples:**
|
|
120
|
+
- `'0 2 * * 0'` - Every Sunday at 2 AM (default)
|
|
121
|
+
- `'0 3 * * *'` - Every day at 3 AM
|
|
122
|
+
- `'0 */6 * * *'` - Every 6 hours
|
|
123
|
+
- `'0 0 1 * *'` - First day of every month
|
|
124
|
+
|
|
60
125
|
### Utility Functions
|
|
61
126
|
|
|
62
127
|
The SDK exports various utility functions directly.
|
|
@@ -96,6 +161,17 @@ myLogger.error('This is an error message');
|
|
|
96
161
|
- **sendMessage**: Helper for sending messages (e.g., to socket rooms).
|
|
97
162
|
- **hexRequest**: Generates HEX requests for the terminal.
|
|
98
163
|
- **parser**: Parses responses from the terminal.
|
|
164
|
+
- **Transaction Storage**: SQLite-based storage for request/response tracking.
|
|
165
|
+
- **Auto-Purge**: Automatic cleanup of old transaction data.
|
|
166
|
+
|
|
167
|
+
## Database
|
|
168
|
+
|
|
169
|
+
The SDK creates a `transactions.db` SQLite database in your project root to store all terminal transactions. This provides:
|
|
170
|
+
|
|
171
|
+
- Complete audit trail of all requests and responses
|
|
172
|
+
- Debugging capabilities with full hex data
|
|
173
|
+
- Transaction reconciliation
|
|
174
|
+
- Automatic weekly cleanup (configurable)
|
|
99
175
|
|
|
100
176
|
## License
|
|
101
177
|
|
package/dist/index.js
CHANGED
|
@@ -631,6 +631,303 @@ var require_parser = __commonJS({
|
|
|
631
631
|
}
|
|
632
632
|
});
|
|
633
633
|
|
|
634
|
+
// src/db/autoPurge.js
|
|
635
|
+
var require_autoPurge = __commonJS({
|
|
636
|
+
"src/db/autoPurge.js"(exports2, module2) {
|
|
637
|
+
var cron = require("node-cron");
|
|
638
|
+
var logger = require_winston()(module2);
|
|
639
|
+
var { cleanupOldTransactions } = require_transactionStore();
|
|
640
|
+
var scheduledTask = null;
|
|
641
|
+
function startAutoPurge(daysToKeep = 7, cronSchedule = "0 2 * * 0") {
|
|
642
|
+
if (scheduledTask) {
|
|
643
|
+
logger.log({
|
|
644
|
+
level: "warn",
|
|
645
|
+
message: "Auto-purge already running. Stopping existing task first."
|
|
646
|
+
});
|
|
647
|
+
stopAutoPurge();
|
|
648
|
+
}
|
|
649
|
+
scheduledTask = cron.schedule(cronSchedule, () => {
|
|
650
|
+
logger.log({
|
|
651
|
+
level: "info",
|
|
652
|
+
message: `Running scheduled transaction cleanup (keeping last ${daysToKeep} days)`
|
|
653
|
+
});
|
|
654
|
+
try {
|
|
655
|
+
const deletedCount = cleanupOldTransactions(daysToKeep);
|
|
656
|
+
logger.log({
|
|
657
|
+
level: "info",
|
|
658
|
+
message: `Auto-purge completed: Deleted ${deletedCount} old transactions`
|
|
659
|
+
});
|
|
660
|
+
} catch (error) {
|
|
661
|
+
logger.log({
|
|
662
|
+
level: "error",
|
|
663
|
+
message: `Auto-purge failed: ${error.message}`
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
logger.log({
|
|
668
|
+
level: "info",
|
|
669
|
+
message: `Auto-purge scheduled: ${cronSchedule} (keeping last ${daysToKeep} days)`
|
|
670
|
+
});
|
|
671
|
+
return scheduledTask;
|
|
672
|
+
}
|
|
673
|
+
function stopAutoPurge() {
|
|
674
|
+
if (scheduledTask) {
|
|
675
|
+
scheduledTask.stop();
|
|
676
|
+
scheduledTask = null;
|
|
677
|
+
logger.log({
|
|
678
|
+
level: "info",
|
|
679
|
+
message: "Auto-purge stopped"
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
function isAutoPurgeRunning() {
|
|
684
|
+
return scheduledTask !== null;
|
|
685
|
+
}
|
|
686
|
+
module2.exports = {
|
|
687
|
+
startAutoPurge,
|
|
688
|
+
stopAutoPurge,
|
|
689
|
+
isAutoPurgeRunning
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
// src/db/transactionStore.js
|
|
695
|
+
var require_transactionStore = __commonJS({
|
|
696
|
+
"src/db/transactionStore.js"(exports2, module2) {
|
|
697
|
+
var Database = require("better-sqlite3");
|
|
698
|
+
var path = require("path");
|
|
699
|
+
var fs = require("fs");
|
|
700
|
+
var logger = require_winston()(module2);
|
|
701
|
+
var db = null;
|
|
702
|
+
function initDatabase(dbPath, autoPurgeConfig = {}) {
|
|
703
|
+
try {
|
|
704
|
+
const defaultPath = path.join(__dirname, "../../transactions.db");
|
|
705
|
+
const finalPath = dbPath || defaultPath;
|
|
706
|
+
const dir = path.dirname(finalPath);
|
|
707
|
+
if (!fs.existsSync(dir)) {
|
|
708
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
709
|
+
}
|
|
710
|
+
db = new Database(finalPath);
|
|
711
|
+
db.pragma("journal_mode = WAL");
|
|
712
|
+
const createTableSQL = `
|
|
713
|
+
CREATE TABLE IF NOT EXISTS transactions (
|
|
714
|
+
ecn TEXT PRIMARY KEY,
|
|
715
|
+
request_type TEXT NOT NULL,
|
|
716
|
+
request_payload TEXT,
|
|
717
|
+
request_hex TEXT,
|
|
718
|
+
request_timestamp INTEGER NOT NULL,
|
|
719
|
+
response_hex TEXT,
|
|
720
|
+
response_data TEXT,
|
|
721
|
+
response_timestamp INTEGER,
|
|
722
|
+
status TEXT DEFAULT 'PENDING',
|
|
723
|
+
created_at INTEGER NOT NULL,
|
|
724
|
+
updated_at INTEGER NOT NULL
|
|
725
|
+
)
|
|
726
|
+
`;
|
|
727
|
+
db.exec(createTableSQL);
|
|
728
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_request_timestamp ON transactions(request_timestamp DESC)");
|
|
729
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_status ON transactions(status)");
|
|
730
|
+
logger.log({
|
|
731
|
+
level: "info",
|
|
732
|
+
message: `Transaction database initialized at ${finalPath}`
|
|
733
|
+
});
|
|
734
|
+
const { enabled = true, daysToKeep = 7, schedule = "0 2 * * 0" } = autoPurgeConfig;
|
|
735
|
+
if (enabled) {
|
|
736
|
+
const autoPurge = require_autoPurge();
|
|
737
|
+
autoPurge.startAutoPurge(daysToKeep, schedule);
|
|
738
|
+
}
|
|
739
|
+
return db;
|
|
740
|
+
} catch (error) {
|
|
741
|
+
logger.log({
|
|
742
|
+
level: "error",
|
|
743
|
+
message: `Failed to initialize database: ${error.message}`
|
|
744
|
+
});
|
|
745
|
+
throw error;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
function getDatabase() {
|
|
749
|
+
if (!db) {
|
|
750
|
+
initDatabase();
|
|
751
|
+
}
|
|
752
|
+
return db;
|
|
753
|
+
}
|
|
754
|
+
function createTransaction(data) {
|
|
755
|
+
try {
|
|
756
|
+
const database = getDatabase();
|
|
757
|
+
const now = Date.now();
|
|
758
|
+
const stmt = database.prepare(`
|
|
759
|
+
INSERT INTO transactions (
|
|
760
|
+
ecn, request_type, request_payload, request_hex,
|
|
761
|
+
request_timestamp, status, created_at, updated_at
|
|
762
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
763
|
+
`);
|
|
764
|
+
const result = stmt.run(
|
|
765
|
+
data.ecn,
|
|
766
|
+
data.requestType,
|
|
767
|
+
JSON.stringify(data.requestPayload || {}),
|
|
768
|
+
data.requestHex,
|
|
769
|
+
now,
|
|
770
|
+
"PENDING",
|
|
771
|
+
now,
|
|
772
|
+
now
|
|
773
|
+
);
|
|
774
|
+
logger.log({
|
|
775
|
+
level: "info",
|
|
776
|
+
message: `Transaction created: ECN=${data.ecn}, Type=${data.requestType}`
|
|
777
|
+
});
|
|
778
|
+
return result;
|
|
779
|
+
} catch (error) {
|
|
780
|
+
logger.log({
|
|
781
|
+
level: "error",
|
|
782
|
+
message: `Failed to create transaction: ${error.message}`
|
|
783
|
+
});
|
|
784
|
+
throw error;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
function updateTransactionResponse(ecn, data) {
|
|
788
|
+
try {
|
|
789
|
+
const database = getDatabase();
|
|
790
|
+
const now = Date.now();
|
|
791
|
+
const stmt = database.prepare(`
|
|
792
|
+
UPDATE transactions
|
|
793
|
+
SET response_hex = ?,
|
|
794
|
+
response_data = ?,
|
|
795
|
+
response_timestamp = ?,
|
|
796
|
+
status = ?,
|
|
797
|
+
updated_at = ?
|
|
798
|
+
WHERE ecn = ?
|
|
799
|
+
`);
|
|
800
|
+
const result = stmt.run(
|
|
801
|
+
data.responseHex,
|
|
802
|
+
JSON.stringify(data.responseData || {}),
|
|
803
|
+
now,
|
|
804
|
+
data.status || "COMPLETED",
|
|
805
|
+
now,
|
|
806
|
+
ecn
|
|
807
|
+
);
|
|
808
|
+
logger.log({
|
|
809
|
+
level: "info",
|
|
810
|
+
message: `Transaction updated: ECN=${ecn}, Status=${data.status || "COMPLETED"}`
|
|
811
|
+
});
|
|
812
|
+
return result;
|
|
813
|
+
} catch (error) {
|
|
814
|
+
logger.log({
|
|
815
|
+
level: "error",
|
|
816
|
+
message: `Failed to update transaction: ${error.message}`
|
|
817
|
+
});
|
|
818
|
+
throw error;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
function getTransactionByEcn(ecn) {
|
|
822
|
+
try {
|
|
823
|
+
const database = getDatabase();
|
|
824
|
+
const stmt = database.prepare("SELECT * FROM transactions WHERE ecn = ?");
|
|
825
|
+
const row = stmt.get(ecn);
|
|
826
|
+
if (row) {
|
|
827
|
+
row.request_payload = JSON.parse(row.request_payload || "{}");
|
|
828
|
+
row.response_data = JSON.parse(row.response_data || "{}");
|
|
829
|
+
}
|
|
830
|
+
return row;
|
|
831
|
+
} catch (error) {
|
|
832
|
+
logger.log({
|
|
833
|
+
level: "error",
|
|
834
|
+
message: `Failed to get transaction: ${error.message}`
|
|
835
|
+
});
|
|
836
|
+
return null;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
function getRecentTransactions(limit = 100) {
|
|
840
|
+
try {
|
|
841
|
+
const database = getDatabase();
|
|
842
|
+
const stmt = database.prepare(`
|
|
843
|
+
SELECT * FROM transactions
|
|
844
|
+
ORDER BY request_timestamp DESC
|
|
845
|
+
LIMIT ?
|
|
846
|
+
`);
|
|
847
|
+
const rows = stmt.all(limit);
|
|
848
|
+
return rows.map((row) => ({
|
|
849
|
+
...row,
|
|
850
|
+
request_payload: JSON.parse(row.request_payload || "{}"),
|
|
851
|
+
response_data: JSON.parse(row.response_data || "{}")
|
|
852
|
+
}));
|
|
853
|
+
} catch (error) {
|
|
854
|
+
logger.log({
|
|
855
|
+
level: "error",
|
|
856
|
+
message: `Failed to get recent transactions: ${error.message}`
|
|
857
|
+
});
|
|
858
|
+
return [];
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
function getTransactionsByStatus(status, limit = 100) {
|
|
862
|
+
try {
|
|
863
|
+
const database = getDatabase();
|
|
864
|
+
const stmt = database.prepare(`
|
|
865
|
+
SELECT * FROM transactions
|
|
866
|
+
WHERE status = ?
|
|
867
|
+
ORDER BY request_timestamp DESC
|
|
868
|
+
LIMIT ?
|
|
869
|
+
`);
|
|
870
|
+
const rows = stmt.all(status, limit);
|
|
871
|
+
return rows.map((row) => ({
|
|
872
|
+
...row,
|
|
873
|
+
request_payload: JSON.parse(row.request_payload || "{}"),
|
|
874
|
+
response_data: JSON.parse(row.response_data || "{}")
|
|
875
|
+
}));
|
|
876
|
+
} catch (error) {
|
|
877
|
+
logger.log({
|
|
878
|
+
level: "error",
|
|
879
|
+
message: `Failed to get transactions by status: ${error.message}`
|
|
880
|
+
});
|
|
881
|
+
return [];
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
function cleanupOldTransactions(daysToKeep = 90) {
|
|
885
|
+
try {
|
|
886
|
+
const database = getDatabase();
|
|
887
|
+
const cutoffTime = Date.now() - daysToKeep * 24 * 60 * 60 * 1e3;
|
|
888
|
+
const stmt = database.prepare("DELETE FROM transactions WHERE request_timestamp < ?");
|
|
889
|
+
const result = stmt.run(cutoffTime);
|
|
890
|
+
logger.log({
|
|
891
|
+
level: "info",
|
|
892
|
+
message: `Cleaned up ${result.changes} old transactions (older than ${daysToKeep} days)`
|
|
893
|
+
});
|
|
894
|
+
return result.changes;
|
|
895
|
+
} catch (error) {
|
|
896
|
+
logger.log({
|
|
897
|
+
level: "error",
|
|
898
|
+
message: `Failed to cleanup old transactions: ${error.message}`
|
|
899
|
+
});
|
|
900
|
+
return 0;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
function closeDatabase() {
|
|
904
|
+
if (db) {
|
|
905
|
+
db.close();
|
|
906
|
+
db = null;
|
|
907
|
+
logger.log({
|
|
908
|
+
level: "info",
|
|
909
|
+
message: "Database connection closed"
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
module2.exports = {
|
|
914
|
+
initDatabase,
|
|
915
|
+
getDatabase,
|
|
916
|
+
createTransaction,
|
|
917
|
+
updateTransactionResponse,
|
|
918
|
+
getTransactionByEcn,
|
|
919
|
+
getRecentTransactions,
|
|
920
|
+
getTransactionsByStatus,
|
|
921
|
+
cleanupOldTransactions,
|
|
922
|
+
closeDatabase,
|
|
923
|
+
// Auto-purge control functions
|
|
924
|
+
startAutoPurge: require_autoPurge().startAutoPurge,
|
|
925
|
+
stopAutoPurge: require_autoPurge().stopAutoPurge,
|
|
926
|
+
isAutoPurgeRunning: require_autoPurge().isAutoPurgeRunning
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
});
|
|
930
|
+
|
|
634
931
|
// src/payment/responseHandler.js
|
|
635
932
|
var require_responseHandler = __commonJS({
|
|
636
933
|
"src/payment/responseHandler.js"(exports2, module2) {
|
|
@@ -648,6 +945,7 @@ var require_responseHandler = __commonJS({
|
|
|
648
945
|
} = require_parser();
|
|
649
946
|
var fw = require_manageConfig();
|
|
650
947
|
var { xorCalculation } = require_utils_helper();
|
|
948
|
+
var { updateTransactionResponse } = require_transactionStore();
|
|
651
949
|
var queue2 = new Queue();
|
|
652
950
|
module2.exports.terminalStatus = (ecn) => {
|
|
653
951
|
const length = queue2.size();
|
|
@@ -662,6 +960,18 @@ var require_responseHandler = __commonJS({
|
|
|
662
960
|
level: "info",
|
|
663
961
|
message: status
|
|
664
962
|
});
|
|
963
|
+
try {
|
|
964
|
+
updateTransactionResponse(ecn, {
|
|
965
|
+
responseHex: fullHex,
|
|
966
|
+
responseData: { status },
|
|
967
|
+
status: status ? "COMPLETED" : "FAILED"
|
|
968
|
+
});
|
|
969
|
+
} catch (error) {
|
|
970
|
+
logger.log({
|
|
971
|
+
level: "error",
|
|
972
|
+
message: `Failed to update transaction: ${error.message}`
|
|
973
|
+
});
|
|
974
|
+
}
|
|
665
975
|
if (status) {
|
|
666
976
|
fw.updateConfig({ terminal_status: true });
|
|
667
977
|
sendMessage2("clientRoom", "STATUS_MESSAGE", {
|
|
@@ -687,6 +997,18 @@ var require_responseHandler = __commonJS({
|
|
|
687
997
|
}
|
|
688
998
|
console.log(fullHex);
|
|
689
999
|
const response = logonParser(fullHex, ecn);
|
|
1000
|
+
try {
|
|
1001
|
+
updateTransactionResponse(ecn, {
|
|
1002
|
+
responseHex: fullHex,
|
|
1003
|
+
responseData: response,
|
|
1004
|
+
status: response.status ? "COMPLETED" : "FAILED"
|
|
1005
|
+
});
|
|
1006
|
+
} catch (error) {
|
|
1007
|
+
logger.log({
|
|
1008
|
+
level: "error",
|
|
1009
|
+
message: `Failed to update transaction: ${error.message}`
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
690
1012
|
if (response.status) {
|
|
691
1013
|
fw.updateConfig({ last_logon: /* @__PURE__ */ new Date() });
|
|
692
1014
|
sendMessage2("clientRoom", "LOGON_MESSAGE", {
|
|
@@ -714,6 +1036,18 @@ var require_responseHandler = __commonJS({
|
|
|
714
1036
|
module2.exports.terminalPayment = (hexValue, ecn) => {
|
|
715
1037
|
const parsedValue = netsPaymentParser(hexValue, ecn);
|
|
716
1038
|
const response = jsonProcessor(parsedValue);
|
|
1039
|
+
try {
|
|
1040
|
+
updateTransactionResponse(ecn, {
|
|
1041
|
+
responseHex: hexValue,
|
|
1042
|
+
responseData: response,
|
|
1043
|
+
status: response.translated?.status || "UNKNOWN"
|
|
1044
|
+
});
|
|
1045
|
+
} catch (error) {
|
|
1046
|
+
logger.log({
|
|
1047
|
+
level: "error",
|
|
1048
|
+
message: `Failed to update transaction: ${error.message}`
|
|
1049
|
+
});
|
|
1050
|
+
}
|
|
717
1051
|
if (response.translated) {
|
|
718
1052
|
if (response.translated.status == "APPROVED") {
|
|
719
1053
|
sendMessage2("clientRoom", "PAYMENT_MESSAGE", {
|
|
@@ -741,6 +1075,18 @@ var require_responseHandler = __commonJS({
|
|
|
741
1075
|
module2.exports.terminalCreditPayment = (hexValue, ecn) => {
|
|
742
1076
|
const parsedValue = creditPaymentParser(hexValue, ecn);
|
|
743
1077
|
const response = jsonProcessor(parsedValue);
|
|
1078
|
+
try {
|
|
1079
|
+
updateTransactionResponse(ecn, {
|
|
1080
|
+
responseHex: hexValue,
|
|
1081
|
+
responseData: response,
|
|
1082
|
+
status: response.translated?.status || "UNKNOWN"
|
|
1083
|
+
});
|
|
1084
|
+
} catch (error) {
|
|
1085
|
+
logger.log({
|
|
1086
|
+
level: "error",
|
|
1087
|
+
message: `Failed to update transaction: ${error.message}`
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
744
1090
|
if (response.translated) {
|
|
745
1091
|
if (response.translated.status == "APPROVED") {
|
|
746
1092
|
sendMessage2("clientRoom", "PAYMENT_MESSAGE", {
|
|
@@ -817,6 +1163,7 @@ var require_communication = __commonJS({
|
|
|
817
1163
|
} = require_responseHandler();
|
|
818
1164
|
var { sendMessage: sendMessage2 } = require_sendMessage();
|
|
819
1165
|
var fw = require_manageConfig();
|
|
1166
|
+
var { createTransaction } = require_transactionStore();
|
|
820
1167
|
var { initialiseRequest } = require_httpRequest();
|
|
821
1168
|
var requestType;
|
|
822
1169
|
var calculated;
|
|
@@ -968,16 +1315,55 @@ var require_communication = __commonJS({
|
|
|
968
1315
|
requestPayload = body;
|
|
969
1316
|
if (requestType == "STATUS_CHECK") {
|
|
970
1317
|
calculated = generateStatusReq();
|
|
1318
|
+
try {
|
|
1319
|
+
createTransaction({
|
|
1320
|
+
ecn: calculated.ecn,
|
|
1321
|
+
requestType,
|
|
1322
|
+
requestPayload: null,
|
|
1323
|
+
requestHex: calculated.buffer.toString("hex")
|
|
1324
|
+
});
|
|
1325
|
+
} catch (error) {
|
|
1326
|
+
logger.log({
|
|
1327
|
+
level: "error",
|
|
1328
|
+
message: `Failed to store transaction: ${error.message}`
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
971
1331
|
global.port.write(calculated.buffer);
|
|
972
1332
|
}
|
|
973
1333
|
if (requestType == "LOGON") {
|
|
974
1334
|
calculated = generateLogonRequest();
|
|
1335
|
+
try {
|
|
1336
|
+
createTransaction({
|
|
1337
|
+
ecn: calculated.ecn,
|
|
1338
|
+
requestType,
|
|
1339
|
+
requestPayload: null,
|
|
1340
|
+
requestHex: calculated.buffer.toString("hex")
|
|
1341
|
+
});
|
|
1342
|
+
} catch (error) {
|
|
1343
|
+
logger.log({
|
|
1344
|
+
level: "error",
|
|
1345
|
+
message: `Failed to store transaction: ${error.message}`
|
|
1346
|
+
});
|
|
1347
|
+
}
|
|
975
1348
|
global.port.write(calculated.buffer);
|
|
976
1349
|
}
|
|
977
1350
|
if (requestType == "PAYMENT" || requestType == "CREDIT_PAYMENT") {
|
|
978
1351
|
exports2.reset();
|
|
979
1352
|
calculated = generatePaymentRequest(body);
|
|
980
1353
|
console.log(calculated);
|
|
1354
|
+
try {
|
|
1355
|
+
createTransaction({
|
|
1356
|
+
ecn: calculated.ecn,
|
|
1357
|
+
requestType,
|
|
1358
|
+
requestPayload: body,
|
|
1359
|
+
requestHex: calculated.hexString
|
|
1360
|
+
});
|
|
1361
|
+
} catch (error) {
|
|
1362
|
+
logger.log({
|
|
1363
|
+
level: "error",
|
|
1364
|
+
message: `Failed to store transaction: ${error.message}`
|
|
1365
|
+
});
|
|
1366
|
+
}
|
|
981
1367
|
global.port.write(calculated.buffer);
|
|
982
1368
|
exports2.checkACKorNACK();
|
|
983
1369
|
}
|
|
@@ -996,6 +1382,7 @@ var hexRequest = require_hexRequest();
|
|
|
996
1382
|
var httpRequest = require_httpRequest();
|
|
997
1383
|
var parser = require_parser();
|
|
998
1384
|
var responseHandler = require_responseHandler();
|
|
1385
|
+
var transactionStore = require_transactionStore();
|
|
999
1386
|
module.exports = {
|
|
1000
1387
|
...utilsHelper,
|
|
1001
1388
|
logger: winston,
|
|
@@ -1006,5 +1393,14 @@ module.exports = {
|
|
|
1006
1393
|
hexRequest,
|
|
1007
1394
|
httpRequest,
|
|
1008
1395
|
parser,
|
|
1009
|
-
responseHandler
|
|
1396
|
+
responseHandler,
|
|
1397
|
+
// Transaction store utilities
|
|
1398
|
+
getTransactionByEcn: transactionStore.getTransactionByEcn,
|
|
1399
|
+
getRecentTransactions: transactionStore.getRecentTransactions,
|
|
1400
|
+
getTransactionsByStatus: transactionStore.getTransactionsByStatus,
|
|
1401
|
+
cleanupOldTransactions: transactionStore.cleanupOldTransactions,
|
|
1402
|
+
// Auto-purge control
|
|
1403
|
+
startAutoPurge: transactionStore.startAutoPurge,
|
|
1404
|
+
stopAutoPurge: transactionStore.stopAutoPurge,
|
|
1405
|
+
isAutoPurgeRunning: transactionStore.isAutoPurgeRunning
|
|
1010
1406
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nets-service-sdk",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Utility functions for Nets Service",
|
|
5
5
|
"source": "src/index.js",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,16 +11,18 @@
|
|
|
11
11
|
"watch": "microbundle watch",
|
|
12
12
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
13
13
|
},
|
|
14
|
-
"keywords": [],
|
|
14
|
+
"keywords": ["nets", "payment", "terminal", "pos", "sqlite", "transaction", "serial", "payment-gateway"],
|
|
15
15
|
"author": "dineshhv",
|
|
16
16
|
"license": "ISC",
|
|
17
17
|
"files": [
|
|
18
18
|
"dist"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
+
"better-sqlite3": "^12.5.0",
|
|
21
22
|
"dollars-to-cents": "^1.0.3",
|
|
22
23
|
"lodash": "^4.17.21",
|
|
23
24
|
"moment": "^2.29.4",
|
|
25
|
+
"node-cron": "^4.2.1",
|
|
24
26
|
"request": "^2.88.2",
|
|
25
27
|
"serialport": "^10.5.0",
|
|
26
28
|
"socket.io-client": "^4.7.2",
|