Emitir una factura
Una factura (tipo 01 de SUNAT) se emite a un cliente con RUC. Lo mínimo es una serie, el
cliente y lo vendido:
curl https://api.emitay.com/v1/invoices \ -H "Authorization: Bearer $EMITAY_API_KEY" \ -H "Content-Type: application/json" \ -H "Prefer: wait=10" \ -d '{ "series": "F001", "customer": { "document_number": "20100066603", "name": "CLIENTE S.A." }, "items": [ { "description": "Servicio de consultoría", "quantity": 2, "unit_price": "50.00" } ] }'$cabeceras = @{ Authorization = "Bearer $env:EMITAY_API_KEY" Prefer = "wait=10"}$cuerpo = @'{ "series": "F001", "customer": { "document_number": "20100066603", "name": "CLIENTE S.A." }, "items": [ { "description": "Servicio de consultoría", "quantity": 2, "unit_price": "50.00" } ]}'@Invoke-RestMethod -Method Post ` -Uri https://api.emitay.com/v1/invoices ` -Headers $cabeceras ` -ContentType "application/json; charset=utf-8" ` -Body $cuerpoimport { Emitay } from "emitay";
const emitay = new Emitay(); // toma la llave de EMITAY_API_KEY
const factura = await emitay.invoices.create({ series: "F001", customer: { document_number: "20100066603", name: "CLIENTE S.A." }, items: [ { description: "Servicio de consultoría", quantity: 2, unit_price: "50.00" }, ],}, { wait: 10 });Prefer: wait=10 (wait en el SDK) hace que la respuesta espere a SUNAT hasta 10 segundos.
Sin él, la API responde al instante con la factura en pending; las dos formas están en
El veredicto de SUNAT.
Lo que no hace falta enviar
Sección titulada «Lo que no hace falta enviar»| Campo | Si se omite |
|---|---|
number |
El siguiente de la serie. Emitay lleva el correlativo, sin huecos |
issue_date, issue_time |
Hoy y ahora, en hora de Lima |
currency |
PEN |
customer.document_type |
"6", cuando document_number es un RUC válido |
items[].unit_code |
NIU (unidades). Para un servicio, ZZ |
items[].tax_affectation |
10: gravado con IGV |
items[].price_includes_tax |
false: unit_price es el valor sin IGV |
payment |
Al contado |
Los totales y los impuestos nunca se envían: los calcula Emitay y vuelven en total y
amounts.
Una factura con más datos
Sección titulada «Una factura con más datos»En dólares, con orden de compra, observaciones y el correo del cliente:
curl https://api.emitay.com/v1/invoices \ -H "Authorization: Bearer $EMITAY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "series": "F001", "currency": "USD", "customer": { "document_number": "20100066603", "name": "CLIENTE S.A.", "email": "compras@cliente.pe" }, "purchase_order": "OC-2291", "observations": "Entrega en almacén central", "items": [ { "description": "Licencia anual", "quantity": 3, "unit_price": "120.00", "unit_code": "ZZ" } ] }'$cabeceras = @{ Authorization = "Bearer $env:EMITAY_API_KEY"}$cuerpo = @'{ "series": "F001", "currency": "USD", "customer": { "document_number": "20100066603", "name": "CLIENTE S.A.", "email": "compras@cliente.pe" }, "purchase_order": "OC-2291", "observations": "Entrega en almacén central", "items": [ { "description": "Licencia anual", "quantity": 3, "unit_price": "120.00", "unit_code": "ZZ" } ]}'@Invoke-RestMethod -Method Post ` -Uri https://api.emitay.com/v1/invoices ` -Headers $cabeceras ` -ContentType "application/json; charset=utf-8" ` -Body $cuerpoimport { Emitay } from "emitay";
const emitay = new Emitay(); // toma la llave de EMITAY_API_KEY
const factura = await emitay.invoices.create({ series: "F001", currency: "USD", customer: { document_number: "20100066603", name: "CLIENTE S.A.", email: "compras@cliente.pe", }, purchase_order: "OC-2291", observations: "Entrega en almacén central", items: [ { description: "Licencia anual", quantity: 3, unit_price: "120.00", unit_code: "ZZ", }, ],});customer.emailes a donde va el correo automático cuando SUNAT acepta, si la empresa lo tiene activado.metadataguarda pares clave-valor tuyos (el id del pedido, por ejemplo) que vuelven en cada respuesta, evento y webhook. Emitay no los lee.due_date,purchase_order,despatch_references(las guías con que viajó la venta) yobservationsse imprimen en el PDF y van en el XML.
Todos los campos, con sus límites, están en la referencia. Descuentos, operaciones gratuitas, exportación, detracción, anticipos, ventas al crédito y bolsas plásticas están en Casos tributarios.
Lo que la API comprueba antes de numerar
Sección titulada «Lo que la API comprueba antes de numerar»Lo que SUNAT rechazaría después de numerar, Emitay lo niega en la petición, con el campo y el
motivo. Un 422 no consume número: corrige y vuelve a enviar.
- La serie empieza con
Fy tiene cuatro caracteres (F001). - El cliente tiene RUC (
document_type: "6"), salvo en una exportación. SUNAT rechaza una factura a un DNI. - El RUC tiene su dígito verificador correcto, y un DNI, 8 dígitos.
- La unidad de medida está en el catálogo 03 de SUNAT y la moneda en ISO 4217.
- Los importes llevan hasta 2 decimales; cantidades y precios unitarios, hasta 10. Un tercer decimal en un importe se rechaza, no se redondea.
- La fecha de emisión no es anterior a 3 días ni posterior a hoy en más de 2: es la ventana en que SUNAT recibe una factura.
La respuesta
Sección titulada «La respuesta»El comprobante vuelve con su número, su estado y los enlaces a sus archivos:
{ "id": "doc_…", "object": "document", "type": "01", "series": "F001", "number": 1, "status": "accepted", "currency": "PEN", "total": "118.00", "amounts": { "taxed": "100.00", "exempt": "0.00", "unaffected": "0.00", "igv": "18.00" }, "sunat": { "code": "0", "description": "La Factura numero F001-1, ha sido aceptada", "notes": [], "simulated": false }, "links": { "pdf": "https://files.emitay.com/files/…/F001-1.pdf", "xml": "https://files.emitay.com/files/…/F001-1.xml", "cdr": "https://files.emitay.com/files/…/R-F001-1.zip" }}Guarda el id: con él consultas, anulas, descargas el
PDF y envías por correo el comprobante. Si lo pierdes, se encuentra por
serie y número: GET /v1/documents?series=F001&number=1.