Saltar al contenido

Pedidos ​

Usa order para sincronizar pedidos e informar el contexto fiscal que Factulit necesita para decidir si crear, cancelar o rectificar una factura.

En las conexiones API, las instrucciones fiscales solo se aplican despues de que el propietario active la facturacion mediante el asistente de consentimiento de Factulit. Antes se guardan pedidos, clientes y estados, pero no se emite ninguna factura, anulacion o rectificativa. La fecha elegida en el asistente limita las instrucciones de pedidos; no limita las facturas directas.

Payload minimo compatible v1.0 ​

json
{
  "id_external": "order-1001",
  "reference": "1001",
  "order_date": "2026-07-07 10:30:00",
  "total": 121,
  "total_tax": 21,
  "currency": "EUR",
  "status": "paid",
  "id_order_status": "paid",
  "source_platform": "custom",
  "fiscal_event": "invoice_candidate",
  "invoice_action": "create_invoice",
  "client": {
    "id_external": "customer-1001",
    "first_name": "Ada",
    "last_name": "Lovelace",
    "email": "ada@example.test",
    "country": "ES"
  },
  "breakdown": [
    {
      "id_external_product": "sku-001",
      "name": "Product",
      "quantity": 1,
      "base_amount": 100,
      "tax_rate": 21,
      "tax_amount": 21
    }
  ]
}

Fecha de cobro (v1.5, aditivo) ​

paid_at es el instante en que la tienda cobro realmente el pedido (captura del PSP, confirmacion del modulo de pago o momento en que un administrador registro el cobro), como fecha RFC 3339 con offset:

json
{
  "order_date": "2026-09-07 10:15:00",
  "paid_at": "2026-09-07T10:15:42+02:00",
  "currency": "USD"
}

Es opcional y aditivo dentro del contrato 1.5. Cuando solo llega una de las dos fechas, order_date o paid_at, Factulit toma la otra como el mismo instante, que es el caso habitual del checkout; envia las dos cuando difieran (transferencia cobrada dias despues, contra reembolso). Omite la clave cuando la tienda no conoce el dato.

Factulit la usa para elegir el tipo de cambio de un pedido cobrado en una moneda distinta del euro: el ultimo tipo de referencia del BCE publicado antes del instante del cobro. No altera ninguna otra decision fiscal.

Hechos de canal y tienda (v1.3+) ​

Dos hechos opcionales ayudan a Factulit a clasificar cada pedido en un perfil de facturacion cuando el titular de la cuenta los configura (serie y modo de emision propios por canal comercial o por tienda):

  • source_channel (string, max 32): el canal comercial en el que nacio el pedido, por ejemplo web o com. Recomendado en minusculas.
  • source_channel_evidence (string, clave=valor): de donde salio ese canal en el sistema de origen, por ejemplo created_via=admin.
  • shop.id: las instalaciones multitienda deben seguir enviando el id de tienda de cada pedido; se conserva con el pedido y tambien puede clasificarlo.

Estos campos nunca son ordenes fiscales. Si la conexion no tiene perfiles de facturacion, simplemente se almacenan. Si el titular ha configurado perfiles, un pedido que no encaje exactamente en un perfil queda retenido para clasificacion manual y no se emite factura por el: jamas se numera con la serie de otro canal.

El envio de pedidos esta disponible para conexiones de comercio y para conexiones API (x-api-key de una conexion API). Cada conexion mantiene su propio espacio de id_external, de modo que los identificadores de sistemas distintos nunca chocan. Los tipos de conexion que no aceptan pedidos reciben 403 con error_code: orders_not_supported_by_connection.

Puerta de configuracion de la conexion (v1.4+) ​

Las conexiones nuevas arrancan con una puesta en marcha guiada en 3 pasos. Hasta que el titular completa el paso 2 en Factulit, los recursos order y client responden 423:

json
{
  "success": false,
  "error": "Connection is not configured yet: complete the setup in Factulit before syncing orders",
  "error_code": "sync_not_ready",
  "retryable": true
}

Tratalo como una condicion temporal a nivel de cuenta: pausa y reintenta mas tarde sin quemar reintentos por pedido. Los recursos status e inventory permanecen abiertos durante la configuracion: son el insumo del paso 2. Las conexiones API quedan exentas (sus pedidos son instrucciones deliberadas bajo su propio consentimiento). Las conexiones anteriores a este flujo no se gatean.

Recurso inventory (paso 1) ​

Justo despues de conectar, reporta el inventario de la instalacion para que el paso 2 muestre tiendas y volumen antes de sincronizar ningun pedido:

http
POST /v1/inventory
{
  "stores": [
    {"id": "0", "name": "Tienda principal", "url": "https://tienda.example", "orders_count": 120}
  ],
  "orders_total": 120
}

stores[] admite hasta 100 entradas (id obligatorio, max 32 caracteres; name, url y orders_count opcionales). La llamada es idempotente (upsert por id de tienda). Las plataformas de tienda unica pueden reportar una sola entrada.

Campos de configuracion en module-version (aditivos) ​

La respuesta de module-version incluye ahora:

  • setup_state: pending_inventory, pending_configuration o configured.
  • sync_ready (bool): si los pedidos se aceptan ya.
  • store_ids: ids de tienda seleccionados en Factulit (paso 2) separados por comas, "" = todas las tiendas, o null cuando la seleccion no se gestiona desde Factulit. Cuando no es null, el modulo debe espejarlo en su selector local de tiendas; el mismo valor viaja como parametro store_ids del callback de pull. Con null o ausente sigue mandando el selector local.

Conceptos sin mapear y naturaleza de los descuentos (v1.5+, v1.8) ​

unmapped_totals[] (v1.5+) transporta cualquier importe que participa en el total del pedido pero que el conector no puede traducir a linea fiscal: el canje de una tarjeta regalo, saldo a favor del cliente, un recargo del metodo de pago o un total de una extension de terceros. Cada entrada tiene un code estable en minusculas (por ejemplo store_credit), un title opcional y un value con signo, el efecto sobre el total del pedido. El conector solo registra el hecho; Factulit decide el tratamiento fiscal. Un codigo sin declarar deja el pedido retenido para revision hasta que el comerciante declara su tratamiento en el perfil de facturacion.

json
{
  "unmapped_totals": [
    { "code": "store_credit", "title": "Saldo del cliente", "value": -80, "kind": "customer_credit" }
  ]
}

El contrato v1.8 anade un campo opcional kind tanto a las entradas de discounts[] como de unmapped_totals[], describiendo la naturaleza comercial del concepto tal y como la observa el conector:

  • promotional (valor por defecto cuando esta ausente): un cupon comercial ordinario.
  • customer_credit: un saldo que la tienda debe al cliente (credito de tienda, credito de devolucion, monedero). Se aplica como descuento por defecto, salvo que el perfil elija retenerlo para revision.
  • gift_card: canje de una tarjeta regalo vendida previamente.
  • loyalty: puntos de fidelizacion propios de la tienda.
  • unknown: el conector no puede determinarlo.

kind es un hecho sobre el origen del cupon, nunca una instruccion fiscal: Factulit sigue decidiendo como tributa cada naturaleza. Para el lado de la venta de una tarjeta regalo, ver breakdown[].line_kind: gift_voucher (v1.5).

Eventos de correccion v1.3 ​

Envia contract_version: "1.3" cuando uses correction_events[]. Usa un id_external_event estable, describe el hecho observado, sus lineas y deltas con signo, y deja la decision fiscal en Factulit. Las ediciones administrativas genericas deben usar event_type: "unknown" y nunca justifican una emision automatica. refunds[] v1.2 sigue aceptandose y se normaliza a eventos explicitos de reembolso.

Envia contract_version: "1.4" para incluir tags[] opcional. La coincidencia es exacta y no distingue mayusculas tras normalizar. Las etiquetas describen el pedido; solo las reglas confirmadas por el propietario deciden la accion fiscal.

Los payloads v1.0 existentes siguen siendo validos sin estos campos.

Documentacion publica de la API de Factulit.