feat(sire): RVIE Ventas + RCE Compras automation#4
Merged
Conversation
Adds end-to-end automation for SUNAT SIRE — the mandatory monthly
electronic books filing system that all CPE emisores must complete
since 2024 (multa up to 1 UIT per late filing).
Replaces the painful SOL portal SIRE workflow with scriptable commands.
What's new:
1. OAuth password grant (SIRE-specific)
- oauth.ts extended: when username/password provided, switches from
client_credentials to password grant + clientessol endpoint
- Same in-process token cache + 401 retry as PR #3
- CPE consulta (PR #3) keeps working unchanged
- Three host families now: api-seguridad, api, api-sire
2. SIRE client (src/sunat-rest/sire.ts)
- listarPeriodos(codLibro) — GET ejercicios y periodos disponibles
- descargarPropuesta({codLibro, perTributario}) — async, returns ticket
- descargarRvie(perTributario) — async, returns ticket
- aceptarPropuestaRvie(perTributario) — POST, returns ticket
- consultarTicket(numTicket) — GET status (01/03/06/07/10)
- descargarArchivo({...}) — streams the actual ZIP/TXT bytes
- pollTicket({...}) — backoff 2s/4s/8s/16s/30s, max 5min
- codLibro: 140000 RVIE, 080000 RCE
- sireCredentials() helper builds the password-grant creds shape
3. Commands: sunat sire {ventas|compras} ...
- periodos — listar ejercicios y periodos
- propuesta — descargar propuesta SUNAT (async, --wait, --out)
- ticket --num X — consultar/poll cualquier ticket
- archivo --nombre — bajar archivo por nombre + tipo
- aceptar (ventas) — T2, requires --yes, accepts SUNAT proposal as-is
- descargar (ventas)— bajar el RVIE ya generado del periodo
4. Tests (14 nuevos, 223 total)
- sireCredentials concat RUC+SOL_USER, scope sire
- OAuth password grant: posts to clientessol with grant_type=password
- listarPeriodos hits api-sire host with codLibro in path
- descargarPropuesta: RVIE vs RCE use different endpoints
- descargarRvie hits exportarregistropropuesta
- aceptarPropuestaRvie POSTs to /aceptapropuesta
- consultarTicket: maps registros[0], handles empty
- pollTicket: completed/error/still-processing transitions
What's deliberately NOT shipped (deferred to follow-up PRs):
- Reemplazar propuesta + Importar comprobantes — TUS.IO resumable upload
protocol, SUNAT's own note says JAVA client required. Needs TUS.IO
client work as separate PR.
- Reportes complementarios (resumen, inconsistencias, CAR, casillas, etc) —
same async pattern, easy adds when needed.
- Tipo de cambio masivo — JSON POST, easy add.
- Smoke test — RUC test 20000000001 (PR #1) doesn't have RVIE periods,
needs real RUC with billing history. Verify after first prod run.
See src/sunat-rest/SIRE-RESEARCH.md for full endpoint specs.
This was referenced Apr 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
End-to-end automation for SUNAT SIRE (Sistema Integrado de Registros Electrónicos) — the mandatory monthly electronic books filing system that all CPE emisores must complete since 2024.
Why this matters: SIRE is the biggest monthly tax dolor for any empresa peruana. Late filing = multa hasta 1 UIT (S/5,350 in 2026). Today contadores do this manually in the SOL portal every month. This PR automates 95% of the workflow.
What's in this PR
SIRE-specific OAuth (password grant)
oauth.ts: whenusername/passwordprovided, switches fromclient_credentials→passwordgrant +clientessolendpoint variantapi-sire.sunat.gob.pe(separate fromapi.sunat.gob.peused in PR feat(rest): consulta CPE OAuth + padrón RUC local #3)SIRE client (
src/sunat-rest/sire.ts)listarPeriodos(codLibro)— GET ejercicios + periodos disponiblesdescargarPropuesta({codLibro, perTributario})— async, returns ticketdescargarRvie(perTributario)— async, returns ticketaceptarPropuestaRvie(perTributario)— POST, returns ticketconsultarTicket(numTicket)— GET status (01/03/06/07/10)descargarArchivo({...})— streams the ZIP/TXT bytespollTicket({...})— backoff 2s/4s/8s/16s/30s, max 5mincodLibro: 140000 RVIE | 080000 RCEsireCredentials()builds the password-grant creds shapeCommands
--waitpolls getStatus until terminal (06=Terminado, 07/10=error). Without--wait, returns ticket for manual polling.Tests
What's NOT in this PR (deferred)
propuesta, easy addsSUNAT specs honored
All endpoints follow Manual de Servicios Web Api SIRE Ventas v22 (March 2024) verified shapes. See
src/sunat-rest/SIRE-RESEARCH.mdfor full mapping.SUNAT's note: "los servicios del API SIRE no deben ser consumidos desde un cliente Web, en caso de utilizar un cliente Web se producirá error de CORS". CLI is server-side, no CORS concern.
Test plan
bun testgreen (223 pass / 2 skip / 0 fail)sunat sire --helplists ventas + comprassunat sire ventas --helplists 5 verbs