# Cancelar CFDI 4.0

Este endpoint permite **cancelar un CFDI 4.0** que fue timbrado previamente a través del API
de QRwey!. Se debe especificar el motivo de cancelación conforme al catálogo del SAT.

## Endpoint

```
DELETE /v1/qrs/invoices/{invoiceId}
```

**Host (DEV):**

```
https://api-dev.qrwey.com
```

**Host (PROD):**

```
https://api.qrwey.com
```

## Headers requeridos

```http
Authorization: Bearer {{access_token}}
Content-Type: application/json
```

## Parámetros de ruta

| Parámetro | Descripción |
|  --- | --- |
| `invoiceId` | Identificador interno de la factura a cancelar (obtenido al timbrar el CFDI) |


## Request body

| Campo | Tipo | Requerido | Descripción |
|  --- | --- | --- | --- |
| `cfdiCancellationReason` | String | Si | Código del motivo de cancelación del SAT |
| `replacementUuid` | String | Condicional | UUID del CFDI sustituto. **Obligatorio** cuando `cfdiCancellationReason` es `01` |


### Motivos de cancelación (`cfdiCancellationReason`)

| Código | Descripción | `replacementUuid` |
|  --- | --- | --- |
| `01` | Comprobante emitido con errores con relación | **Requerido** |
| `02` | Comprobante emitido con errores sin relación | No aplica |
| `03` | No se llevó a cabo la operación | No aplica |
| `04` | Operación nominativa relacionada en una factura global | No aplica |


## Precondiciones

- La factura debe existir y pertenecer al comercio del usuario autenticado.
- El estatus actual de la factura debe ser `GENERATED`. Cualquier otro estatus
(`CANCELLED`, `CANCEL_REQUESTED`, etc.) provocará un error `412`.


## Ejemplo de request — motivo 02 (DEV)

```bash
curl -X DELETE "https://api-dev.qrwey.com/v1/qrs/invoices/8f3a1c2d-9b4e-4a7f-91d6-2b8e7c5a1f3d" \
  -H "Authorization: Bearer {{access_token}}" \
  -H "Content-Type: application/json" \
  -d '{
    "cfdiCancellationReason": "02"
  }'
```

## Ejemplo de request — motivo 01 con UUID sustituto (DEV)

```bash
curl -X DELETE "https://api-dev.qrwey.com/v1/qrs/invoices/8f3a1c2d-9b4e-4a7f-91d6-2b8e7c5a1f3d" \
  -H "Authorization: Bearer {{access_token}}" \
  -H "Content-Type: application/json" \
  -d '{
    "cfdiCancellationReason": "01",
    "replacementUuid": "A1B2C3D4-E5F6-7890-ABCD-EF1234567890"
  }'
```

## Respuesta

```json
{
  "invoiceId": "8f3a1c2d-9b4e-4a7f-91d6-2b8e7c5a1f3d",
  "invoiceStatus": "CANCELLED",
  "folioUuid": "F1G2H3I4-J5K6-7890-LMNO-PQ1234567890",
  "sourceTaxId": "FUNK671228PH6",
  "sourceLegalName": "KARLA FUENTE NOLASCO",
  "targetTaxId": "EKU9003173C9",
  "targetLegalName": "ESCUELA KEMPER URGATE",
  "subtotal": 500.00,
  "iva": 80.00,
  "total": 580.00,
  "invoiceDate": "2026-03-19T15:00:00Z"
}
```

### Estatus posibles tras la cancelación

| `invoiceStatus` | Significado |
|  --- | --- |
| `CANCELLED` | El SAT acepto la cancelación de inmediato |
| `CANCEL_REQUESTED` | La cancelación fue solicitada y queda pendiente de aceptación del receptor |


## Errores comunes

| Código | Motivo |
|  --- | --- |
| 400 | Motivo de cancelación inválido, falta `replacementUuid` cuando motivo es `01`, o el SAT rechazo la cancelación |
| 401 | Token inválido o expirado |
| 404 | Factura no encontrada o usuario no pertenece al comercio |
| 412 | El estatus de la factura no permite cancelación (no está en `GENERATED`) |


Consulta: [Manejo de errores](/guides/error-handling)

## Buenas prácticas

- Verifica el estatus de la factura antes de intentar cancelarla.
- Cuando uses motivo `01`, asegurate de haber timbrado el CFDI sustituto antes de cancelar el original.
- Conserva el `folioUuid` y la respuesta completa para tu registro contable.
- Si la respuesta es `CANCEL_REQUESTED`, debes dar seguimiento al flujo de aceptación
del receptor en el portal del SAT.
- La cancelación es una operación irreversible: una vez aceptada por el SAT, el CFDI
no podrá reactivarse.


## ¿Qué sigue?

- Vuelve a facturas de ingreso: [Timbrar CFDI 4.0](/guides/stamp-cfdi)
- Genera notas de crédito: [Notas de crédito](/guides/credit-notes)
- Vuelve al índice: [Guias](/guides)