
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@stackflow-lab/tef-elgin
Advanced tools
SDK Node.js para integração com Elgin TEF - Terminal de pagamentos eletrônicos
SDK Node.js para integração com Elgin TEF - Terminal de pagamentos eletrônicos
payment.pix(), payment.credit()E1_Tef01.dll instalada em C:\Elgin\TEF\127.0.0.1:60906)npm install @stackflow-lab/tef-elgin
ou
yarn add @stackflow-lab/tef-elgin
import { Client } from "@stackflow-lab/tef-elgin";
// 1. Criar instância do cliente
const client = Client.instance();
// 2. Configurar conexão
client.configure("127.0.0.1", 60906, {
pinpadText: "MINHA LOJA",
version: "v1.0.0",
storeName: "Minha Loja",
storeCode: "01",
terminalId: "T0001",
});
// 3. Configurar eventos
client.on("approved", ({ authorizationCode, nsu }) => {
console.log(`Aprovado! NSU: ${nsu}`);
});
client.on("error", (code, message) => {
console.error(`Erro [${code}]: ${message}`);
});
// 4. Realizar pagamento
await client.payment.pix(10);
import { Client } from "@stackflow-lab/tef-elgin";
const client = Client.instance();
// Caminho customizado para a DLL (opcional)
// const client = Client.instance('D:\\MinhaDLL\\E1_Tef01.dll')
client.configure(ip, port, {
pinpadText: "NOME LOJA", // Texto exibido no pinpad
version: "v1.0.0", // Versão da aplicação
storeName: "Nome Completo", // Nome do estabelecimento
storeCode: "01", // Código da loja
terminalId: "T0001", // ID do terminal/PDV
});
await client.payment.pix(50);
await client.payment.credit(100);
await client.payment.debit(75.5);
// O pinpad perguntará ao cliente qual tipo usar
await client.payment.ask(80);
// Voucher (alimentação/refeição)
await client.payment.voucher(45);
// Frota
await client.payment.fleet(200);
// Private Label
await client.payment.privateLabel(150);
await client.admin.cancel();
await client.admin.pending();
await client.admin.reprint();
// O pinpad perguntará qual operação realizar
await client.admin.ask();
Configure handlers para os eventos da transação:
// Mensagem informativa
client.on("display", (message) => {
console.log(`[TEF] ${message}`);
});
// Aguardando processamento
client.on("waiting", (message) => {
console.log(`[AGUARDE] ${message}`);
});
// Coletar texto do usuário
client.on("collect:text", async ({ message, type, mask }) => {
const value = await getUserInput(message);
client.input(value);
// ou client.cancel() para cancelar
});
// Coletar opção (menu)
client.on("collect:options", async ({ message, options }) => {
const index = await getUserChoice(options);
client.input(String(index));
});
// QR Code PIX
client.on("qrcode", ({ data }) => {
displayQRCode(data);
});
// Comprovantes
client.on("print", ({ store, customer }) => {
printReceipt(store, customer);
});
// Transação aprovada
client.on(
"approved",
({
sequenceId,
authorizationCode,
cardBrand,
maskedPan,
nsu,
totalAmount,
transactionDateTime,
// ... outros campos disponíveis
}) => {
console.log(`Aprovado!`);
console.log(`NSU: ${nsu}`);
console.log(`Autorização: ${authorizationCode}`);
console.log(`Valor: R$ ${(Number(totalAmount) / 100).toFixed(2)}`);
},
);
// Transação negada
client.on("declined", (code, message) => {
console.error(`Negado [${code}]: ${message}`);
});
// Erro
client.on("error", (code, message) => {
console.error(`Erro [${code}]: ${message}`);
});
// Operação finalizada
client.on("finished", () => {
console.log("Operação concluída");
});
Ative o modo debug para ver todas as chamadas DLL e respostas:
// Habilitar debug
client.enableDebug();
// Realizar operações...
await client.payment.pix(10);
// Desabilitar debug
client.disableDebug();
Output de debug:
[15:23:45.123] 🐛 Debug mode enabled
[15:23:45.124] 📡 Configuring client { ip: '127.0.0.1', port: 60906, ... }
[15:23:46.001] 🚀 Starting TEF session
[15:23:46.002] 💰 Starting PIX { amount: '10.00' }
[15:23:46.003] 📞 Calling pix TEF { payload: { ... }, isNew: true }
[15:23:46.150] 📥 DLL Response { tef: { ... } }
[15:23:46.151] 📝 Emitting collect:text { message: 'Digite o CPF', ... }
[15:23:50.234] 📤 User responded 12345678901
[15:23:55.678] ✅ Emitting approved { sequenceId: '123', ... }
Veja a documentação completa de debug para mais detalhes.
Client.instance(dllPath?: string): Client - Cria nova instânciaconfigure(ip: string, port: number, config: PdvConfig): void - Configura clienteenableDebug(): void - Ativa logs de debugdisableDebug(): void - Desativa logs de debuginput(value: string): void - Envia valor coletado do usuáriocancel(): void - Cancela operação em andamentounload(): void - Descarrega DLLpix(amount: number): Promise<void> - Pagamento PIXcredit(amount: number): Promise<void> - Créditodebit(amount: number): Promise<void> - Débitovoucher(amount: number): Promise<void> - Voucherfleet(amount: number): Promise<void> - FrotaprivateLabel(amount: number): Promise<void> - Private Labelask(amount: number): Promise<void> - Pergunta tipo de cartãocancel(): Promise<void> - Cancelamentopending(): Promise<void> - Pendênciasreprint(): Promise<void> - Reimpressãoask(): Promise<void> - Pergunta operação| Evento | Parâmetros | Descrição |
|---|---|---|
display | (message: string) | Mensagem informativa |
waiting | (message: string) | Aguardando processamento |
collect:text | (data: CollectTextEvent) | Coletar texto do usuário |
collect:options | (data: CollectOptionsEvent) | Coletar opção (menu) |
qrcode | (data: QrCodeEvent) | QR Code PIX disponível |
print | (data: PrintEvent) | Comprovantes para impressão |
approved | (data: ApprovedEvent) | Transação aprovada |
declined | (code: string, message: string) | Transação negada |
error | (code: string, message: string) | Erro na operação |
finished | () | Operação finalizada |
confirmed | () | Transação confirmada |
interface PdvConfig {
pinpadText: string; // Texto no pinpad
version: string; // Versão da aplicação
storeName: string; // Nome do estabelecimento
storeCode: string; // Código da loja
terminalId: string; // ID do terminal
}
interface ApprovedEvent {
sequenceId: string;
needsConfirmation: boolean;
acquirerDocument?: string;
authorizationCode?: string;
transactionDateTime?: string;
paymentMethod?: string;
merchantId?: string;
terminalId?: string;
message?: string;
cardBrand?: string;
merchantName?: string;
provider?: string;
nsu?: string;
maskedPan?: string;
result?: string;
service?: string;
cardType?: string;
transaction?: string;
uniqueId?: string;
totalAmount?: string;
}
Veja todos os tipos em src/types.ts.
import * as readline from "node:readline";
import { Client } from "@stackflow-lab/tef-elgin";
const client = Client.instance();
// Configurar
client.configure("127.0.0.1", 60906, {
pinpadText: "LOJA EXEMPLO",
version: "v1.0.0",
storeName: "Loja Exemplo Ltda",
storeCode: "001",
terminalId: "PDV01",
});
// Interface readline para coletar dados
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
function ask(question: string): Promise<string> {
return new Promise((resolve) => rl.question(question, resolve));
}
// Eventos
client.on("display", (msg) => console.log(`\n[TEF] ${msg}`));
client.on("waiting", (msg) => console.log(`[AGUARDE] ${msg}`));
client.on("collect:text", async ({ message, type, mask }) => {
const value = await ask(`${message}: `);
if (value) {
client.input(value);
} else {
client.cancel();
}
});
client.on("collect:options", async ({ message, options }) => {
console.log(`\n${message}`);
options.forEach((opt, i) => console.log(` [${i}] ${opt}`));
const value = await ask("Escolha: ");
client.input(value);
});
client.on("qrcode", ({ data }) => {
console.log("\n[QR CODE GERADO]");
// Aqui você pode gerar e exibir o QR Code
});
client.on("print", ({ store, customer }) => {
console.log("\n--- COMPROVANTE LOJA ---");
console.log(store);
console.log("\n--- COMPROVANTE CLIENTE ---");
console.log(customer);
});
client.on(
"approved",
({ sequenceId, authorizationCode, cardBrand, nsu, totalAmount }) => {
console.log("\n✅ TRANSAÇÃO APROVADA");
console.log(`Sequencial: ${sequenceId}`);
console.log(`Autorização: ${authorizationCode}`);
console.log(`Bandeira: ${cardBrand}`);
console.log(`NSU: ${nsu}`);
console.log(`Valor: R$ ${(Number(totalAmount) / 100).toFixed(2)}`);
},
);
client.on("declined", (code, message) => {
console.error(`\n❌ TRANSAÇÃO NEGADA [${code}]: ${message}`);
});
client.on("error", (code, message) => {
console.error(`\n⚠️ ERRO [${code}]: ${message}`);
});
client.on("finished", async () => {
console.log("\n✓ Operação finalizada\n");
rl.close();
});
// Executar
async function main() {
const value = await ask("Valor da venda: R$ ");
await client.payment.credit(parseFloat(value));
}
main().catch(console.error);
Veja mais exemplos em playground/.
DLL não encontrada:
Error: Could not find module 'C:\Elgin\TEF\E1_Tef01.dll'
Solução: Instale o Elgin TEF Client
Servidor não disponível:
Erro [-1]: Falha ao iniciar operação TEF
Solução: Verifique se o Elgin TEF Client está rodando
Operação não implementada:
Erro [-1]: Not implemented
Solução: Operação não disponível no provedor TEF atual
// Sempre trate erros
client.on("error", (code, message) => {
logger.error(`TEF Error [${code}]: ${message}`);
// Notificar usuário
// Reverter operações se necessário
});
// Sempre trate negações
client.on("declined", (code, message) => {
logger.warn(`TEF Declined [${code}]: ${message}`);
// Informar usuário
// Permitir nova tentativa
});
// Sempre finalize corretamente
process.on("SIGINT", () => {
client.unload();
process.exit(0);
});
MIT © stackflow-lab
Contribuições são bem-vindas! Por favor, leia o guia de contribuição primeiro.
Desenvolvido com ❤️ pela Stackflow
FAQs
SDK Node.js para integração com Elgin TEF - Terminal de pagamentos eletrônicos
We found that @stackflow-lab/tef-elgin demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.