Comprobantes

Un pedido por la API

Factura al cobrar, guía al despachar y nota de crédito al reembolsar, con los webhooks que escuchar y una clave de idempotencia por cada evento del pedido.

Estos son los pasos para que tu tienda emita los tres comprobantes de un pedido. Por qué va cada uno, y qué hacer con envíos parciales, cambios o facturas a consumidor final, está en Comercio electrónico.

El ejemplo es el pedido #1041: unas zapatillas y su envío, pagados con tarjeta por Luis Pérez.

Escucha los resultados del SRI

Registra un endpoint para los tres comprobantes. Así sabrás cuándo la factura está autorizada, que es lo que la guía y la nota de crédito necesitan.

curl -X POST https://api.fiscalbase.io/v1/webhook-endpoints \
  -H "Authorization: Bearer $FISCALBASE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://tutienda.ec/webhooks/fiscalbase",
    "events": [
      "invoice.authorized", "invoice.returned", "invoice.not_authorized",
      "delivery_note.authorized", "delivery_note.returned", "delivery_note.not_authorized",
      "credit_note.authorized", "credit_note.returned", "credit_note.not_authorized"
    ]
  }'

Guarda el secret de la respuesta y verifica cada entrega.

Cuando se paga, emite la factura

Usa una clave de idempotencia por cada evento del pedido. Si la red se corta y reintentas, recibes la misma factura, nunca dos (idempotencia).

curl -X POST https://api.fiscalbase.io/v1/ec/invoices \
  -H "Authorization: Bearer $FISCALBASE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-1041:factura" \
  -d @factura.json
factura.json
{
  "buyer": {
    "identification_type": "cedula",
    "identification": "1710034065",
    "name": "Luis Pérez",
    "address": "Av. República E7-123, Quito",
    "email": "luis.perez@correo.ec"
  },
  "lines": [
    {
      "code": "ZAP-42",
      "description": "Zapatillas urbanas, talla 42",
      "quantity": "1",
      "unit_price": "52.17",
      "taxes": [{ "type": "iva", "rate": "iva_15" }]
    },
    {
      "code": "ENVIO",
      "description": "Envío a domicilio",
      "quantity": "1",
      "unit_price": "4.35",
      "taxes": [{ "type": "iva", "rate": "iva_15" }]
    }
  ],
  "payments": [{ "method": "tarjeta_credito" }],
  "additional_info": [{ "name": "Pedido", "value": "#1041" }],
  "metadata": { "order_id": "1041" }
}

Respondemos 201 con la factura en pending. Guarda su id junto al pedido: la guía y la nota de crédito la usarán.

Espera invoice.authorized

{
  "id": "3c1a7e52-…",
  "type": "invoice.authorized",
  "timestamp": "2026-10-01T14:03:52.118Z",
  "data": {
    "id": "0f6c8f4e-6c6e-4a31-9c1e-3b1f2a9d7c10",
    "object": "invoice",
    "status": "authorized",
    "environment": "live",
    "country": "ec",
    "entity_id": "01926c10-…"
  }
}

Busca el pedido por data.id y márcalo como facturado. Si llega invoice.returned o invoice.not_authorized, lee los sri_messages de la factura y corrígela con el mismo número.

Cuando despachas, emite la guía

Antes de que el paquete salga, una guía por envío, con la factura como sustento. Si el pedido sale en dos cajas, emite dos guías, cada una con su clave (pedido-1041:guia:1, pedido-1041:guia:2) y con lo que va en esa caja.

curl -X POST https://api.fiscalbase.io/v1/ec/delivery-notes \
  -H "Authorization: Bearer $FISCALBASE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-1041:guia:1" \
  -d @guia.json
guia.json
{
  "origin_address": "Bodega Norte, Av. Eloy Alfaro N50-120, Quito",
  "carrier": {
    "identification_type": "ruc",
    "identification": "1792233445001",
    "name": "TRANSPORTES ANDES CÍA. LTDA."
  },
  "plate": "PBC-1234",
  "transport_start": "2026-10-01",
  "transport_end": "2026-10-02",
  "recipients": [
    {
      "identification": "1710034065",
      "name": "Luis Pérez",
      "address": "Av. República E7-123, Quito",
      "email": "luis.perez@correo.ec",
      "reason": "Venta",
      "support_document": {
        "document_id": "0f6c8f4e-6c6e-4a31-9c1e-3b1f2a9d7c10"
      },
      "items": [
        {
          "code": "ZAP-42",
          "description": "Zapatillas urbanas, talla 42",
          "quantity": "1"
        }
      ]
    }
  ],
  "metadata": { "order_id": "1041", "shipment": "1" }
}
  • carrier y plate son del courier que retira el paquete, o de tu empresa y tu vehículo si repartes tú.
  • transport_start no puede ser anterior a hoy, ni transport_end anterior al inicio.
  • Si la factura aún no está autorizada, respondemos 422 en recipients[0].support_document.document_id.

delivery_note.authorized te dice que la guía es válida, y en Producción le llega por correo a Luis.

Si reembolsas, emite la nota de crédito

Una nota por cada reembolso, con su propia clave (pedido-1041:reembolso:1) y solo lo que devuelves. Aquí Luis devuelve las zapatillas; el envío no se reembolsa.

curl -X POST https://api.fiscalbase.io/v1/ec/credit-notes \
  -H "Authorization: Bearer $FISCALBASE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-1041:reembolso:1" \
  -d @nota-de-credito.json
nota-de-credito.json
{
  "buyer": {
    "identification_type": "cedula",
    "identification": "1710034065",
    "name": "Luis Pérez",
    "email": "luis.perez@correo.ec"
  },
  "modified_document": {
    "document_id": "0f6c8f4e-6c6e-4a31-9c1e-3b1f2a9d7c10"
  },
  "reason": "Devolución del pedido #1041",
  "lines": [
    {
      "code": "ZAP-42",
      "description": "Zapatillas urbanas, talla 42",
      "quantity": "1",
      "unit_price": "52.17",
      "taxes": [{ "type": "iva", "rate": "iva_15" }]
    }
  ],
  "metadata": { "order_id": "1041", "refund": "1" }
}

Usa el comprador, el precio y la tarifa de IVA que tenía la factura. Si la factura fue a consumidor final, respondemos 422 en modified_document: el SRI no admite notas de crédito para ella.

Si cancelas después de facturar

Si el pedido se cancela entero y la factura es de este mes, o del anterior y aún no pasa el día 7, anúlala en SRI en línea y registra la anulación:

curl -X POST https://api.fiscalbase.io/v1/ec/invoices/0f6c8f4e-6c6e-4a31-9c1e-3b1f2a9d7c10/annul \
  -H "Authorization: Bearer $FISCALBASE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "annulled_on": "2026-10-03", "reason": "Pedido cancelado antes del despacho" }'

Tus webhooks reciben invoice.annulled. Una factura a consumidor final no se anula (respondemos 409) ni admite nota de crédito. Fuera del plazo, emite una nota de crédito por el total, como en el paso anterior (correcciones).

Las claves de idempotencia del pedido

Evento del pedidoEndpointIdempotency-Key
PagadoPOST /v1/ec/invoicespedido-1041:factura
Cada envíoPOST /v1/ec/delivery-notespedido-1041:guia:{n.º de envío}
Cada reembolsoPOST /v1/ec/credit-notespedido-1041:reembolso:{id del reembolso}

Cualquier forma sirve si es estable entre reintentos y única por evento: el id del envío o del reembolso de tu plataforma es perfecto. La misma clave con otro cuerpo responde 409 conflict, que casi siempre es un evento distinto usando una clave repetida.

En esta página