@networksolution/sia-vpos-node 1.0.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 ADDED
@@ -0,0 +1,245 @@
1
+ # sia-vpos-node
2
+
3
+ Node.js SDK for **SIA/Nexi VPOS** payment gateway (API v2.4.3).
4
+
5
+ Supports all major operations: Authorization, Pay-By-Link, Booking, Refund, and webhook verification.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @networksolution/sia-vpos-node
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { VposClient } from '@networksolution/sia-vpos-node';
17
+
18
+ const vpos = new VposClient({
19
+ shopId: '000000000000003', // Merchant ID (15 chars)
20
+ operatorId: 'oper0001', // Operator ID (8-18 chars)
21
+ secretKey: 'your_secret_string', // Shared secret (50 or 100 chars)
22
+ hashAlgorithm: 'hmac-sha256', // 'hmac-sha256' (recommended) | 'sha1' | 'md5'
23
+ environment: 'test', // 'test' (default) | 'production'
24
+ });
25
+ ```
26
+
27
+ ## Environment (Test vs Production)
28
+
29
+ The SDK defaults to the **test** environment for safety. Three ways to control it:
30
+
31
+ **1. Config option (recommended):**
32
+ ```typescript
33
+ // Test (default)
34
+ const vpos = new VposClient({ ..., environment: 'test' });
35
+
36
+ // Production
37
+ const vpos = new VposClient({ ..., environment: 'production' });
38
+ ```
39
+
40
+ **2. Environment variable `VPOS_ENV`:**
41
+ ```bash
42
+ # .env or shell
43
+ VPOS_ENV=test # uses test URL
44
+ VPOS_ENV=production # uses production URL
45
+ ```
46
+ ```typescript
47
+ // No need to specify environment - picks up VPOS_ENV automatically
48
+ const vpos = new VposClient({ shopId, operatorId, secretKey });
49
+ ```
50
+
51
+ **3. Custom URL (overrides everything):**
52
+ ```typescript
53
+ const vpos = new VposClient({
54
+ ...,
55
+ apiUrl: 'https://custom-proxy.example.com/vpos',
56
+ });
57
+ ```
58
+
59
+ **Priority:** `apiUrl` > `environment` > `VPOS_ENV` > `'test'` (default)
60
+
61
+ **Helper properties:**
62
+ ```typescript
63
+ vpos.isTest; // true if test environment
64
+ vpos.isProduction; // true if production environment
65
+ vpos.apiUrl; // current API URL
66
+ ```
67
+
68
+ | Environment | URL |
69
+ |---|---|
70
+ | **test** | `https://virtualpostest.sia.eu/vpos/apibo/apiBOXML-UTF8.app` |
71
+ | **production** | `https://virtualpos.sia.eu/vpos/apibo/apiBOXML-UTF8.app` |
72
+
73
+ ## Operations
74
+
75
+ ### Authorization (Hosted Payment Page)
76
+
77
+ Server-to-server card payment authorization.
78
+
79
+ ```typescript
80
+ const result = await vpos.authorize({
81
+ orderId: 'ORDER-001',
82
+ pan: '9998500000000015',
83
+ expDate: '0409', // yyMM
84
+ cvv2: '123',
85
+ amount: 4450, // EUR 44.50 (in cents)
86
+ currency: '978', // EUR
87
+ accountingMode: 'I', // I=Immediate, D=Deferred
88
+ network: '01', // 01=VISA, 02=MC, 93=auto
89
+ });
90
+
91
+ if (result.result === '00') {
92
+ console.log('Authorized!', result.authorization);
93
+ }
94
+ ```
95
+
96
+ ### Pay-By-Link (Create Payment Link)
97
+
98
+ ```typescript
99
+ const link = await vpos.createLink({
100
+ sendMail: 'Y',
101
+ linkAmount: 9900, // EUR 99.00
102
+ linkOrderId: 'PBL-20260220-001',
103
+ linkUrlMs: 'https://yoursite.com/api/vpos/webhook',
104
+ linkUrlDone: 'https://yoursite.com/payment/success',
105
+ linkAccountingMode: 'I',
106
+ linkAuthorMode: 'I',
107
+ linkLang: 'EN',
108
+ linkName: 'John',
109
+ linkSurname: 'Doe',
110
+ linkEmail: 'john@example.com',
111
+ });
112
+
113
+ if (link.result === '00' && link.linkCreated) {
114
+ console.log('Payment link:', link.linkCreated.completeLink);
115
+ console.log('Token:', link.linkCreated.token);
116
+ }
117
+ ```
118
+
119
+ ### List Links
120
+
121
+ ```typescript
122
+ const links = await vpos.listLinks({
123
+ startDate: '2026-01-01',
124
+ endDate: '2026-12-31',
125
+ linkStatus: '01', // optional filter
126
+ });
127
+ console.log('Found links:', links.links);
128
+ ```
129
+
130
+ ### Revoke Link
131
+
132
+ ```typescript
133
+ await vpos.revokeLink({ token: 'scxfuyegan23510hi68vm7s12' });
134
+ ```
135
+
136
+ ### Booking / Capture (Accounting)
137
+
138
+ Capture a deferred authorization.
139
+
140
+ ```typescript
141
+ const capture = await vpos.accounting({
142
+ transactionId: '8032180310AB0E30917930112',
143
+ orderId: 'ORDER-001',
144
+ amount: 4450,
145
+ });
146
+ ```
147
+
148
+ ### Reverse Accounting (Cancel Booking)
149
+
150
+ ```typescript
151
+ await vpos.reverseAccounting({
152
+ transactionId: '8032180310AB0E30917930112',
153
+ orderId: 'ORDER-001',
154
+ });
155
+ ```
156
+
157
+ ### Refund
158
+
159
+ ```typescript
160
+ const refund = await vpos.refund({
161
+ transactionId: '8032180310AB0E30917930112',
162
+ orderId: 'ORDER-001',
163
+ amount: 2000, // partial refund EUR 20.00
164
+ });
165
+ ```
166
+
167
+ ### Order Status
168
+
169
+ ```typescript
170
+ const status = await vpos.orderStatus({ orderId: 'ORDER-001' });
171
+ console.log('Authorization:', status.authorization);
172
+ ```
173
+
174
+ ## Webhook Verification
175
+
176
+ When SIA sends server-to-server notifications (URLMS), verify the response MAC:
177
+
178
+ ```typescript
179
+ // In your Express/Next.js webhook handler:
180
+ app.post('/api/vpos/webhook', (req, res) => {
181
+ const xml = req.body; // raw XML string
182
+
183
+ // Parse the webhook data
184
+ const data = vpos.parseWebhook(xml);
185
+
186
+ // Verify root MAC (Timestamp + Result)
187
+ const isValid = vpos.verifyBPWResponseMAC(
188
+ data.timestamp,
189
+ data.result,
190
+ data.mac
191
+ );
192
+
193
+ if (!isValid) {
194
+ return res.status(400).send('Invalid MAC');
195
+ }
196
+
197
+ if (data.result === '00' && data.authorization) {
198
+ // Payment successful
199
+ console.log('Order:', data.authorization.orderId);
200
+ console.log('Amount:', data.authorization.authorizedAmount);
201
+ }
202
+
203
+ res.status(200).send('OK');
204
+ });
205
+ ```
206
+
207
+ ## MAC Algorithms
208
+
209
+ The SDK supports 3 hash algorithms (spec section 4.2):
210
+
211
+ | Algorithm | MAC Length | Method |
212
+ |---|---|---|
213
+ | `md5` | 32 chars | `MD5(text + secretKey)` |
214
+ | `sha1` | 40 chars | `SHA1(text + secretKey)` |
215
+ | `hmac-sha256` | 64 chars | `HMAC-SHA256(text, secretKey)` **(recommended)** |
216
+
217
+ ## Result Codes
218
+
219
+ | Code | Description |
220
+ |---|---|
221
+ | `00` | Success |
222
+ | `02` | ReqRefNum duplicated or incorrect |
223
+ | `03` | Incorrect message format |
224
+ | `04` | Incorrect MAC / authentication |
225
+ | `06` | Processing error |
226
+ | `07` | TransactionID not found |
227
+ | `13` | Duplicated order |
228
+ | `99` | Transaction failed (see Data) |
229
+
230
+ Full list available via `import { RESULT_CODES } from '@networksolution/sia-vpos-node'`.
231
+
232
+ ## Link Statuses
233
+
234
+ | Code | Status |
235
+ |---|---|
236
+ | `00` | Created |
237
+ | `01` | Returned |
238
+ | `02` | Sent |
239
+ | `03` | Used |
240
+ | `04` | Paid |
241
+ | `05` | Revoked |
242
+
243
+ ## License
244
+
245
+ MIT
@@ -0,0 +1,6 @@
1
+ export { VposClient, generateTimestamp, generateReqRefNum } from './vpos-client';
2
+ export { generateMAC, verifyMAC, computeHash } from './mac';
3
+ export { buildBPWXmlRequest, buildHeaderXml, el, parseBPWXmlResponse, parseAuthorization, parsePanAliasData, parseOperation, parseLinkCreated, parseLinkCreatedList, getXmlValue, getXmlBlocks, } from './xml';
4
+ export type { VposConfig, VposEnvironment, HashAlgorithm, HeaderData, AuthorizationRequest, AuthorizationResponse, PanAliasData, CreateLinkRequest, LinkCreatedData, ListLinkRequest, RevokeLinkRequest, AccountingRequest, ReverseAccountingRequest, RefundRequest, OrderStatusRequest, OperationData, VposResponse, } from './types';
5
+ export { RESULT_CODES, LINK_STATUS } from './types';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAC5D,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,EAAE,EACF,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,WAAW,EACX,YAAY,GACb,MAAM,OAAO,CAAC;AACf,YAAY,EACV,UAAU,EACV,eAAe,EACf,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,YAAY,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LINK_STATUS = exports.RESULT_CODES = exports.getXmlBlocks = exports.getXmlValue = exports.parseLinkCreatedList = exports.parseLinkCreated = exports.parseOperation = exports.parsePanAliasData = exports.parseAuthorization = exports.parseBPWXmlResponse = exports.el = exports.buildHeaderXml = exports.buildBPWXmlRequest = exports.computeHash = exports.verifyMAC = exports.generateMAC = exports.generateReqRefNum = exports.generateTimestamp = exports.VposClient = void 0;
4
+ var vpos_client_1 = require("./vpos-client");
5
+ Object.defineProperty(exports, "VposClient", { enumerable: true, get: function () { return vpos_client_1.VposClient; } });
6
+ Object.defineProperty(exports, "generateTimestamp", { enumerable: true, get: function () { return vpos_client_1.generateTimestamp; } });
7
+ Object.defineProperty(exports, "generateReqRefNum", { enumerable: true, get: function () { return vpos_client_1.generateReqRefNum; } });
8
+ var mac_1 = require("./mac");
9
+ Object.defineProperty(exports, "generateMAC", { enumerable: true, get: function () { return mac_1.generateMAC; } });
10
+ Object.defineProperty(exports, "verifyMAC", { enumerable: true, get: function () { return mac_1.verifyMAC; } });
11
+ Object.defineProperty(exports, "computeHash", { enumerable: true, get: function () { return mac_1.computeHash; } });
12
+ var xml_1 = require("./xml");
13
+ Object.defineProperty(exports, "buildBPWXmlRequest", { enumerable: true, get: function () { return xml_1.buildBPWXmlRequest; } });
14
+ Object.defineProperty(exports, "buildHeaderXml", { enumerable: true, get: function () { return xml_1.buildHeaderXml; } });
15
+ Object.defineProperty(exports, "el", { enumerable: true, get: function () { return xml_1.el; } });
16
+ Object.defineProperty(exports, "parseBPWXmlResponse", { enumerable: true, get: function () { return xml_1.parseBPWXmlResponse; } });
17
+ Object.defineProperty(exports, "parseAuthorization", { enumerable: true, get: function () { return xml_1.parseAuthorization; } });
18
+ Object.defineProperty(exports, "parsePanAliasData", { enumerable: true, get: function () { return xml_1.parsePanAliasData; } });
19
+ Object.defineProperty(exports, "parseOperation", { enumerable: true, get: function () { return xml_1.parseOperation; } });
20
+ Object.defineProperty(exports, "parseLinkCreated", { enumerable: true, get: function () { return xml_1.parseLinkCreated; } });
21
+ Object.defineProperty(exports, "parseLinkCreatedList", { enumerable: true, get: function () { return xml_1.parseLinkCreatedList; } });
22
+ Object.defineProperty(exports, "getXmlValue", { enumerable: true, get: function () { return xml_1.getXmlValue; } });
23
+ Object.defineProperty(exports, "getXmlBlocks", { enumerable: true, get: function () { return xml_1.getXmlBlocks; } });
24
+ var types_1 = require("./types");
25
+ Object.defineProperty(exports, "RESULT_CODES", { enumerable: true, get: function () { return types_1.RESULT_CODES; } });
26
+ Object.defineProperty(exports, "LINK_STATUS", { enumerable: true, get: function () { return types_1.LINK_STATUS; } });
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,6CAAiF;AAAxE,yGAAA,UAAU,OAAA;AAAE,gHAAA,iBAAiB,OAAA;AAAE,gHAAA,iBAAiB,OAAA;AACzD,6BAA4D;AAAnD,kGAAA,WAAW,OAAA;AAAE,gGAAA,SAAS,OAAA;AAAE,kGAAA,WAAW,OAAA;AAC5C,6BAYe;AAXb,yGAAA,kBAAkB,OAAA;AAClB,qGAAA,cAAc,OAAA;AACd,yFAAA,EAAE,OAAA;AACF,0GAAA,mBAAmB,OAAA;AACnB,yGAAA,kBAAkB,OAAA;AAClB,wGAAA,iBAAiB,OAAA;AACjB,qGAAA,cAAc,OAAA;AACd,uGAAA,gBAAgB,OAAA;AAChB,2GAAA,oBAAoB,OAAA;AACpB,kGAAA,WAAW,OAAA;AACX,mGAAA,YAAY,OAAA;AAqBd,iCAAoD;AAA3C,qGAAA,YAAY,OAAA;AAAE,oGAAA,WAAW,OAAA"}
package/dist/mac.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ import type { HashAlgorithm } from './types';
2
+ /**
3
+ * Generate MAC hash using the specified algorithm.
4
+ *
5
+ * Per SIA VPOS spec:
6
+ * - SHA-1 and MD5: Hash(text + secretKey) — secret appended to string
7
+ * - HMAC-SHA256: HMAC(text, secretKey) — secret used as HMAC key, NOT appended
8
+ *
9
+ * The result is hex-encoded (lowercase).
10
+ * MD5 = 32 chars, SHA-1 = 40 chars, HMAC-SHA256 = 64 chars
11
+ */
12
+ export declare function computeHash(text: string, secretKey: string, algorithm?: HashAlgorithm): string;
13
+ /**
14
+ * Build MAC string from an ordered array of [KEY, VALUE] pairs.
15
+ * Optional fields that are undefined/null/empty are SKIPPED entirely (per spec).
16
+ * Format: KEY1=value1&KEY2=value2&...
17
+ *
18
+ * For SHA-1/MD5, the secret key is appended: ...&secretKey
19
+ * For HMAC-SHA256, the secret key is used as HMAC key (not in the string)
20
+ */
21
+ export declare function generateMAC(fields: [string, string | number | undefined | null][], secretKey: string, algorithm?: HashAlgorithm): string;
22
+ /**
23
+ * Verify a MAC received in a response.
24
+ */
25
+ export declare function verifyMAC(fields: [string, string | number | undefined | null][], secretKey: string, receivedMac: string, algorithm?: HashAlgorithm): boolean;
26
+ //# sourceMappingURL=mac.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mac.d.ts","sourceRoot":"","sources":["../src/mac.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAE,aAA6B,GAAG,MAAM,CAW7G;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,EAAE,EACtD,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,aAA6B,GACvC,MAAM,CAkBR;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,EAAE,EACtD,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,aAA6B,GACvC,OAAO,CAIT"}
package/dist/mac.js ADDED
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.computeHash = computeHash;
7
+ exports.generateMAC = generateMAC;
8
+ exports.verifyMAC = verifyMAC;
9
+ const crypto_js_1 = __importDefault(require("crypto-js"));
10
+ /**
11
+ * Generate MAC hash using the specified algorithm.
12
+ *
13
+ * Per SIA VPOS spec:
14
+ * - SHA-1 and MD5: Hash(text + secretKey) — secret appended to string
15
+ * - HMAC-SHA256: HMAC(text, secretKey) — secret used as HMAC key, NOT appended
16
+ *
17
+ * The result is hex-encoded (lowercase).
18
+ * MD5 = 32 chars, SHA-1 = 40 chars, HMAC-SHA256 = 64 chars
19
+ */
20
+ function computeHash(text, secretKey, algorithm = 'hmac-sha256') {
21
+ switch (algorithm) {
22
+ case 'md5':
23
+ return crypto_js_1.default.MD5(text + secretKey).toString(crypto_js_1.default.enc.Hex);
24
+ case 'sha1':
25
+ return crypto_js_1.default.SHA1(text + secretKey).toString(crypto_js_1.default.enc.Hex);
26
+ case 'hmac-sha256':
27
+ return crypto_js_1.default.HmacSHA256(text, secretKey).toString(crypto_js_1.default.enc.Hex);
28
+ default:
29
+ throw new Error(`Unsupported hash algorithm: ${algorithm}`);
30
+ }
31
+ }
32
+ /**
33
+ * Build MAC string from an ordered array of [KEY, VALUE] pairs.
34
+ * Optional fields that are undefined/null/empty are SKIPPED entirely (per spec).
35
+ * Format: KEY1=value1&KEY2=value2&...
36
+ *
37
+ * For SHA-1/MD5, the secret key is appended: ...&secretKey
38
+ * For HMAC-SHA256, the secret key is used as HMAC key (not in the string)
39
+ */
40
+ function generateMAC(fields, secretKey, algorithm = 'hmac-sha256') {
41
+ const parts = [];
42
+ for (const [key, value] of fields) {
43
+ if (value === undefined || value === null || value === '')
44
+ continue;
45
+ parts.push(`${key}=${value}`);
46
+ }
47
+ const macString = parts.join('&');
48
+ if (algorithm === 'hmac-sha256') {
49
+ // HMAC-256: secret key is NOT appended; it's used as the HMAC key
50
+ return computeHash(macString, secretKey, algorithm);
51
+ }
52
+ else {
53
+ // SHA-1 / MD5: secret key IS appended to the string
54
+ // The computeHash function already handles this (text + secretKey)
55
+ return computeHash(macString, secretKey, algorithm);
56
+ }
57
+ }
58
+ /**
59
+ * Verify a MAC received in a response.
60
+ */
61
+ function verifyMAC(fields, secretKey, receivedMac, algorithm = 'hmac-sha256') {
62
+ if (!receivedMac || receivedMac === 'NULL')
63
+ return false;
64
+ const computed = generateMAC(fields, secretKey, algorithm);
65
+ return computed.toLowerCase() === receivedMac.toLowerCase();
66
+ }
67
+ //# sourceMappingURL=mac.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mac.js","sourceRoot":"","sources":["../src/mac.ts"],"names":[],"mappings":";;;;;AAaA,kCAWC;AAUD,kCAsBC;AAKD,8BASC;AAtED,0DAAiC;AAGjC;;;;;;;;;GASG;AACH,SAAgB,WAAW,CAAC,IAAY,EAAE,SAAiB,EAAE,YAA2B,aAAa;IACnG,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,KAAK;YACR,OAAO,mBAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,QAAQ,CAAC,mBAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnE,KAAK,MAAM;YACT,OAAO,mBAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,QAAQ,CAAC,mBAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpE,KAAK,aAAa;YAChB,OAAO,mBAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,mBAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACzE;YACE,MAAM,IAAI,KAAK,CAAC,+BAA+B,SAAS,EAAE,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,WAAW,CACzB,MAAsD,EACtD,SAAiB,EACjB,YAA2B,aAAa;IAExC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QAClC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;YAAE,SAAS;QACpE,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAElC,IAAI,SAAS,KAAK,aAAa,EAAE,CAAC;QAChC,kEAAkE;QAClE,OAAO,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACtD,CAAC;SAAM,CAAC;QACN,oDAAoD;QACpD,mEAAmE;QACnE,OAAO,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CACvB,MAAsD,EACtD,SAAiB,EACjB,WAAmB,EACnB,YAA2B,aAAa;IAExC,IAAI,CAAC,WAAW,IAAI,WAAW,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACzD,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAC3D,OAAO,QAAQ,CAAC,WAAW,EAAE,KAAK,WAAW,CAAC,WAAW,EAAE,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,268 @@
1
+ export type HashAlgorithm = 'sha1' | 'md5' | 'hmac-sha256';
2
+ export type VposEnvironment = 'test' | 'production';
3
+ export interface VposConfig {
4
+ /** Merchant store identifier (MID) - 15 chars */
5
+ shopId: string;
6
+ /** Operator identifier (User ID) - 8-18 chars */
7
+ operatorId: string;
8
+ /** Shared secret string (50 or 100 chars) */
9
+ secretKey: string;
10
+ /** Hash algorithm: 'sha1' | 'md5' | 'hmac-sha256' (recommended) */
11
+ hashAlgorithm?: HashAlgorithm;
12
+ /** Environment: 'test' or 'production'. Defaults to 'test' for safety.
13
+ * Can also be set via VPOS_ENV environment variable. */
14
+ environment?: VposEnvironment;
15
+ /** Custom API URL - overrides environment-based URL if provided */
16
+ apiUrl?: string;
17
+ /** Release version - defaults to '02' */
18
+ release?: string;
19
+ }
20
+ export interface HeaderData {
21
+ shopId: string;
22
+ operatorId: string;
23
+ reqRefNum: string;
24
+ }
25
+ export interface AuthorizationRequest {
26
+ /** Unique order identifier (1-50 chars) */
27
+ orderId: string;
28
+ /** Card number (PAN) - 10-19 chars */
29
+ pan: string;
30
+ /** Card expiry date - yyMM format */
31
+ expDate: string;
32
+ /** Amount in smallest currency unit (EUR cents) */
33
+ amount: number;
34
+ /** ISO currency code (978 = EUR) */
35
+ currency?: string;
36
+ /** Exponent of the currency */
37
+ exponent?: string;
38
+ /** Accounting mode: D=Deferred, I=Immediate */
39
+ accountingMode: 'D' | 'I';
40
+ /** Network code (01=VISA, 02=MasterCard, etc. 93=auto) */
41
+ network: string;
42
+ /** CVV2 code (optional) */
43
+ cvv2?: string;
44
+ /** Create PAN alias: S=DO, null=DON'T */
45
+ createPanAlias?: 'S';
46
+ /** Cardholder email */
47
+ emailCH?: string;
48
+ /** Cardholder identifier */
49
+ userId?: string;
50
+ /** Acquirer code */
51
+ acquirer?: string;
52
+ /** IP address */
53
+ ipAddress?: string;
54
+ /** Operation description (max 100) */
55
+ opDescr?: string;
56
+ /** User auth flag: 0=occasional, 1=registered, 2=unrecognized */
57
+ usrAuthFlag?: '0' | '1' | '2';
58
+ /** Additional options (max 26 chars) */
59
+ options?: string;
60
+ /** Antifraud payload */
61
+ antifraud?: string;
62
+ /** Sale identifier (max 15) */
63
+ productRef?: string;
64
+ /** Cardholder first name (max 40) */
65
+ name?: string;
66
+ /** Cardholder surname (max 40) */
67
+ surname?: string;
68
+ /** Cardholder tax ID (max 16) */
69
+ taxId?: string;
70
+ /** Recurring payment type: R, U, C */
71
+ tRecurr?: 'R' | 'U' | 'C';
72
+ /** Recurring code (max 50) */
73
+ cRecurr?: string;
74
+ /** Installments number (0-99) */
75
+ installmentsNumber?: string;
76
+ }
77
+ export interface AuthorizationResponse {
78
+ paymentType: string;
79
+ authorizationType: string;
80
+ transactionId: string;
81
+ network: string;
82
+ orderId: string;
83
+ transactionAmount: string;
84
+ authorizedAmount: string;
85
+ currency: string;
86
+ exponent: string;
87
+ accountedAmount: string;
88
+ refundedAmount: string;
89
+ transactionResult: string;
90
+ timestamp: string;
91
+ authorizationNumber: string;
92
+ acquirerBIN: string;
93
+ merchantId: string;
94
+ transactionStatus: string;
95
+ responseCodeISO?: string;
96
+ panTail?: string;
97
+ panExpiryDate?: string;
98
+ paymentTypePP?: string;
99
+ rrn?: string;
100
+ cardType?: string;
101
+ cardholderInfo?: string;
102
+ ibanCode?: string;
103
+ mac: string;
104
+ }
105
+ export interface PanAliasData {
106
+ panAlias: string;
107
+ panAliasRev: string;
108
+ panAliasExpDate: string;
109
+ panAliasTail: string;
110
+ cRecurr?: string;
111
+ mac: string;
112
+ }
113
+ export interface CreateLinkRequest {
114
+ /** Send email: Y or N */
115
+ sendMail: 'Y' | 'N';
116
+ /** Link expiration (yyyy-MM-ddTHH:mm:ss.SSS) */
117
+ linkExpirationDate?: string;
118
+ /** Amount in smallest currency unit (EUR cents) */
119
+ linkAmount: number;
120
+ /** ISO currency code (978 = EUR) */
121
+ linkCurrency?: string;
122
+ /** Currency exponent */
123
+ linkExponent?: string;
124
+ /** Unique order identifier (max 50, must be unique for 5 years) */
125
+ linkOrderId: string;
126
+ /** Redirect URL on success (max 254) */
127
+ linkUrlDone?: string;
128
+ /** Server-to-server notification URL (max 254) */
129
+ linkUrlMs: string;
130
+ /** Accounting mode: D=Deferred, I=Immediate */
131
+ linkAccountingMode: 'D' | 'I';
132
+ /** Authorization mode (must be 'I') */
133
+ linkAuthorMode: 'I';
134
+ /** Language: ITA or EN */
135
+ linkLang?: string;
136
+ /** Shop email for transaction outcome (max 50) */
137
+ linkShopEmail?: string;
138
+ /** Additional options (max 10) */
139
+ linkOptions?: string;
140
+ /** Commission amount in cents (max 8) */
141
+ linkCommis?: string;
142
+ /** Cardholder email (max 50) */
143
+ linkEmail?: string;
144
+ /** Cardholder name (max 40) */
145
+ linkName: string;
146
+ /** Cardholder surname (max 40) */
147
+ linkSurname: string;
148
+ /** Order description (max 140) */
149
+ linkOrdDescr?: string;
150
+ /** Operation description (max 100) */
151
+ linkOpDescr?: string;
152
+ /** Phone number for Jiffy (10-14 chars) */
153
+ linkPhoneNumber?: string;
154
+ /** Min months of card remaining duration (0-60) */
155
+ linkRemainingDuration?: string;
156
+ /** Merchant user ID (max 255) */
157
+ linkUserId?: string;
158
+ /** Sale identifier (max 15) */
159
+ linkProductRef?: string;
160
+ /** Recurring type: R, U, C */
161
+ linkTRecurr?: 'R' | 'U' | 'C';
162
+ /** Recurring code (max 50) */
163
+ linkCRecurr?: string;
164
+ /** 3DS data (max 5000) */
165
+ threeDsData?: string;
166
+ /** Additional options */
167
+ options?: string;
168
+ }
169
+ export interface LinkCreatedData {
170
+ completeLink: string;
171
+ token: string;
172
+ creationDate: string;
173
+ status: string;
174
+ lastUseDate: string;
175
+ expirationDate: string;
176
+ revokeDate: string;
177
+ orderId: string;
178
+ mac: string;
179
+ }
180
+ export interface ListLinkRequest {
181
+ /** Search start date (yyyy-MM-dd) */
182
+ startDate: string;
183
+ /** Search end date (yyyy-MM-dd) */
184
+ endDate: string;
185
+ /** Filter by status */
186
+ linkStatus?: string;
187
+ /** Filter by order ID */
188
+ orderId?: string;
189
+ /** Filter by token */
190
+ token?: string;
191
+ /** Additional options */
192
+ options?: string;
193
+ }
194
+ export interface RevokeLinkRequest {
195
+ /** Token of the link to revoke */
196
+ token: string;
197
+ /** Additional options */
198
+ options?: string;
199
+ }
200
+ export interface AccountingRequest {
201
+ /** Transaction ID from the authorization */
202
+ transactionId: string;
203
+ /** Order ID */
204
+ orderId: string;
205
+ /** Amount in cents */
206
+ amount: number;
207
+ /** ISO currency code */
208
+ currency?: string;
209
+ /** Currency exponent */
210
+ exponent?: string;
211
+ /** Operation description (max 100) */
212
+ opDescr?: string;
213
+ /** Additional options */
214
+ options?: string;
215
+ }
216
+ export interface ReverseAccountingRequest {
217
+ /** Transaction ID of the booking to cancel */
218
+ transactionId: string;
219
+ /** Order ID */
220
+ orderId: string;
221
+ /** Additional options */
222
+ options?: string;
223
+ }
224
+ export interface RefundRequest {
225
+ /** Transaction ID of the authorization */
226
+ transactionId: string;
227
+ /** Order ID */
228
+ orderId: string;
229
+ /** Amount to refund in cents */
230
+ amount: number;
231
+ /** ISO currency code */
232
+ currency?: string;
233
+ /** Currency exponent */
234
+ exponent?: string;
235
+ /** Operation description (max 100) */
236
+ opDescr?: string;
237
+ /** Additional options */
238
+ options?: string;
239
+ }
240
+ export interface OrderStatusRequest {
241
+ /** Order ID to query */
242
+ orderId: string;
243
+ /** Product reference */
244
+ productRef?: string;
245
+ /** Additional options */
246
+ options?: string;
247
+ }
248
+ export interface OperationData {
249
+ transactionId: string;
250
+ timestampReq: string;
251
+ timestampElab: string;
252
+ srcType: string;
253
+ amount: string;
254
+ result: string;
255
+ status: string;
256
+ opDescr?: string;
257
+ mac: string;
258
+ authorization?: AuthorizationResponse;
259
+ }
260
+ export interface VposResponse {
261
+ timestamp: string;
262
+ result: string;
263
+ mac: string;
264
+ data?: Record<string, any>;
265
+ }
266
+ export declare const RESULT_CODES: Record<string, string>;
267
+ export declare const LINK_STATUS: Record<string, string>;
268
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}