SIRE
RVIE y RCE, por qué mirar y comprometer son rutas distintas, y por qué no hay dónde ensayar.
El Sistema Integrado de Registros Electrónicos de SUNAT: el registro de ventas (RVIE) y el de compras (RCE) de un contribuyente, mes a mes.
Es otra SUNAT que la de emisión, y conviene saberlo antes de empezar: REST en vez de SOAP, OAuth2 en vez de certificado, ticket en vez de CDR, y el periodo en vez del comprobante. La frontera de firma no participa en nada de esto.
No hay entorno de ensayo. SUNAT no publica un SIRE de pruebas — los manuales v22 nombran dos
hosts de servicio y ninguna variante de pruebas. El e-beta.sunat.gob.pe que aparece al buscar es
el beta de emisión, otro producto. La primera vez que ejecutes el camino completo será sobre
el periodo real de un contribuyente real, y por eso todo lo de abajo insiste tanto.
Antes de nada: la empresa tiene que estar en producción
SIRE sólo conoce RUC reales. Una empresa que todavía emite en BETA no puede tener ni una fila
de SIRE: lo rechaza la base de datos, no una comprobación en la ruta.
{ "error": { "code": "SIRE_REQUIRES_PRODUCTION" } }Pásala a producción primero. En la consola es «Pasar a producción».
Y unas credenciales que no son las de siempre
SIRE usa el mismo par client_id / client_secret que la consulta de validez de CPE, y los cambia
por un token de forma distinta: /clientessol/ con password, que identifica a la aplicación
y a la persona —RUC, usuario SOL y clave—, frente al /clientesextranet/ con
client_credentials de CPE, que identifica sólo a la aplicación.
Hay un requisito que no es nuestro y no podemos modelar. Al crear las credenciales en el portal de SUNAT, el contribuyente registra una aplicación y marca las URI que va a consumir. Tiene que estar marcada «MIGE RCE y RVIE - SIRE». Una aplicación registrada en su día sólo para consultar CPE no la tiene, y su par no servirá aquí por bien guardado que esté. Es una propiedad de lo que alguien marcó en un portal, no de tus datos.
El ciclo de un periodo
abrir → ver propuesta → aceptar y generar → esperar ticket → registrado| Estado | Qué significa |
|---|---|
PENDING | Abierto. No se ha pedido nada a SUNAT |
PROPOSAL_READY | La propuesta se descargó y está para revisar |
ACCEPTED | Se aceptó la propuesta |
AWAITING_TICKET | SUNAT está procesando; hay ticket |
REGISTERED | El registro quedó generado |
FAILED | SUNAT dijo que no, con código |
AMBIGUOUS | No se puede saber si SUNAT aplicó el último acto |
Abrir no manda nada
curl -X POST https://apifact.fac-360.com/api/v2/sire/periods/rvie/202607 \
-H "Authorization: Bearer $APIFACT_TOKEN"El libro va como palabra —rvie o rce— y no como los códigos 140000 y 080000 de SUNAT. La
traducción vive dentro, que es donde no se equivoca nadie.
Abrir un periodo es una fila en tu registro diciendo que alguien va a trabajar sobre ese mes. Le
basta el scope sire:read: exigir sire:manage para esto haría imposible mirar sin tener además la
capacidad de cerrar un periodo.
Mirar y comprometer son rutas distintas
# MIRAR: descarga la propuesta de SUNAT y para. scope sire:read
curl -X POST .../sire/periods/rvie/202607/proposal -H "Authorization: Bearer $T"
# COMPROMETER: acepta la propuesta y genera el registro. scope sire:manage
curl -X POST .../sire/periods/rvie/202607/generation -H "Authorization: Bearer $T"No es la misma ruta con una bandera, y eso es deliberado. La diferencia entre mirar y
comprometer no puede vivir en un campo JSON: el día que alguien deje ese campo puesto, un periodo
queda cerrado y no hay operación inversa — ninguna ruta de esta plataforma retira un registro
generado. Es el mismo razonamiento que hizo de POST /api/v2/documents/validations una ruta y no
un dry-run.
Las dos contestan 202 y entregan el periodo a un ciclo durable. El resultado se consulta en
GET /api/v2/sire/periods/{book}/{period}.
Una llamada repetida no duplica nada: el identificador de la instancia es el de la operación, así que pedir dos veces la misma ejecución produce una.
AMBIGUOUS es terminal, y no es un error del que se reintente
Es el estado que más importa entender.
No significa que fallara. Significa que no se puede establecer si SUNAT aplicó el último acto —
un fallo de transporte sobre una llamada que cambia el periodo, o un 2xx cuyo ticket no se pudo
leer. El registro puede haber arrancado, y no hay forma de preguntar por un ticket cuyo número no
tenemos.
Volver a ejecutarlo podría generar el registro dos veces, y eso no se deshace. Así que:
- la plataforma no reintenta jamás un periodo en este estado;
- la consola no ofrece ningún botón para él;
- lo resuelve una persona, mirando en SUNAT qué ocurrió de verdad.
Un rechazo con código de SUNAT es otra cosa: eso es FAILED, con el código guardado, porque
«falló» no le sirve a nadie y 1033 sí.
Desde la consola
En SIRE, con rol ADMIN — el mismo tramo que los scopes, para que el rol de una persona y el
permiso de una credencial no puedan discrepar sobre quién cierra un periodo.
La pantalla mantiene la separación en dos botones: «Ver propuesta» y «Generar». Y generar pide escribir el periodo a mano antes de confirmar. No es fricción decorativa: es la única acción de la consola que no tiene vuelta atrás y que además no tiene dónde ensayarse.
Lo que todavía no hace
- Contrastar la propuesta de RCE con tus compras reales. La propuesta la arma SUNAT con lo que otros emitieron contra tu RUC, así que el flujo normal no te exige cargar nada. Comparar eso con tus compras es valor añadido y aún no está.
- Cargar ajustes y no domiciliados, que van por TUS y no por
POST.