@qrcommunication/viva-local-terminal-sdk 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/CHANGELOG.md +26 -0
- package/LICENSE +21 -0
- package/README.md +252 -0
- package/dist/index.cjs +422 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +593 -0
- package/dist/index.d.ts +593 -0
- package/dist/index.js +409 -0
- package/dist/index.js.map +1 -0
- package/package.json +85 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,593 @@
|
|
|
1
|
+
import { Dispatcher } from 'undici';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for the Viva.com Local Terminal API.
|
|
5
|
+
*
|
|
6
|
+
* Unlike the Viva cloud APIs (api.vivapayments.com, OAuth2), the Local Terminal
|
|
7
|
+
* API is a PEER-TO-PEER (P2P) protocol: the client talks DIRECTLY to the EFT POS
|
|
8
|
+
* terminal over the local network. There is therefore:
|
|
9
|
+
*
|
|
10
|
+
* - NO cloud "environment" (demo/production) — the base URL is the terminal's
|
|
11
|
+
* own IP address and port, e.g. `https://192.168.1.50:8080`.
|
|
12
|
+
* - NO authentication. The official spec states verbatim:
|
|
13
|
+
* "In a closed network environment, authentication is not required for
|
|
14
|
+
* peer-to-peer communication. [...] eliminating the need to include an
|
|
15
|
+
* Authorization tag in the header."
|
|
16
|
+
*
|
|
17
|
+
* The terminal serves HTTPS, usually with a self-signed certificate. By default
|
|
18
|
+
* this SDK VERIFIES TLS. On a closed LAN with a self-signed terminal cert you
|
|
19
|
+
* typically pass `verifyTls: false` (accepting the LAN-only trust model).
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
interface VivaLocalTerminalConfigOptions {
|
|
23
|
+
/**
|
|
24
|
+
* The terminal's base URL: scheme + IP + port, e.g.
|
|
25
|
+
* `https://192.168.1.50:8080`. A trailing slash, if present, is stripped.
|
|
26
|
+
*/
|
|
27
|
+
terminalBaseUrl: string;
|
|
28
|
+
/**
|
|
29
|
+
* TLS certificate verification.
|
|
30
|
+
*
|
|
31
|
+
* `true` (default) verifies the terminal's certificate against the system CA
|
|
32
|
+
* bundle. `false` disables verification, which is the common case for a
|
|
33
|
+
* self-signed terminal certificate on a trusted closed LAN.
|
|
34
|
+
*/
|
|
35
|
+
verifyTls?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Target the ISV (trailing-slash) endpoint variants, e.g. `/pos/v1/sale/`.
|
|
38
|
+
* The merchant (default) variants use no trailing slash.
|
|
39
|
+
*/
|
|
40
|
+
useIsvEndpoints?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Per-request timeout in milliseconds. Terminal interactions are async (they
|
|
43
|
+
* return PROCESSING immediately), so a short timeout is fine for the
|
|
44
|
+
* initiating call. Defaults to 30000 (30s).
|
|
45
|
+
*/
|
|
46
|
+
timeout?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Optional `fetch` implementation override (mainly for testing). Defaults to
|
|
49
|
+
* the platform global `fetch` (Node 18+, browsers, Deno).
|
|
50
|
+
*/
|
|
51
|
+
fetch?: typeof fetch;
|
|
52
|
+
/**
|
|
53
|
+
* Optional undici `Dispatcher` override. When omitted and `verifyTls` is
|
|
54
|
+
* `false` on Node, an undici `Agent` with `connect.rejectUnauthorized = false`
|
|
55
|
+
* is created automatically so the self-signed terminal cert is accepted.
|
|
56
|
+
*/
|
|
57
|
+
dispatcher?: Dispatcher;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Immutable runtime configuration for the Local Terminal client.
|
|
61
|
+
*/
|
|
62
|
+
declare class VivaLocalTerminalConfig {
|
|
63
|
+
/** The normalized terminal base URL (no trailing slash). */
|
|
64
|
+
readonly baseUrl: string;
|
|
65
|
+
readonly verifyTls: boolean;
|
|
66
|
+
readonly useIsvEndpoints: boolean;
|
|
67
|
+
readonly timeout: number;
|
|
68
|
+
readonly fetch: typeof fetch;
|
|
69
|
+
readonly dispatcher: Dispatcher | undefined;
|
|
70
|
+
constructor(options: VivaLocalTerminalConfigOptions);
|
|
71
|
+
/**
|
|
72
|
+
* Build the absolute URL for a `/pos/v1/...` endpoint.
|
|
73
|
+
*
|
|
74
|
+
* The ISV variants of the endpoints differ only by a trailing slash. When
|
|
75
|
+
* {@link useIsvEndpoints} is true, a trailing slash is appended to the path
|
|
76
|
+
* (unless one is already present), matching the spec's `(ISV)` paths.
|
|
77
|
+
*/
|
|
78
|
+
url(path: string): string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
interface HttpRequestOptions {
|
|
82
|
+
query?: Record<string, string | number | boolean | undefined | null>;
|
|
83
|
+
body?: unknown;
|
|
84
|
+
signal?: AbortSignal;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Low-level HTTP client for the Local Terminal (P2P) API.
|
|
88
|
+
*
|
|
89
|
+
* Transport model:
|
|
90
|
+
* - Requests go DIRECTLY to the terminal on the LAN (base URL = terminal
|
|
91
|
+
* IP:port). There is NO cloud endpoint.
|
|
92
|
+
* - NO authentication: no Authorization header, no token exchange. The
|
|
93
|
+
* terminal trusts any caller on the closed network (per the official spec).
|
|
94
|
+
* - HTTPS is served by the terminal, often with a self-signed certificate. On
|
|
95
|
+
* Node, when `verifyTls` is `false`, an undici `Agent` with
|
|
96
|
+
* `connect.rejectUnauthorized = false` is used so the self-signed cert is
|
|
97
|
+
* accepted (the standard `fetch` API has no per-call TLS toggle).
|
|
98
|
+
*
|
|
99
|
+
* Error model:
|
|
100
|
+
* The API returns JSON on 2xx but a PLAIN STRING body on 400 (e.g.
|
|
101
|
+
* "ZeroconfException error message Amount cannot be null"). This client
|
|
102
|
+
* decodes JSON when possible and preserves the raw string under `raw`
|
|
103
|
+
* otherwise. The thrown {@link ApiError}'s message is that raw text.
|
|
104
|
+
*/
|
|
105
|
+
declare class HttpClient {
|
|
106
|
+
private readonly config;
|
|
107
|
+
private readonly dispatcher;
|
|
108
|
+
constructor(config: VivaLocalTerminalConfig);
|
|
109
|
+
get<T = unknown>(path: string, options?: Omit<HttpRequestOptions, "body">): Promise<T>;
|
|
110
|
+
post<T = unknown>(path: string, body?: unknown, options?: Omit<HttpRequestOptions, "body">): Promise<T>;
|
|
111
|
+
private request;
|
|
112
|
+
private buildUrl;
|
|
113
|
+
private decodeBody;
|
|
114
|
+
private buildException;
|
|
115
|
+
private mergeSignals;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Enumerations for the Viva.com Local Terminal API.
|
|
120
|
+
*
|
|
121
|
+
* These mirror the string/numeric values the terminal returns and accepts.
|
|
122
|
+
*/
|
|
123
|
+
/**
|
|
124
|
+
* The `paymentMethod` accepted by the sale request — the payment method
|
|
125
|
+
* displayed to the user first by default. The user may still choose an
|
|
126
|
+
* alternative method on the terminal.
|
|
127
|
+
*
|
|
128
|
+
* @see /pos/v1/sale
|
|
129
|
+
*/
|
|
130
|
+
declare enum PaymentMethod {
|
|
131
|
+
CARD_PRESENT = "CardPresent",
|
|
132
|
+
IRIS = "Iris"
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The `state` value returned by the Local Terminal API.
|
|
136
|
+
*
|
|
137
|
+
* Returned immediately by sale/refund/abort/etc. (PROCESSING, BUSY_ERROR, ...)
|
|
138
|
+
* and as the terminal/session outcome by GET /pos/v1/sessions/{sessionId}
|
|
139
|
+
* (SUCCESS, FAILURE).
|
|
140
|
+
*
|
|
141
|
+
* @see /pos/v1/sale, /pos/v1/sessions/{sessionId}
|
|
142
|
+
*/
|
|
143
|
+
declare enum SessionState {
|
|
144
|
+
/** The operation is in progress on the terminal. */
|
|
145
|
+
PROCESSING = "PROCESSING",
|
|
146
|
+
/** Another transaction is already in progress on the terminal. */
|
|
147
|
+
BUSY_ERROR = "BUSY_ERROR",
|
|
148
|
+
/** The terminal reported a server-side error. */
|
|
149
|
+
SERVER_ERROR = "SERVER_ERROR",
|
|
150
|
+
/** The given session id could not be found (abort). */
|
|
151
|
+
SESSION_NOT_FOUND_ERROR = "SESSION_NOT_FOUND_ERROR",
|
|
152
|
+
/** The transaction completed successfully (sessions outcome). */
|
|
153
|
+
SUCCESS = "SUCCESS",
|
|
154
|
+
/** The transaction completed with an error (sessions outcome). */
|
|
155
|
+
FAILURE = "FAILURE"
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* The `sessionType` returned by the Local Terminal API, indicating which kind
|
|
159
|
+
* of operation a session represents.
|
|
160
|
+
*
|
|
161
|
+
* @see /pos/v1/sale, /pos/v1/refund, /pos/v1/abort, /pos/v1/sessions/{sessionId}
|
|
162
|
+
*/
|
|
163
|
+
declare enum SessionType {
|
|
164
|
+
/** A sale transaction. */
|
|
165
|
+
SALE = "SALE",
|
|
166
|
+
/** A capture (completion) of a pre-authorized sale. */
|
|
167
|
+
CAPTURE_PREAUTH = "CAPTURE_PREAUTH",
|
|
168
|
+
/** A refund / cancellation referencing an original transaction. */
|
|
169
|
+
CANCEL = "CANCEL",
|
|
170
|
+
/** An unreferenced refund (not linked to an original transaction). */
|
|
171
|
+
UNREFERENCED_REFUND = "UNREFERENCED_REFUND",
|
|
172
|
+
/** An abort of an in-progress SALE session. */
|
|
173
|
+
ABORT = "ABORT"
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Transaction type identifiers returned in transaction / session payloads
|
|
177
|
+
* (`transactionTypeId`) and accepted as the `transactionTypes` query filter on
|
|
178
|
+
* GET /pos/v1/transactions.
|
|
179
|
+
*
|
|
180
|
+
* @see /pos/v1/transactions, /pos/v1/sessions/{sessionId}
|
|
181
|
+
*/
|
|
182
|
+
declare enum TransactionTypeId {
|
|
183
|
+
SALE = 5,
|
|
184
|
+
REFUND = 4,
|
|
185
|
+
REVERSAL = 7,
|
|
186
|
+
IRIS_SALE = 60,
|
|
187
|
+
IRIS_REFUND = 61,
|
|
188
|
+
IRIS_VOID = 85
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Immediate response returned by sale / capture / refund / abort operations.
|
|
193
|
+
*
|
|
194
|
+
* The terminal returns this synchronously with `state` typically `PROCESSING`.
|
|
195
|
+
* Poll {@link SessionResponse} via `sessions.get(sessionId)` for the outcome.
|
|
196
|
+
*/
|
|
197
|
+
interface TransactionResponse {
|
|
198
|
+
/** Operation state, e.g. PROCESSING, BUSY_ERROR. */
|
|
199
|
+
state?: SessionState | string;
|
|
200
|
+
/** The kind of session created, e.g. SALE, CANCEL. */
|
|
201
|
+
sessionType?: SessionType | string;
|
|
202
|
+
/** The session id echoed back (the one you passed in). */
|
|
203
|
+
sessionId?: string;
|
|
204
|
+
[key: string]: unknown;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Full session details returned by GET /pos/v1/sessions/{sessionId}.
|
|
208
|
+
*
|
|
209
|
+
* `payloadData` is populated only once the transaction has completed (state
|
|
210
|
+
* SUCCESS or FAILURE).
|
|
211
|
+
*/
|
|
212
|
+
interface SessionResponse {
|
|
213
|
+
state?: SessionState | string;
|
|
214
|
+
sessionType?: SessionType | string;
|
|
215
|
+
sessionId?: string;
|
|
216
|
+
/** Final transaction payload, present once the session has completed. */
|
|
217
|
+
payloadData?: Record<string, unknown>;
|
|
218
|
+
[key: string]: unknown;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Response to AADE FIM control creation (Greek fiscalisation).
|
|
222
|
+
*
|
|
223
|
+
* @see /pos/v1/aade-fim-control
|
|
224
|
+
*/
|
|
225
|
+
interface AadeFimControlResponse {
|
|
226
|
+
status?: string;
|
|
227
|
+
message?: string;
|
|
228
|
+
[key: string]: unknown;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Response to historical transaction retrieval.
|
|
232
|
+
*
|
|
233
|
+
* @see /pos/v1/transactions
|
|
234
|
+
*/
|
|
235
|
+
interface TransactionsListResponse {
|
|
236
|
+
isSuccess?: boolean;
|
|
237
|
+
transactions?: Array<Record<string, unknown>>;
|
|
238
|
+
[key: string]: unknown;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Generic device-operation response (`screenControl`, `brightness`).
|
|
242
|
+
*
|
|
243
|
+
* @see /pos/v1/awake-lock, /pos/v1/brightness
|
|
244
|
+
*/
|
|
245
|
+
interface DeviceResponse {
|
|
246
|
+
isSuccess?: boolean;
|
|
247
|
+
[key: string]: unknown;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Device configuration operations on the Local Terminal (P2P) API.
|
|
252
|
+
*
|
|
253
|
+
* These control the physical terminal device directly: screen wake/sleep and
|
|
254
|
+
* display brightness.
|
|
255
|
+
*
|
|
256
|
+
* @see /pos/v1/awake-lock, /pos/v1/brightness
|
|
257
|
+
*/
|
|
258
|
+
declare class Device {
|
|
259
|
+
private readonly http;
|
|
260
|
+
constructor(http: HttpClient);
|
|
261
|
+
/**
|
|
262
|
+
* Control the device screen / sleep mode — POST /pos/v1/awake-lock.
|
|
263
|
+
*
|
|
264
|
+
* @param wakeUpLock When `true`, the device wakes from sleep and the screen
|
|
265
|
+
* stays active until the user unlocks it. When `false`, the device reverts
|
|
266
|
+
* to its normal sleep behavior.
|
|
267
|
+
*/
|
|
268
|
+
screenControl(wakeUpLock: boolean): Promise<DeviceResponse>;
|
|
269
|
+
/**
|
|
270
|
+
* Adjust the terminal app brightness — POST /pos/v1/brightness.
|
|
271
|
+
*
|
|
272
|
+
* @param brightness Value in the range (0, 1], where 1.00 is maximum
|
|
273
|
+
* brightness. A value of 0 is NOT allowed.
|
|
274
|
+
* @throws {RangeError} If `brightness` is not within (0, 1].
|
|
275
|
+
*/
|
|
276
|
+
brightness(brightness: number): Promise<DeviceResponse>;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Session retrieval on the Local Terminal (P2P) API.
|
|
281
|
+
*
|
|
282
|
+
* After a sale/refund/preauth-completion returns `PROCESSING`, poll the session
|
|
283
|
+
* to obtain the final outcome. The `payloadData` field is populated only once
|
|
284
|
+
* the transaction has completed (with `state` SUCCESS or FAILURE).
|
|
285
|
+
*
|
|
286
|
+
* The ISV variant uses a trailing slash (`/pos/v1/sessions/{id}/`), handled
|
|
287
|
+
* automatically when `useIsvEndpoints` is enabled.
|
|
288
|
+
*
|
|
289
|
+
* @see /pos/v1/sessions/{sessionId}
|
|
290
|
+
*/
|
|
291
|
+
declare class Sessions {
|
|
292
|
+
private readonly http;
|
|
293
|
+
constructor(http: HttpClient);
|
|
294
|
+
/**
|
|
295
|
+
* Retrieve a session's full details by its id —
|
|
296
|
+
* GET /pos/v1/sessions/{sessionId}.
|
|
297
|
+
*/
|
|
298
|
+
get(sessionId: string): Promise<SessionResponse>;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Parameters for {@link Transactions.sale} — POST /pos/v1/sale.
|
|
303
|
+
*
|
|
304
|
+
* Amounts are ALWAYS integers in the currency's minor unit (cents).
|
|
305
|
+
*/
|
|
306
|
+
interface SaleParams {
|
|
307
|
+
/** Caller-generated transaction session UUID. */
|
|
308
|
+
sessionId: string;
|
|
309
|
+
/** Amount to authorize, in cents. */
|
|
310
|
+
amount: number;
|
|
311
|
+
/** Free-text merchant reference. */
|
|
312
|
+
merchantReference?: string;
|
|
313
|
+
/** Free-text customer reference. */
|
|
314
|
+
customerTrns?: string;
|
|
315
|
+
/** Whether the payment is a pre-authorization. */
|
|
316
|
+
preauth?: boolean;
|
|
317
|
+
/** Tip amount in cents (not compatible with `preauth`). */
|
|
318
|
+
tipAmount?: number;
|
|
319
|
+
/** Default payment method shown first (e.g. "CardPresent"). */
|
|
320
|
+
paymentMethod?: PaymentMethod | string;
|
|
321
|
+
/** Whether to show the transaction result on screen. */
|
|
322
|
+
showTransactionResult?: boolean;
|
|
323
|
+
/** Whether to show the receipt and result on screen. */
|
|
324
|
+
showReceipt?: boolean;
|
|
325
|
+
/** ISO 4217 numeric currency code (merchant currency), e.g. 978 for EUR. */
|
|
326
|
+
currencyCode?: number;
|
|
327
|
+
/** Disable surcharge even on eligible cards. */
|
|
328
|
+
skipSurcharge?: boolean;
|
|
329
|
+
/** Base64-encoded JSON of extra acquirer metadata. */
|
|
330
|
+
saleToAcquirerData?: string;
|
|
331
|
+
/** Max instalments allowed (Greek merchants only). */
|
|
332
|
+
maxInstalments?: number;
|
|
333
|
+
/** AADE provider id (Greece). */
|
|
334
|
+
aadeProviderId?: string;
|
|
335
|
+
/** AADE provider signature data (Greece). */
|
|
336
|
+
aadeProviderSignatureData?: string;
|
|
337
|
+
/** AADE provider signature (Greece). */
|
|
338
|
+
aadeProviderSignature?: string;
|
|
339
|
+
/** AADE preloaded flag (Greece). */
|
|
340
|
+
aadePreloaded?: boolean;
|
|
341
|
+
/** AADE preloaded expiry duration (Greece). */
|
|
342
|
+
aadePreloadedDuration?: number;
|
|
343
|
+
/** Viva Fiscalisation object. */
|
|
344
|
+
fiscalisationData?: Record<string, unknown>;
|
|
345
|
+
/** ISV partner / fee / multi-merchant object (ISV endpoints only). */
|
|
346
|
+
isvDetails?: Record<string, unknown>;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Parameters for {@link Transactions.capturePreauth} —
|
|
350
|
+
* POST /pos/v1/preauth-completion.
|
|
351
|
+
*/
|
|
352
|
+
interface CapturePreauthParams {
|
|
353
|
+
/** Caller-generated transaction session UUID. */
|
|
354
|
+
sessionId: string;
|
|
355
|
+
/** Amount to capture, in cents. */
|
|
356
|
+
amount: number;
|
|
357
|
+
/** Transaction id of the original pre-authorized sale. */
|
|
358
|
+
transactionId: string;
|
|
359
|
+
merchantReference?: string;
|
|
360
|
+
customerTrns?: string;
|
|
361
|
+
/** ISO 4217 numeric currency code. */
|
|
362
|
+
currencyCode?: number;
|
|
363
|
+
saleToAcquirerData?: string;
|
|
364
|
+
aadeProviderId?: string;
|
|
365
|
+
aadeProviderSignatureData?: string;
|
|
366
|
+
aadeProviderSignature?: string;
|
|
367
|
+
aadePreloaded?: boolean;
|
|
368
|
+
aadePreloadedDuration?: number;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Parameters for {@link Transactions.refund} — POST /pos/v1/refund.
|
|
372
|
+
*
|
|
373
|
+
* A referenced refund / cancellation linked to an original transaction.
|
|
374
|
+
*/
|
|
375
|
+
interface RefundParams {
|
|
376
|
+
/** Caller-generated transaction session UUID. */
|
|
377
|
+
sessionId: string;
|
|
378
|
+
/** Amount to refund, in cents. */
|
|
379
|
+
amount: number;
|
|
380
|
+
/** Transaction id of the original sale to refund. */
|
|
381
|
+
transactionId: string;
|
|
382
|
+
/** Order code of the original sale. */
|
|
383
|
+
orderCode?: number;
|
|
384
|
+
/** Short order code (filter helper). */
|
|
385
|
+
shortOrderCode?: number;
|
|
386
|
+
merchantReference?: string;
|
|
387
|
+
customerTrns?: string;
|
|
388
|
+
currencyCode?: number;
|
|
389
|
+
showTransactionResult?: boolean;
|
|
390
|
+
showReceipt?: boolean;
|
|
391
|
+
/** ISO 8601 lower bound for locating the transaction. */
|
|
392
|
+
txnDateFrom?: string;
|
|
393
|
+
/** ISO 8601 upper bound for locating the transaction. */
|
|
394
|
+
txnDateTo?: string;
|
|
395
|
+
aadeProviderId?: string;
|
|
396
|
+
aadeProviderSignatureData?: string;
|
|
397
|
+
aadeProviderSignature?: string;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Parameters for {@link Transactions.unreferencedRefund} —
|
|
401
|
+
* POST /pos/v1/unreferenced-refund.
|
|
402
|
+
*/
|
|
403
|
+
interface UnreferencedRefundParams {
|
|
404
|
+
/** Caller-generated transaction session UUID. */
|
|
405
|
+
sessionId: string;
|
|
406
|
+
/** Amount to refund, in cents. */
|
|
407
|
+
amount: number;
|
|
408
|
+
merchantReference?: string;
|
|
409
|
+
customerTrns?: string;
|
|
410
|
+
showTransactionResult?: boolean;
|
|
411
|
+
showReceipt?: boolean;
|
|
412
|
+
aadeProviderId?: string;
|
|
413
|
+
aadeProviderSignatureData?: string;
|
|
414
|
+
aadeProviderSignature?: string;
|
|
415
|
+
fiscalisationData?: Record<string, unknown>;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Filters for {@link Transactions.retrieve} — GET /pos/v1/transactions.
|
|
419
|
+
*
|
|
420
|
+
* All filters are optional. `transactionTypes` may be a single id or a list.
|
|
421
|
+
*/
|
|
422
|
+
interface RetrieveTransactionsParams {
|
|
423
|
+
cardNumber?: string;
|
|
424
|
+
orderCode?: string;
|
|
425
|
+
transactionTypes?: TransactionTypeId | number | Array<TransactionTypeId | number>;
|
|
426
|
+
transactionStatus?: string;
|
|
427
|
+
/** ISO 8601 lower bound. */
|
|
428
|
+
startDate?: string;
|
|
429
|
+
/** ISO 8601 upper bound. */
|
|
430
|
+
endDate?: string;
|
|
431
|
+
isAadeAutonomouslyOnly?: boolean;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Transaction operations on the Local Terminal (P2P) API.
|
|
436
|
+
*
|
|
437
|
+
* Every operation that starts a transaction returns IMMEDIATELY with a `state`
|
|
438
|
+
* (typically `PROCESSING`) and a `sessionId`. The actual outcome is then polled
|
|
439
|
+
* via `sessions.get()` once the cardholder has interacted with the terminal.
|
|
440
|
+
*
|
|
441
|
+
* Amounts are ALWAYS integers in the currency's minor unit (cents).
|
|
442
|
+
*
|
|
443
|
+
* Merchant vs ISV variants: the same methods serve both. Whether a request hits
|
|
444
|
+
* the ISV trailing-slash path (e.g. `/pos/v1/sale/`) is controlled globally by
|
|
445
|
+
* `useIsvEndpoints`. ISV sale/refund additionally accept `isvDetails`.
|
|
446
|
+
*
|
|
447
|
+
* @see /pos/v1/sale, /pos/v1/preauth-completion, /pos/v1/refund,
|
|
448
|
+
* /pos/v1/unreferenced-refund, /pos/v1/abort, /pos/v1/aade-fim-control,
|
|
449
|
+
* /pos/v1/transactions
|
|
450
|
+
*/
|
|
451
|
+
declare class Transactions {
|
|
452
|
+
private readonly http;
|
|
453
|
+
constructor(http: HttpClient);
|
|
454
|
+
/**
|
|
455
|
+
* Initiate a sale request — POST /pos/v1/sale.
|
|
456
|
+
*
|
|
457
|
+
* The terminal displays the amount and waits for the card. Use
|
|
458
|
+
* `sessions.get()` with the returned `sessionId` to retrieve the final result.
|
|
459
|
+
*/
|
|
460
|
+
sale(params: SaleParams): Promise<TransactionResponse>;
|
|
461
|
+
/**
|
|
462
|
+
* Capture (complete) a previously pre-authorized sale —
|
|
463
|
+
* POST /pos/v1/preauth-completion.
|
|
464
|
+
*/
|
|
465
|
+
capturePreauth(params: CapturePreauthParams): Promise<TransactionResponse>;
|
|
466
|
+
/**
|
|
467
|
+
* Refund / cancel a transaction by its original transaction id —
|
|
468
|
+
* POST /pos/v1/refund.
|
|
469
|
+
*/
|
|
470
|
+
refund(params: RefundParams): Promise<TransactionResponse>;
|
|
471
|
+
/**
|
|
472
|
+
* Issue an unreferenced refund (not linked to an original transaction) —
|
|
473
|
+
* POST /pos/v1/unreferenced-refund.
|
|
474
|
+
*/
|
|
475
|
+
unreferencedRefund(params: UnreferencedRefundParams): Promise<TransactionResponse>;
|
|
476
|
+
/**
|
|
477
|
+
* Abort an in-progress SALE session — POST /pos/v1/abort.
|
|
478
|
+
*/
|
|
479
|
+
abort(sessionId: string): Promise<TransactionResponse>;
|
|
480
|
+
/**
|
|
481
|
+
* Create an AADE FIM control action — POST /pos/v1/aade-fim-control.
|
|
482
|
+
*
|
|
483
|
+
* Creates the Echo Message (to fetch the Master Key) and the Control Message
|
|
484
|
+
* (to create the Session Key), validating the Master Key, KCV and encrypted
|
|
485
|
+
* Session Key (Greek AADE fiscalisation).
|
|
486
|
+
*
|
|
487
|
+
* @param token The FIMAS control token including the AADE token.
|
|
488
|
+
*/
|
|
489
|
+
aadeFimControl(token: string): Promise<AadeFimControlResponse>;
|
|
490
|
+
/**
|
|
491
|
+
* Retrieve historical transactions with optional filters —
|
|
492
|
+
* GET /pos/v1/transactions.
|
|
493
|
+
*
|
|
494
|
+
* `transactionTypes` may be a single id or a list. When an array is passed it
|
|
495
|
+
* is sent as a comma-separated value.
|
|
496
|
+
*/
|
|
497
|
+
retrieve(params?: RetrieveTransactionsParams): Promise<TransactionsListResponse>;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
type VivaLocalTerminalClientOptions = VivaLocalTerminalConfigOptions;
|
|
501
|
+
/**
|
|
502
|
+
* Viva.com Local Terminal SDK — main entry point.
|
|
503
|
+
*
|
|
504
|
+
* The Local Terminal API is a PEER-TO-PEER (P2P) protocol: this client talks
|
|
505
|
+
* DIRECTLY to an EFT POS terminal over the local network. There is no Viva cloud
|
|
506
|
+
* endpoint and no authentication — you address the terminal's own IP and port.
|
|
507
|
+
*
|
|
508
|
+
* @example
|
|
509
|
+
* ```ts
|
|
510
|
+
* import { VivaLocalTerminalClient } from "@qrcommunication/viva-local-terminal-sdk";
|
|
511
|
+
* import { randomUUID } from "node:crypto";
|
|
512
|
+
*
|
|
513
|
+
* const terminal = new VivaLocalTerminalClient({
|
|
514
|
+
* terminalBaseUrl: "https://192.168.1.50:8080",
|
|
515
|
+
* // self-signed terminal cert on a closed LAN:
|
|
516
|
+
* verifyTls: false,
|
|
517
|
+
* });
|
|
518
|
+
*
|
|
519
|
+
* // Start a sale (amount in cents)
|
|
520
|
+
* const sessionId = randomUUID();
|
|
521
|
+
* const res = await terminal.transactions.sale({
|
|
522
|
+
* sessionId,
|
|
523
|
+
* amount: 1170, // 11.70 EUR
|
|
524
|
+
* currencyCode: 978, // EUR
|
|
525
|
+
* merchantReference: "order-123",
|
|
526
|
+
* });
|
|
527
|
+
* // res.state === "PROCESSING"
|
|
528
|
+
*
|
|
529
|
+
* // Poll for the result
|
|
530
|
+
* const session = await terminal.sessions.get(sessionId);
|
|
531
|
+
* // session.state === "SUCCESS" once the cardholder has paid
|
|
532
|
+
*
|
|
533
|
+
* // Control the device
|
|
534
|
+
* await terminal.device.screenControl(true);
|
|
535
|
+
* await terminal.device.brightness(0.5);
|
|
536
|
+
* ```
|
|
537
|
+
*/
|
|
538
|
+
declare class VivaLocalTerminalClient {
|
|
539
|
+
readonly transactions: Transactions;
|
|
540
|
+
readonly sessions: Sessions;
|
|
541
|
+
readonly device: Device;
|
|
542
|
+
private readonly config;
|
|
543
|
+
private readonly http;
|
|
544
|
+
constructor(options: VivaLocalTerminalClientOptions);
|
|
545
|
+
/** The resolved, immutable configuration in use by this client. */
|
|
546
|
+
getConfig(): VivaLocalTerminalConfig;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Error model for the Viva.com Local Terminal (P2P) API.
|
|
551
|
+
*
|
|
552
|
+
* The Local Terminal API does NOT return structured error codes. On a 400 it
|
|
553
|
+
* returns a PLAIN STRING body (e.g. "ZeroconfException error message Amount
|
|
554
|
+
* cannot be null"). The raw body is always preserved so callers can inspect the
|
|
555
|
+
* exact text the terminal sent back.
|
|
556
|
+
*/
|
|
557
|
+
/**
|
|
558
|
+
* Shape used to carry whatever the terminal returned on an error. When the body
|
|
559
|
+
* was JSON it is spread here; when it was a plain string it is preserved under
|
|
560
|
+
* `raw`.
|
|
561
|
+
*/
|
|
562
|
+
interface VivaErrorBody {
|
|
563
|
+
message?: string;
|
|
564
|
+
error?: string;
|
|
565
|
+
/** The raw, undecoded response body (set when the terminal returns a string). */
|
|
566
|
+
raw?: string;
|
|
567
|
+
[key: string]: unknown;
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Base error for every Viva Local Terminal SDK failure.
|
|
571
|
+
*/
|
|
572
|
+
declare class VivaError extends Error {
|
|
573
|
+
constructor(message: string);
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Thrown when the terminal returns an HTTP error (4xx/5xx) or when the request
|
|
577
|
+
* could not reach the terminal at all (httpStatus === 0).
|
|
578
|
+
*
|
|
579
|
+
* The Local Terminal API returns a plain string body on 400, so the human
|
|
580
|
+
* message is that raw string verbatim. Use {@link getErrorText} to retrieve it.
|
|
581
|
+
*/
|
|
582
|
+
declare class ApiError extends VivaError {
|
|
583
|
+
readonly httpStatus: number;
|
|
584
|
+
readonly responseBody: VivaErrorBody | null;
|
|
585
|
+
constructor(message: string, httpStatus: number, responseBody?: VivaErrorBody | null);
|
|
586
|
+
/**
|
|
587
|
+
* The error text reported by the terminal, preferring a structured field and
|
|
588
|
+
* falling back to the raw string body. Returns `null` if nothing was sent.
|
|
589
|
+
*/
|
|
590
|
+
getErrorText(): string | null;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
export { type AadeFimControlResponse, ApiError, type CapturePreauthParams, Device, type DeviceResponse, HttpClient, type HttpRequestOptions, PaymentMethod, type RefundParams, type RetrieveTransactionsParams, type SaleParams, type SessionResponse, SessionState, SessionType, Sessions, type TransactionResponse, TransactionTypeId, Transactions, type TransactionsListResponse, type UnreferencedRefundParams, VivaError, type VivaErrorBody, VivaLocalTerminalClient, type VivaLocalTerminalClientOptions, VivaLocalTerminalConfig, type VivaLocalTerminalConfigOptions };
|