Skip to main content
facturas gives your Node.js application a direct, typed connection to Argentina’s ARCA/AFIP tax authority. Instead of routing through a proxy service or a third-party API, the SDK communicates with WSFE and WSMTXCA over SOAP using credentials you register yourself — so your invoices stay under your own CUIT, your data never touches an intermediary, and you control the full lifecycle of every fiscal document.

What ARCA/AFIP is and why direct integration matters

ARCA (formerly AFIP) is Argentina’s federal tax authority. Every Argentine business must issue electronic invoices (comprobantes) through ARCA’s web services, and those invoices must carry a CAE (Código de Autorización Electrónica) that ARCA grants at the moment of issuance. Without a valid CAE, an invoice has no fiscal standing. Historically, developers used proxy services to avoid dealing with SOAP, XML signing, and credential management directly. Those proxies add latency, cost, and an additional trust boundary. facturas handles all of that inside your process: it signs WSAA authentication tokens, caches them, derives invoice types from your issuer condition, maps JavaScript-style inputs to the wire format, and parses every response into a typed outcome — so you never read raw SOAP.

Key capabilities

WSFE — Simple invoices

Issue and query Facturas A, B, C, and their credit and debit note variants. Works for monotributo, responsable inscripto, exento, and no alcanzado issuers.

WSMTXCA — Itemized invoices

Issue detailed invoices with line-item breakdowns through the WSMTXCA service using the same arca.issue() facade by passing { service: "wsmtxca" }.

Padrón lookups

Query ARCA’s Padrón to look up a taxpayer’s fiscal condition, name, and registered activities before issuing a Factura A.

Safe retries

Pair a store (Postgres, Redis, file, or memory) with an idempotencyKey so that a crash between number reservation and authorization never causes a duplicate invoice.
The SDK also includes a CLI (npx facturas) that generates your private key and CSR, walks you through ARCA’s registration portal step by step, and runs a layered diagnostic (npx facturas check) that names exactly which configuration layer is broken — without writing anything to ARCA.

Requirements

  • Node.js >= 20 — the SDK uses native crypto APIs and top-level ESM features
  • ESM only — add "type": "module" to your package.json, or use .mjs file extensions
  • Four environment variablesARCA_TAX_ID, ARCA_CERTIFICATE_PEM, ARCA_PRIVATE_KEY_PEM, ARCA_ENVIRONMENT
No database, no external service, and no additional infrastructure is required to start issuing invoices. Optional stores (Postgres, Redis, file) unlock durable idempotency and shared WSAA session caching for multi-worker deployments.

How facturas fits into your application

In a typical integration, facturas lives alongside your order or billing service. When a sale is confirmed, your code calls arca.issue() with the sale’s details. The SDK authenticates with WSAA (reusing a cached ticket if one exists), reserves the next voucher number, calls WSFE or WSMTXCA to authorize the invoice, and returns one of four typed outcomes: authorized, rejected, indeterminate, or conflict. You handle each outcome and persist the CAE with your own order record.
There is no webhook, no polling loop, and no background job needed for basic issuance — each call is synchronous from your code’s perspective.

Public API surface

The main export is createArcaClient(), which returns an ArcaClient with: The client also exposes arca.wsfe, arca.wsmtxca, and arca.padron as low-level service properties for direct SOAP operations. The factory functions createWsfeService(), createWsmtxcaService(), and createPadronService() are also exported if you need to instantiate them independently.

Quick Start

Set environment variables and issue your first invoice.

ARCA Setup

Generate a key and CSR, register with ARCA, and verify every layer.
Pre-1.0: pin the exact version. While the package version starts with 0., any minor release may introduce breaking changes to the public API. Set "facturas": "0.11.0" (or whatever the current version is) in your package.json — not a range — and read the changelog before every upgrade.