@stackflow-lab/tef-elgin 1.0.3

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Stackflow Lab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,546 @@
1
+ # Elgin TEF SDK
2
+
3
+ > SDK Node.js para integração com Elgin TEF - Terminal de pagamentos eletrônicos
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@stackflow-lab/elgin-sdk.svg)](https://www.npmjs.com/package/@stackflow-lab/elgin-sdk)
6
+ [![License](https://img.shields.io/npm/l/@stackflow-lab/elgin-sdk.svg)](https://github.com/stackflow-lab/elgin-sdk/blob/main/LICENSE)
7
+
8
+ ## 📋 Índice
9
+
10
+ - [Características](#-características)
11
+ - [Requisitos](#-requisitos)
12
+ - [Instalação](#-instalação)
13
+ - [Início Rápido](#-início-rápido)
14
+ - [Uso](#-uso)
15
+ - [Configuração](#configuração)
16
+ - [Pagamentos](#pagamentos)
17
+ - [Operações Administrativas](#operações-administrativas)
18
+ - [Eventos](#eventos)
19
+ - [Debug](#-debug)
20
+ - [API Reference](#-api-reference)
21
+ - [Exemplos](#-exemplos)
22
+ - [Tratamento de Erros](#-tratamento-de-erros)
23
+ - [Licença](#-licença)
24
+
25
+ ## ✨ Características
26
+
27
+ - 🎯 **API Intuitiva** - Métodos direcionados como `payment.pix()`, `payment.credit()`
28
+ - 🔄 **Event-driven** - Arquitetura baseada em eventos para máximo controle
29
+ - 📦 **TypeScript** - Totalmente tipado para melhor experiência de desenvolvimento
30
+ - 🐛 **Debug Built-in** - Sistema de logs detalhados para desenvolvimento
31
+ - ✅ **Testado** - 100% de cobertura de testes
32
+ - 🚀 **Moderno** - ESM + CJS, Node.js 22+
33
+
34
+ ## 📦 Requisitos
35
+
36
+ - **Node.js**: >= 22.0.0
37
+ - **Sistema Operacional**: Windows (requerido pela DLL da Elgin)
38
+ - **DLL Elgin TEF**: `E1_Tef01.dll` instalada em `C:\Elgin\TEF\`
39
+ - **Elgin TEF Client**: Servidor TEF rodando (padrão: `127.0.0.1:60906`)
40
+
41
+ ## 🚀 Instalação
42
+
43
+ ```bash
44
+ npm install @stackflow-lab/elgin-sdk
45
+ ```
46
+
47
+ ou
48
+
49
+ ```bash
50
+ yarn add @stackflow-lab/elgin-sdk
51
+ ```
52
+
53
+ ## ⚡ Início Rápido
54
+
55
+ ```typescript
56
+ import { Client } from "@stackflow-lab/elgin-sdk";
57
+
58
+ // 1. Criar instância do cliente
59
+ const client = Client.instance();
60
+
61
+ // 2. Configurar conexão
62
+ client.configure("127.0.0.1", 60906, {
63
+ pinpadText: "MINHA LOJA",
64
+ version: "v1.0.0",
65
+ storeName: "Minha Loja",
66
+ storeCode: "01",
67
+ terminalId: "T0001",
68
+ });
69
+
70
+ // 3. Configurar eventos
71
+ client.on("approved", ({ authorizationCode, nsu }) => {
72
+ console.log(`Aprovado! NSU: ${nsu}`);
73
+ });
74
+
75
+ client.on("error", (code, message) => {
76
+ console.error(`Erro [${code}]: ${message}`);
77
+ });
78
+
79
+ // 4. Realizar pagamento
80
+ await client.payment.pix("10.00");
81
+ ```
82
+
83
+ ## 📖 Uso
84
+
85
+ ### Configuração
86
+
87
+ ```typescript
88
+ import { Client } from "@stackflow-lab/elgin-sdk";
89
+
90
+ const client = Client.instance();
91
+
92
+ // Caminho customizado para a DLL (opcional)
93
+ // const client = Client.instance('D:\\MinhaDLL\\E1_Tef01.dll')
94
+
95
+ client.configure(ip, port, {
96
+ pinpadText: "NOME LOJA", // Texto exibido no pinpad
97
+ version: "v1.0.0", // Versão da aplicação
98
+ storeName: "Nome Completo", // Nome do estabelecimento
99
+ storeCode: "01", // Código da loja
100
+ terminalId: "T0001", // ID do terminal/PDV
101
+ });
102
+ ```
103
+
104
+ ### Pagamentos
105
+
106
+ #### PIX
107
+
108
+ ```typescript
109
+ await client.payment.pix("50.00");
110
+ ```
111
+
112
+ #### Cartão de Crédito
113
+
114
+ ```typescript
115
+ await client.payment.credit("100.00");
116
+ ```
117
+
118
+ #### Cartão de Débito
119
+
120
+ ```typescript
121
+ await client.payment.debit("75.50");
122
+ ```
123
+
124
+ #### Perguntar Tipo de Cartão
125
+
126
+ ```typescript
127
+ // O pinpad perguntará ao cliente qual tipo usar
128
+ await client.payment.ask("80.00");
129
+ ```
130
+
131
+ #### Outros Tipos
132
+
133
+ ```typescript
134
+ // Voucher (alimentação/refeição)
135
+ await client.payment.voucher("45.00");
136
+
137
+ // Frota
138
+ await client.payment.fleet("200.00");
139
+
140
+ // Private Label
141
+ await client.payment.privateLabel("150.00");
142
+ ```
143
+
144
+ ### Operações Administrativas
145
+
146
+ #### Cancelamento
147
+
148
+ ```typescript
149
+ await client.admin.cancel();
150
+ ```
151
+
152
+ #### Consultar Pendências
153
+
154
+ ```typescript
155
+ await client.admin.pending();
156
+ ```
157
+
158
+ #### Reimpressão
159
+
160
+ ```typescript
161
+ await client.admin.reprint();
162
+ ```
163
+
164
+ #### Perguntar Operação
165
+
166
+ ```typescript
167
+ // O pinpad perguntará qual operação realizar
168
+ await client.admin.ask();
169
+ ```
170
+
171
+ ### Eventos
172
+
173
+ Configure handlers para os eventos da transação:
174
+
175
+ ```typescript
176
+ // Mensagem informativa
177
+ client.on("display", (message) => {
178
+ console.log(`[TEF] ${message}`);
179
+ });
180
+
181
+ // Aguardando processamento
182
+ client.on("waiting", (message) => {
183
+ console.log(`[AGUARDE] ${message}`);
184
+ });
185
+
186
+ // Coletar texto do usuário
187
+ client.on("collect:text", async ({ message, type, mask }) => {
188
+ const value = await getUserInput(message);
189
+ client.respond(value);
190
+ // ou client.cancel() para cancelar
191
+ });
192
+
193
+ // Coletar opção (menu)
194
+ client.on("collect:options", async ({ message, options }) => {
195
+ const index = await getUserChoice(options);
196
+ client.respond(String(index));
197
+ });
198
+
199
+ // QR Code PIX
200
+ client.on("qrcode", ({ data }) => {
201
+ displayQRCode(data);
202
+ });
203
+
204
+ // Comprovantes
205
+ client.on("print", ({ store, customer }) => {
206
+ printReceipt(store, customer);
207
+ });
208
+
209
+ // Transação aprovada
210
+ client.on(
211
+ "approved",
212
+ ({
213
+ sequenceId,
214
+ authorizationCode,
215
+ cardBrand,
216
+ maskedPan,
217
+ nsu,
218
+ totalAmount,
219
+ transactionDateTime,
220
+ // ... outros campos disponíveis
221
+ }) => {
222
+ console.log(`Aprovado!`);
223
+ console.log(`NSU: ${nsu}`);
224
+ console.log(`Autorização: ${authorizationCode}`);
225
+ console.log(`Valor: R$ ${(Number(totalAmount) / 100).toFixed(2)}`);
226
+ },
227
+ );
228
+
229
+ // Transação negada
230
+ client.on("declined", (code, message) => {
231
+ console.error(`Negado [${code}]: ${message}`);
232
+ });
233
+
234
+ // Erro
235
+ client.on("error", (code, message) => {
236
+ console.error(`Erro [${code}]: ${message}`);
237
+ });
238
+
239
+ // Operação finalizada
240
+ client.on("finished", () => {
241
+ console.log("Operação concluída");
242
+ });
243
+ ```
244
+
245
+ ## 🐛 Debug
246
+
247
+ Ative o modo debug para ver todas as chamadas DLL e respostas:
248
+
249
+ ```typescript
250
+ // Habilitar debug
251
+ client.enableDebug();
252
+
253
+ // Realizar operações...
254
+ await client.payment.pix("10.00");
255
+
256
+ // Desabilitar debug
257
+ client.disableDebug();
258
+ ```
259
+
260
+ **Output de debug:**
261
+
262
+ ```
263
+ [15:23:45.123] 🐛 Debug mode enabled
264
+ [15:23:45.124] 📡 Configuring client { ip: '127.0.0.1', port: 60906, ... }
265
+ [15:23:46.001] 🚀 Starting TEF session
266
+ [15:23:46.002] 💰 Starting PIX { amount: '10.00' }
267
+ [15:23:46.003] 📞 Calling pix TEF { payload: { ... }, isNew: true }
268
+ [15:23:46.150] 📥 DLL Response { tef: { ... } }
269
+ [15:23:46.151] 📝 Emitting collect:text { message: 'Digite o CPF', ... }
270
+ [15:23:50.234] 📤 User responded 12345678901
271
+ [15:23:55.678] ✅ Emitting approved { sequenceId: '123', ... }
272
+ ```
273
+
274
+ Veja a [documentação completa de debug](docs/DEBUG.md) para mais detalhes.
275
+
276
+ ## 📚 API Reference
277
+
278
+ ### Client
279
+
280
+ #### Métodos Estáticos
281
+
282
+ - `Client.instance(dllPath?: string): Client` - Cria nova instância
283
+
284
+ #### Métodos de Configuração
285
+
286
+ - `configure(ip: string, port: number, config: PdvConfig): void` - Configura cliente
287
+ - `enableDebug(): void` - Ativa logs de debug
288
+ - `disableDebug(): void` - Desativa logs de debug
289
+
290
+ #### Métodos de Controle
291
+
292
+ - `respond(value: string): void` - Responde à coleta
293
+ - `cancel(): void` - Cancela operação em andamento
294
+ - `unload(): void` - Descarrega DLL
295
+
296
+ ### PaymentApi (client.payment)
297
+
298
+ - `pix(amount: string): Promise<void>` - Pagamento PIX
299
+ - `credit(amount: string): Promise<void>` - Crédito
300
+ - `debit(amount: string): Promise<void>` - Débito
301
+ - `voucher(amount: string): Promise<void>` - Voucher
302
+ - `fleet(amount: string): Promise<void>` - Frota
303
+ - `privateLabel(amount: string): Promise<void>` - Private Label
304
+ - `ask(amount: string): Promise<void>` - Pergunta tipo de cartão
305
+
306
+ ### AdminApi (client.admin)
307
+
308
+ - `cancel(): Promise<void>` - Cancelamento
309
+ - `pending(): Promise<void>` - Pendências
310
+ - `reprint(): Promise<void>` - Reimpressão
311
+ - `ask(): Promise<void>` - Pergunta operação
312
+
313
+ ### Eventos
314
+
315
+ | Evento | Parâmetros | Descrição |
316
+ | ----------------- | --------------------------------- | --------------------------- |
317
+ | `display` | `(message: string)` | Mensagem informativa |
318
+ | `waiting` | `(message: string)` | Aguardando processamento |
319
+ | `collect:text` | `(data: CollectTextEvent)` | Coletar texto do usuário |
320
+ | `collect:options` | `(data: CollectOptionsEvent)` | Coletar opção (menu) |
321
+ | `qrcode` | `(data: QrCodeEvent)` | QR Code PIX disponível |
322
+ | `print` | `(data: PrintEvent)` | Comprovantes para impressão |
323
+ | `approved` | `(data: ApprovedEvent)` | Transação aprovada |
324
+ | `declined` | `(code: string, message: string)` | Transação negada |
325
+ | `error` | `(code: string, message: string)` | Erro na operação |
326
+ | `finished` | `()` | Operação finalizada |
327
+ | `confirmed` | `()` | Transação confirmada |
328
+
329
+ ### Tipos
330
+
331
+ #### PdvConfig
332
+
333
+ ```typescript
334
+ interface PdvConfig {
335
+ pinpadText: string; // Texto no pinpad
336
+ version: string; // Versão da aplicação
337
+ storeName: string; // Nome do estabelecimento
338
+ storeCode: string; // Código da loja
339
+ terminalId: string; // ID do terminal
340
+ }
341
+ ```
342
+
343
+ #### ApprovedEvent
344
+
345
+ ```typescript
346
+ interface ApprovedEvent {
347
+ sequenceId: string;
348
+ needsConfirmation: boolean;
349
+ acquirerDocument?: string;
350
+ authorizationCode?: string;
351
+ transactionDateTime?: string;
352
+ paymentMethod?: string;
353
+ merchantId?: string;
354
+ terminalId?: string;
355
+ message?: string;
356
+ cardBrand?: string;
357
+ merchantName?: string;
358
+ provider?: string;
359
+ nsu?: string;
360
+ maskedPan?: string;
361
+ result?: string;
362
+ service?: string;
363
+ cardType?: string;
364
+ transaction?: string;
365
+ uniqueId?: string;
366
+ totalAmount?: string;
367
+ }
368
+ ```
369
+
370
+ Veja todos os tipos em [src/types.ts](src/types.ts).
371
+
372
+ ## 💡 Exemplos
373
+
374
+ ### Exemplo Completo: Sistema de Pagamento
375
+
376
+ ```typescript
377
+ import * as readline from "node:readline";
378
+ import { Client } from "@stackflow-lab/elgin-sdk";
379
+
380
+ const client = Client.instance();
381
+
382
+ // Configurar
383
+ client.configure("127.0.0.1", 60906, {
384
+ pinpadText: "LOJA EXEMPLO",
385
+ version: "v1.0.0",
386
+ storeName: "Loja Exemplo Ltda",
387
+ storeCode: "001",
388
+ terminalId: "PDV01",
389
+ });
390
+
391
+ // Interface readline para coletar dados
392
+ const rl = readline.createInterface({
393
+ input: process.stdin,
394
+ output: process.stdout,
395
+ });
396
+
397
+ function ask(question: string): Promise<string> {
398
+ return new Promise((resolve) => rl.question(question, resolve));
399
+ }
400
+
401
+ // Eventos
402
+ client.on("display", (msg) => console.log(`\n[TEF] ${msg}`));
403
+ client.on("waiting", (msg) => console.log(`[AGUARDE] ${msg}`));
404
+
405
+ client.on("collect:text", async ({ message, type, mask }) => {
406
+ const value = await ask(`${message}: `);
407
+ if (value) {
408
+ client.respond(value);
409
+ } else {
410
+ client.cancel();
411
+ }
412
+ });
413
+
414
+ client.on("collect:options", async ({ message, options }) => {
415
+ console.log(`\n${message}`);
416
+ options.forEach((opt, i) => console.log(` [${i}] ${opt}`));
417
+ const value = await ask("Escolha: ");
418
+ client.respond(value);
419
+ });
420
+
421
+ client.on("qrcode", ({ data }) => {
422
+ console.log("\n[QR CODE GERADO]");
423
+ // Aqui você pode gerar e exibir o QR Code
424
+ });
425
+
426
+ client.on("print", ({ store, customer }) => {
427
+ console.log("\n--- COMPROVANTE LOJA ---");
428
+ console.log(store);
429
+ console.log("\n--- COMPROVANTE CLIENTE ---");
430
+ console.log(customer);
431
+ });
432
+
433
+ client.on(
434
+ "approved",
435
+ ({ sequenceId, authorizationCode, cardBrand, nsu, totalAmount }) => {
436
+ console.log("\n✅ TRANSAÇÃO APROVADA");
437
+ console.log(`Sequencial: ${sequenceId}`);
438
+ console.log(`Autorização: ${authorizationCode}`);
439
+ console.log(`Bandeira: ${cardBrand}`);
440
+ console.log(`NSU: ${nsu}`);
441
+ console.log(`Valor: R$ ${(Number(totalAmount) / 100).toFixed(2)}`);
442
+ },
443
+ );
444
+
445
+ client.on("declined", (code, message) => {
446
+ console.error(`\n❌ TRANSAÇÃO NEGADA [${code}]: ${message}`);
447
+ });
448
+
449
+ client.on("error", (code, message) => {
450
+ console.error(`\n⚠️ ERRO [${code}]: ${message}`);
451
+ });
452
+
453
+ client.on("finished", async () => {
454
+ console.log("\n✓ Operação finalizada\n");
455
+ rl.close();
456
+ });
457
+
458
+ // Executar
459
+ async function main() {
460
+ const value = await ask("Valor da venda: R$ ");
461
+ await client.payment.credit(value);
462
+ }
463
+
464
+ main().catch(console.error);
465
+ ```
466
+
467
+ Veja mais exemplos em [playground/](playground/).
468
+
469
+ ## ⚠️ Tratamento de Erros
470
+
471
+ ### Erros Comuns
472
+
473
+ **DLL não encontrada:**
474
+
475
+ ```
476
+ Error: Could not find module 'C:\Elgin\TEF\E1_Tef01.dll'
477
+ ```
478
+
479
+ **Solução:** Instale o Elgin TEF Client
480
+
481
+ **Servidor não disponível:**
482
+
483
+ ```
484
+ Erro [-1]: Falha ao iniciar operação TEF
485
+ ```
486
+
487
+ **Solução:** Verifique se o Elgin TEF Client está rodando
488
+
489
+ **Operação não implementada:**
490
+
491
+ ```
492
+ Erro [-1]: Not implemented
493
+ ```
494
+
495
+ **Solução:** Operação não disponível no provedor TEF atual
496
+
497
+ ### Boas Práticas
498
+
499
+ ```typescript
500
+ // Sempre trate erros
501
+ client.on("error", (code, message) => {
502
+ logger.error(`TEF Error [${code}]: ${message}`);
503
+ // Notificar usuário
504
+ // Reverter operações se necessário
505
+ });
506
+
507
+ // Sempre trate negações
508
+ client.on("declined", (code, message) => {
509
+ logger.warn(`TEF Declined [${code}]: ${message}`);
510
+ // Informar usuário
511
+ // Permitir nova tentativa
512
+ });
513
+
514
+ // Sempre finalize corretamente
515
+ process.on("SIGINT", () => {
516
+ client.unload();
517
+ process.exit(0);
518
+ });
519
+ ```
520
+
521
+ ## 📝 Licença
522
+
523
+ MIT © [stackflow-lab](https://github.com/stackflow-lab)
524
+
525
+ ---
526
+
527
+ ## 🔗 Links Úteis
528
+
529
+ - [Documentação Elgin TEF](https://elgindevelopercommunity.github.io/group__t2.html)
530
+ - [Changelog](CHANGELOG.md)
531
+ - [Guia de Debug](docs/DEBUG.md)
532
+ - [API Detalhada](docs/NEW_API.md)
533
+
534
+ ## 🤝 Contribuindo
535
+
536
+ Contribuições são bem-vindas! Por favor, leia o [guia de contribuição](CONTRIBUTING.md) primeiro.
537
+
538
+ ## 💬 Suporte
539
+
540
+ - 📧 Email: suporte@stackflow-lab.com
541
+ - 🐛 Issues: [GitHub Issues](https://github.com/stackflow-lab/elgin-sdk/issues)
542
+ - 📖 Docs: [Documentação Completa](https://github.com/stackflow-lab/elgin-sdk/tree/main/docs)
543
+
544
+ ---
545
+
546
+ **Desenvolvido com ❤️ pela [stackflow-lab](https://stackflow-lab.com)**