Anulación de la operación
Anula o corrige un comprobante ya emitido sin borrarlo: emite otro documento que lo revierte. Es la vía cuando ya pasó el plazo de la baja: 3 días en una factura, 5 en una boleta.
POST
https://cpe-dev.facturamovilai.me/v1/emisores/TU_RUC/comprobantesCabecera Authorization: Bearer TU_LLAVE. Es la misma llave en pruebas y en producción: lo que cambia es la dirección (cpe-dev o cpe-prod).
Solicitud
curl -X POST "https://cpe-dev.facturamovilai.me/v1/emisores/TU_RUC/comprobantes" \
-H "Authorization: Bearer TU_LLAVE" \
-H "Content-Type: application/json" \
-d '{
"tipo": "NOTA_CREDITO",
"serie": "B001",
"referencia_externa": "anulacion-3101",
"precios_incluyen_igv": true,
"nota_credito": {
"motivo": "ANULACION_DE_LA_OPERACION",
"sustento": "El cliente devolvio el producto",
"documento_afectado": {
"tipo": "BOLETA",
"serie": "B001",
"numero": 36
}
},
"cliente": {
"tipo_documento": "SIN_DOCUMENTO"
},
"items": [
{
"descripcion": "Fideos",
"cantidad": "3",
"valor_unitario": "3.50"
}
]
}'const respuesta = await fetch("https://cpe-dev.facturamovilai.me/v1/emisores/TU_RUC/comprobantes", {
method: "POST",
headers: {
"Authorization": "Bearer TU_LLAVE",
"Content-Type": "application/json",
},
body: JSON.stringify({
"tipo": "NOTA_CREDITO",
"serie": "B001",
"referencia_externa": "anulacion-3101",
"precios_incluyen_igv": true,
"nota_credito": {
"motivo": "ANULACION_DE_LA_OPERACION",
"sustento": "El cliente devolvio el producto",
"documento_afectado": {
"tipo": "BOLETA",
"serie": "B001",
"numero": 36
}
},
"cliente": {
"tipo_documento": "SIN_DOCUMENTO"
},
"items": [
{
"descripcion": "Fideos",
"cantidad": "3",
"valor_unitario": "3.50"
}
]
}),
});
console.log(respuesta.status, await respuesta.json());# pip install requests
import requests
respuesta = requests.post(
"https://cpe-dev.facturamovilai.me/v1/emisores/TU_RUC/comprobantes",
headers={"Authorization": "Bearer TU_LLAVE"},
json={
"tipo": "NOTA_CREDITO",
"serie": "B001",
"referencia_externa": "anulacion-3101",
"precios_incluyen_igv": True,
"nota_credito": {
"motivo": "ANULACION_DE_LA_OPERACION",
"sustento": "El cliente devolvio el producto",
"documento_afectado": {
"tipo": "BOLETA",
"serie": "B001",
"numero": 36,
},
},
"cliente": {
"tipo_documento": "SIN_DOCUMENTO",
},
"items": [
{
"descripcion": "Fideos",
"cantidad": "3",
"valor_unitario": "3.50",
},
],
},
)
print(respuesta.status_code, respuesta.json())Campos
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
tipo | opción | Sí | BOLETA, FACTURA o NOTA_CREDITO. Es lo único que cambia entre los tres casosValores: FACTURA · BOLETA · NOTA_CREDITO |
serie | texto | Sí | Cuatro caracteres: una boleta empieza con B (B001) y una factura con F (F001). En una nota de crédito es la serie del documento que anula, no una propia |
nota_credito.motivo | opción | Sí | Por qué se emite (catálogo 09 de SUNAT) Valores: ANULACION_DE_LA_OPERACION · ANULACION_POR_ERROR_EN_EL_RUC · CORRECCION_POR_ERROR_EN_LA_DESCRIPCION · DESCUENTO_GLOBAL · DESCUENTO_POR_ITEM · DEVOLUCION_TOTAL · DEVOLUCION_POR_ITEM |
nota_credito.sustento | texto | Sí | Explicación libre del motivo, por ejemplo «El cliente devolvió el producto» |
nota_credito.documento_afectado.tipo | opción | Sí | Tipo del comprobante que se anula o corrige: BOLETA o FACTURAValores: FACTURA · BOLETA · NOTA_CREDITO |
nota_credito.documento_afectado.serie | texto | Sí | Serie del comprobante original, por ejemplo B001 |
nota_credito.documento_afectado.numero | entero | Sí | Número del comprobante original, sin ceros a la izquierda: 6, no 000006 |
cliente.tipo_documento | opción | Sí | Cómo se identifica el comprador: DNI, RUC o SIN_DOCUMENTO. SIN_DOCUMENTO solo vale en una boleta de hasta S/ 700; una factura exige RUCValores: RUC · DNI · SIN_DOCUMENTO |
items[].descripcion | texto | Sí | Nombre del producto o servicio, tal como debe verse en el comprobante |
items[].cantidad | decimal | Sí | Cuántas unidades se venden, en la unidad indicada. Admite decimales (2.5 kg). Debe ser mayor que cero |
items[].valor_unitario | decimal | Sí | Precio de una unidad. Con precios_incluyen_igv: true es el precio de vitrina, con IGV; con false, el valor neto. No puede ser negativo |
items[].unidad | opción | No | En qué se vende esto (catálogo 03 de SUNAT). UNIDAD por defecto, que es vender de a una. Usa KILOGRAMO, LITRO, BOLSA, CAJA, DOCENA y demás cuando corresponda: va declarado en el comprobante, así que vender 2 kg de lentejas como 2 UNIDAD declara algo distinto de lo que vendiste. SERVICIO para lo que no es un bienLista completa: GET /v1/unidadesPor defecto: UNIDAD |
items[].afectacion | opción | No | Qué dice la ley del IGV de este producto. GRAVADO (18%) por defecto. EXONERADO para lo que no paga IGV -menestras, arroz, verduras, libros- e INAFECTO para exportaciones. Una bodega puede vender los dos en la misma boleta. Si lo marcas mal, el total igual cuadra pero declaras IGV que no debesValores: GRAVADO · EXONERADO · INAFECTOPor defecto: GRAVADO |
referencia_externa | texto | No | El id de esta venta en TU sistema. Mándalo siempre: es lo único que evita emitir dos comprobantes si reintentas. Repetirlo con los mismos datos devuelve el comprobante ya emitido; repetirlo con datos distintos responde 409 |
precios_incluyen_igv | booleano | No | true si mandas precios de vitrina -lo que cobra la caja- y nosotros quitamos el IGV con 6 decimales. false si mandas valores netos. Un item EXONERADO no se convierte: no hay IGV que quitarlePor defecto: false |
Respuestas
{
"id": "NOTA_CREDITO-B001-3",
"emisor": "TU_RUC",
"ambiente": "dev",
"tipo": "NOTA_CREDITO",
"serie": "B001",
"numero": 3,
"estado": "ACEPTADO",
"mensaje": "El documento fue enviado correctamente y aceptado por SUNAT.",
"total": "10.50",
"referencia_externa": "anulacion-3101",
"pdf_factuapi_a4_url": "https://cpe-dev.facturamovilai.me/v1/pdf/<token>",
"desglose": {
"gravado": "8.90",
"exonerado": "0.00",
"inafecto": "0.00",
"igv": "1.60",
"total": "10.50",
"items": [
{
"descripcion": "Fideos",
"valor_unitario": "2.966102",
"igv": "1.60",
"total": "10.50"
}
]
}
}El mismo pedido sin el campo nota_credito
{
"error": "DatosInvalidos",
"mensaje": "Una nota de credito debe indicar motivo y documento afectado"
}Con una llave que no existe
{
"detail": "Credencial invalida"
}Con un RUC que no es de tu cuenta
{
"error": "EmisorNoAutorizado",
"mensaje": "El emisor 20999999999 no pertenece a esta cuenta"
}estado |
Significa |
|---|---|
ACEPTADO |
el comprobante existe ante SUNAT |
RECHAZADO |
SUNAT lo procesó y lo rechazó. Llega con 201, no con un error: lee mensaje |
PENDIENTE |
SUNAT sigue procesando. Consúltalo más tarde |
La respuesta puede traer campos adicionales a los que ves aquí: usa los de estos ejemplos.
La serie es la del documento que anula (B001 para una boleta), no una propia. Aun así, cada tipo lleva su propio correlativo, como exige SUNAT: el número de la nota de crédito no tiene relación con el de la boleta que anula.