> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cucu.bo/llms.txt
> Use this file to discover all available pages before exploring further.

# Crear Nota Credito/Debito

> Emite una nota de credito o debito contra una factura original validada.

Crea y emite una Nota de Credito o Debito contra una factura original validada por el SIAT. La nota permite ajustar montos por devoluciones parciales o totales.

<Note>
  La factura original debe estar en estado `VALIDATED`. No se puede emitir una nota contra facturas rechazadas, anuladas o pendientes.
</Note>

## Path Parameters

| Parametro | Tipo | Req | Descripcion                                                |
| --------- | ---- | --- | ---------------------------------------------------------- |
| `id`      | UUID | Si  | UUID de la factura original contra la que se emite la nota |

## Headers

| Parametro      | Tipo   | Req | Descripcion        |
| -------------- | ------ | --- | ------------------ |
| `X-API-Key`    | string | Si  | Tu API Key         |
| `Content-Type` | string | Si  | `application/json` |

## Request Body

| Campo                | Tipo    | Req | Descripcion                                                                                                                                                          |
| -------------------- | ------- | --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pointOfSaleId`      | UUID    | Si  | UUID del punto de venta registrado en SIAT                                                                                                                           |
| `notaType`           | string  | Si  | Tipo de nota: `CREDITO` o `DEBITO`                                                                                                                                   |
| `documentSectorType` | integer | No  | Sector de la nota: `24` (estandar, default), `47` (Nota Descuento) o `48` (Nota ICE). Ver [Notas Descuento e ICE](#notas-descuento-e-ice-sectores-47-y-48)           |
| `paymentMethodCode`  | integer | Si  | Codigo de metodo de pago (1-308). `1` = Efectivo                                                                                                                     |
| `cardNumber`         | string  | No  | Numero de tarjeta. Se **ofusca automaticamente** antes de guardar y emitir (ver nota de seguridad)                                                                   |
| `observations`       | string  | No  | Observaciones (max 500 caracteres)                                                                                                                                   |
| `isTicket`           | boolean | No  | `true` para generar ticket 80mm ademas de A4                                                                                                                         |
| `returnedDetails`    | array   | Si  | Items devueltos/ajustados (minimo 1)                                                                                                                                 |
| `originalDetails`    | array   | No  | **Solo sector 48 (ICE):** overlay de datos ICE por linea original. En sectores 24/47 se ignora. Ver [Notas Descuento e ICE](#notas-descuento-e-ice-sectores-47-y-48) |

### returnedDetails\[]

| Campo              | Tipo    | Req | Descripcion                                            |
| ------------------ | ------- | --- | ------------------------------------------------------ |
| `activityEconomic` | string  | Si  | Codigo de actividad economica CAEB                     |
| `codeProductSin`   | string  | Si  | Codigo de producto/servicio del catalogo SIN           |
| `codeProduct`      | string  | No  | Codigo interno del producto                            |
| `description`      | string  | Si  | Descripcion del producto o servicio devuelto (max 500) |
| `quantity`         | number  | Si  | Cantidad devuelta (mayor a 0)                          |
| `unitMeasure`      | integer | Si  | Unidad de medida SIN. `58` = Servicio, `1` = Unidad    |
| `priceUnit`        | number  | Si  | Precio unitario en bolivianos (mayor a 0)              |
| `amountDiscount`   | number  | No  | Descuento aplicado al item (default 0)                 |
| `serialNumber`     | string  | No  | Numero de serie (si aplica)                            |
| `imeiNumber`       | string  | No  | Numero IMEI (si aplica)                                |

<RequestExample>
  ```bash cURL theme={"system"}
  curl -X POST "https://sandbox.cucu.bo/api/v1/invoices/a1b2c3d4-e5f6-7890-abcd-ef1234567890/credit-note" \
    -H "Content-Type: application/json" \
    -H "X-API-Key: YOUR_API_KEY" \
    -d '{
      "pointOfSaleId": "660e8400-e29b-41d4-a716-446655440004",
      "notaType": "CREDITO",
      "paymentMethodCode": 1,
      "returnedDetails": [
        {
          "activityEconomic": "620100",
          "codeProductSin": "83141",
          "description": "Devolucion parcial - Servicio de software",
          "quantity": 1,
          "unitMeasure": 58,
          "priceUnit": 200.00
        }
      ]
    }'
  ```

  ```javascript JavaScript theme={"system"}
  const response = await fetch(
    'https://sandbox.cucu.bo/api/v1/invoices/a1b2c3d4-e5f6-7890-abcd-ef1234567890/credit-note',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': 'YOUR_API_KEY'
      },
      body: JSON.stringify({
        pointOfSaleId: '660e8400-e29b-41d4-a716-446655440004',
        notaType: 'CREDITO',
        paymentMethodCode: 1,
        returnedDetails: [{
          activityEconomic: '620100',
          codeProductSin: '83141',
          description: 'Devolucion parcial - Servicio de software',
          quantity: 1,
          unitMeasure: 58,
          priceUnit: 200.00
        }]
      })
    }
  );
  const data = await response.json();
  ```

  ```python Python theme={"system"}
  import requests

  response = requests.post(
      'https://sandbox.cucu.bo/api/v1/invoices/a1b2c3d4-e5f6-7890-abcd-ef1234567890/credit-note',
      headers={
          'Content-Type': 'application/json',
          'X-API-Key': 'YOUR_API_KEY'
      },
      json={
          'pointOfSaleId': '660e8400-e29b-41d4-a716-446655440004',
          'notaType': 'CREDITO',
          'paymentMethodCode': 1,
          'returnedDetails': [{
              'activityEconomic': '620100',
              'codeProductSin': '83141',
              'description': 'Devolucion parcial - Servicio de software',
              'quantity': 1,
              'unitMeasure': 58,
              'priceUnit': 200.00
          }]
      }
  )
  print(response.json())
  ```
</RequestExample>

<ResponseExample>
  ```json 201 theme={"system"}
  {
    "success": true,
    "message": "Nota creada exitosamente",
    "data": {
      "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "invoiceNumber": 10,
      "cuf": "3983G8305613443F748GCBGCD4765FB93313BE59F1A7AF25FCFC9BG85",
      "state": "VALIDATED",
      "clientBusinessName": "EMPRESA DEMO S.R.L.",
      "amountTotal": 200.00,
      "emissionDate": "2026-02-22T10:30:00",
      "pdfUrl": "https://sandbox.cucu.bo/api/v1/public/invoice/3983G...G85/pdf",
      "xmlUrl": "https://sandbox.cucu.bo/api/v1/public/invoice/3983G...G85/xml"
    },
    "timestamp": "2026-02-22T10:30:00"
  }
  ```

  ```json 400 theme={"system"}
  {
    "success": false,
    "error": {
      "code": "BAD_REQUEST",
      "details": "La factura original no tiene detalles suficientes para la devolucion solicitada"
    },
    "timestamp": "2026-02-22T10:30:00"
  }
  ```

  ```json 409 theme={"system"}
  {
    "success": false,
    "error": {
      "code": "CONFLICT",
      "details": "La factura original no esta en estado VALIDATED"
    },
    "timestamp": "2026-02-22T10:30:00"
  }
  ```
</ResponseExample>

## Notas Descuento e ICE (sectores 47 y 48)

Ademas de la nota estandar (`24`), el campo `documentSectorType` permite emitir dos variantes especializadas:

| Sector | Tipo                              | Cuando usarlo                                                                |
| ------ | --------------------------------- | ---------------------------------------------------------------------------- |
| `24`   | Nota Credito-Debito estandar      | Default. Devoluciones/ajustes normales                                       |
| `47`   | Nota Credito-Debito **Descuento** | La factura original tenia descuento adicional prorrateado por item           |
| `48`   | Nota Credito-Debito **ICE**       | La factura original tenia productos con Impuesto al Consumo Especifico (ICE) |

<Warning>
  **No re-envies las lineas de la factura original.** En los tres sectores, las lineas originales
  (`codigoDetalleTransaccion=1`) se **clonan automaticamente desde la base de datos** — espejan
  exacto la factura registrada en SIAT. Enviar tus propias lineas originales causaba rechazos
  SIAT `[1049]` (detalle diferente) y `[1030]` (monto original erroneo). Ahora solo mandas los
  items devueltos en `returnedDetails`.
</Warning>

### Sector 47 — solo `returnedDetails`

Identico al `24` a nivel de request: mandas unicamente `returnedDetails`. El campo `originalDetails`, si viene, se ignora.

### Sector 48 — `returnedDetails` + overlay ICE

La compra-venta original **no almacena** los montos ICE, asi que en el sector `48` esos numeros
si vienen del request, en `originalDetails`, como un **overlay minimal** matcheado por `nroItem`.
La base (actividad/producto/descripcion/cantidad/precio) se toma de la BD; en `originalDetails`
solo importan los campos ICE:

| Campo                | Tipo    | Descripcion                                                                                                                 |
| -------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
| `nroItem`            | integer | `lineNumber` de la linea original a la que aplica el overlay (lo obtienes de `GET /invoices/{id}` → `details[].lineNumber`) |
| `marcaIce`           | integer | `1` = considera ICE, `2` = no considera ICE. **Obligatorio**                                                                |
| `montoIceEspecifico` | number  | Monto ICE especifico de la linea (opcional)                                                                                 |
| `montoIcePorcentual` | number  | Monto ICE porcentual de la linea (opcional)                                                                                 |

<Info>
  En sectores `47`/`48`, cada `returnedDetails[].nroItem` tambien referencia el `lineNumber`
  de la linea original que se devuelve (para el prorrateo del descuento). Consulta los numeros
  de linea de la factura original con `GET /api/v1/invoices/{id}` → `details[].lineNumber`.
</Info>

```json Ejemplo originalDetails (sector 48) theme={"system"}
"originalDetails": [
  { "nroItem": 1, "marcaIce": 2, "montoIceEspecifico": 0, "montoIcePorcentual": 0 }
]
```

<Info>
  **Modo estructural:** si la factura original no tenia ICE, envia `marcaIce: 2` con montos en `0`.
  La nota se emite con la estructura ICE requerida por el XSD del sector 48 pero sin monto ICE real.
</Info>

## Comportamiento

1. El sistema obtiene automaticamente los datos de la factura original (cliente, CUF, montos)
2. Los `returnedDetails` se marcan con `codigoDetalleTransaccion=2` (devolucion)
3. Los items originales se **clonan desde la base de datos** con `codigoDetalleTransaccion=1` (nunca del request)
4. Se calcula: `montoTotalOriginal`, `montoTotalDevuelto`, `montoDescuentoCreditoDebito`, `montoEfectivoCreditoDebito`
5. La nota se envia al SIAT via el WSDL de documento de ajuste (sector 24/47/48 segun `documentSectorType`)
6. Se genera PDF (A4 + ticket opcional), XML y se envia email al cliente

<Warning>
  Si la factura original tiene items con `montoGiftCard > 0`, el `paymentMethodCode` debe incluir el codigo `27` (Gift Card). Error SIAT 1050 si se omite.
</Warning>

<Info>
  La nota genera su propio CUF unico. Puedes acceder a ella via `/f/{cuf}` o los endpoints publicos, igual que una factura regular.
</Info>

<Note>
  **Seguridad — ofuscacion de tarjeta.** Si envias `cardNumber`, la API conserva solo los **4 primeros
  y 4 ultimos digitos** y reemplaza el resto por ceros antes de persistir y emitir el XML SIAT
  (ej: `4111111111111111` → `4111000000001111`). El numero completo (PAN) nunca se guarda en la base
  de datos ni viaja al SIAT. Numeros de 8 digitos o menos se dejan tal cual.
</Note>
