Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/farojas85/fast-rest-api/llms.txt

Use this file to discover all available pages before exploring further.

This is the primary billing endpoint for dine-in restaurant orders. It accepts a structured POS order payload, validates that the declared invoice totals are arithmetically consistent, maps the incoming DTO to domain entities, logs the attempt to the audit repository, and submits the electronic invoice to the DIAN SOAP service via the IDianSoapPort adapter. On success, the DIAN response is normalised and returned as a PedidoLocalResponse containing the track_id (ZipKey) and optional cufe for downstream traceability.

Endpoint Details

PropertyValue
MethodPOST
Path/api/v1/pedidos/consumo-local/
Router prefix/api/v1/pedidos/consumo-local (declared in pedido_local_controller.py)
TagsFacturación Local
Success status201 Created

Request Body

The endpoint accepts a JSON body that conforms to PedidoLocalCreateRequest (defined in src/infrastructure/controllers/schemas/pedido_local_schema.py).

Top-level fields

id_pedido_origen
string
required
The order identifier assigned by the POS system. Used as the id_pedido key on the domain entity and as the primary correlation reference in audit logs.
adquirente
object
Customer identification details. If omitted, the invoice is issued to Consumidor Final using the DIAN-approved anonymous taxpayer values.
items
array
required
Ordered list of products or services included in the invoice. Must contain at least one item (min_length=1).
subtotal
Decimal
required
Sum of all item prices before taxes. Must satisfy subtotal + impuestos_totales + propina_voluntaria == total_factura.
propina_voluntaria
Decimal
default:"0.00"
Voluntary tip amount. Reported on the DIAN invoice but excluded from the taxable base — it is not subject to INC or IVA.
impuestos_totales
Decimal
required
Total tax amount across all items. Must equal the sum of every impuestos[].monto value across all items.
total_factura
Decimal
required
Final invoice total. Must exactly equal subtotal + impuestos_totales + propina_voluntaria. The use case enforces this invariant and raises a ValueError on mismatch.
metodos_pago
array
required
Payment methods used to settle the invoice. Multiple entries are supported (e.g., partial cash + card).

Business Validation

The FacturarPedidoLocalUseCase.execute() method enforces the following rule before any SOAP call is made:
expected_total = payload.subtotal + payload.impuestos_totales + payload.propina_voluntaria
if payload.total_factura != expected_total:
    raise ValueError("El total de la factura no coincide con la suma del subtotal, impuestos y propina.")
If total_factura does not match subtotal + impuestos_totales + propina_voluntaria, a ValueError is raised immediately and no DIAN submission is attempted. The audit log is not updated for failed validations of this type — ensure your POS system pre-validates totals before sending the request.
The voluntary tip (propina_voluntaria) is forwarded to the DIAN as an informational amount but is never added to the taxable base for INC or IVA purposes.

Response

On 201 Created, the endpoint returns a PedidoLocalResponse object.
track_id
string
DIAN’s ZipKey identifier returned by SendTestSetAsync. Use this value to query DIAN’s status portal for the submitted document. Defaults to "UNKNOWN" if the SOAP response does not include a ZipKey.
cufe
string
Código Único de Factura Electrónica — the unique fingerprint of the issued invoice. Optional; populated only when the DIAN response includes it. In the current habilitación mock it returns "VALID_CUFE_MOCK".
status
string
Processing status string from the DIAN response (e.g., "Procesado Correctamente", "SUCCESS").
message
string
Human-readable confirmation message (e.g., "Factura enviada correctamente a la DIAN").

Example Request

The following example is derived from the canonical test fixture in tests/application/use_cases/test_facturar_pedido_local.py:
curl -X POST http://localhost:8000/api/v1/pedidos/consumo-local/ \
  -H "Content-Type: application/json" \
  -d '{
    "id_pedido_origen": "POS-100",
    "items": [
      {
        "id_producto": "B-01",
        "descripcion": "Cerveza Artesanal",
        "cantidad": 2,
        "precio_unitario": 10000.00,
        "impuestos": [
          {"nombre": "INC", "tasa": 0.08, "monto": 1600.00}
        ],
        "total_item": 21600.00
      }
    ],
    "subtotal": 20000.00,
    "propina_voluntaria": 3000.00,
    "impuestos_totales": 1600.00,
    "total_factura": 24600.00,
    "metodos_pago": [
      {"tipo": "Efectivo", "monto": 24600.00}
    ]
  }'
Total breakdown: 20000.00 (subtotal) + 1600.00 (INC) + 3000.00 (tip) = 24600.00 ✓

Example Response (201 Created)

{
  "track_id": "DIAN-ZIPKEY-ABC123",
  "cufe": "VALID_CUFE_MOCK",
  "status": "Procesado Correctamente",
  "message": "Factura enviada correctamente a la DIAN"
}

Error Responses

HTTP StatusCauseBody
422 Unprocessable EntityPydantic validation failed — missing required field, wrong type, or cantidad ≤ 0Standard FastAPI validation error body
500 Internal Server ErrorDIAN submission failed — SOAP timeout, WSDL error, or authentication failure{"message": "Error enviando a la DIAN", "details": {...}}
Example 500 body:
{
  "message": "Error enviando a la DIAN",
  "details": {
    "success": false,
    "error": "TimeoutException",
    "message": "La DIAN tardó demasiado en responder."
  }
}

Tax Notes

INC vs. IVA in Colombian restaurant invoicing:
  • INC (Impuesto Nacional al Consumo) — typically 8 % for food and beverages served and consumed on the restaurant premises. This is the most common tax type for dine-in orders.
  • IVA (Impuesto al Valor Agregado) — typically 19 % for non-food items, alcohol in certain categories, or ancillary services. Some establishments apply a combination of both taxes depending on their tax registration.
  • Voluntary tip (propina_voluntaria) — appears as a distinct line on the DIAN invoice but is not subject to INC or IVA. It is reported for transparency but does not increase the taxable base.
The ImpuestoRequest.nombre field on each item controls which tax type is applied per line, giving the POS full flexibility to mix INC and IVA items within the same invoice.

Build docs developers (and LLMs) love