Factuarea API
Pasarelas de pago

Payouts y conciliación bancaria

Cómo Factuarea ingiere los payouts de Stripe, los vincula con los cobros que agrupan, los concilia contra tu extracto Norma 43 y emite el evento payout.reconciled.

Cuando conectas Stripe vía Stripe Connect, Stripe no transfiere cada cobro a tu banco de uno en uno: agrupa muchos cobros, resta sus comisiones y envía un único payout (po_xxx) a tu cuenta. La línea que aparece en tu extracto reza STRIPE PAYOUT 1.234,56 € y es el neto de N cobros menos comisiones, así que nunca casa con el total de una sola factura.

Factuarea cierra ese ciclo. Ingiere cada payout, lo vincula con los cobros que lo componen y concilia la línea bancaria contra el payout, no contra una factura. Cuando confirmas el match, el payout, la transacción bancaria y todos los cobros subyacentes quedan marcados como conciliados en un único paso atómico.

Los payouts son de solo lectura en la API pública: puedes listarlos e inspeccionarlos junto con su estado de conciliación, pero la conciliación en sí se hace en el Dashboard contra tu extracto Norma 43 importado. Dos endpoints v1 los exponen:

Ingesta de un payout

Cada vez que Stripe completa un payout envía un webhook payout.paid a tu endpoint de Connect. Factuarea reacciona a él:

  1. Registra el payout — connected_account_id (acct_xxx), stripe_payout_id (po_xxx), los importes neto, comisiones y bruto, la divisa y la fecha de llegada prevista — con status: ingested.
  2. Lee las balance transactions del payout en tu nombre (una llamada de solo lectura y paginada a Stripe) para descubrir qué cobros agrupa el payout y el total de comisiones. Ese desglose se guarda como la composition informativa.

La ingesta es idempotente en dos niveles: por el event.id de Stripe (un payout.paid reentregado se procesa como máximo una vez) y por el stripe_payout_id (dos eventos distintos del mismo po_xxx nunca crean una fila duplicada — la unicidad está garantizada en la base de datos, incluso con webhooks concurrentes).

Si el desglose no se puede leer (un error transitorio de Stripe tras los reintentos), el payout no queda ingerido a medias: se reintenta el paso completo, y el event.id solo se marca como procesado cuando la ingesta termina con éxito. Nunca hay una fila de payout sin sus importes.

Para ingerir payouts debes habilitar el evento payout.paid en tu endpoint de webhook de Connect en el Stripe Dashboard. Como siempre, valida el flujo primero con una clave fact_test_ — en el sandbox la ingesta corre contra una empresa aislada con todos los efectos externos desactivados.

Vinculación de los cobros con el payout

Las balance transactions le dicen a Factuarea qué cobros componen el payout. Cada componente lleva su payment_intent (pi_xxx) de Stripe — el mismo identificador que Factuarea estampó en el Payment que registró cuando el cobro se auto-facturó (ver Auto-facturación Stripe).

Con ese identificador, Factuarea encuentra los Payment correspondientes de tu empresa y estampa el id del payout en cada uno. Así los cobros de un payout quedan vinculados a los cobros que los produjeron — la relación que más tarde permite que la conciliación baje en cascada hasta cada cobro.

La vinculación es best-effort e idempotente: re-vincular el mismo payout no es un error, y un componente sin Payment correspondiente (un cobro recibido antes de que existiera la auto-facturación, o por otra herramienta) se registra en el log de integración sin bloquear el resto. El payout se ingiere igualmente — la conciliación casa por el importe neto, nunca exige un desglose completo de los cobros.

Conciliación contra el extracto bancario

La conciliación corre sobre tu extracto bancario Norma 43 importado, en el Dashboard. Cuando subes un extracto, Factuarea propone matches para cada línea de abono. Antes de intentar casar un abono contra una factura pendiente, comprueba si la línea es un payout:

SeñalRegla
ImporteEl abono bancario equivale al importe neto del payout (dentro de una pequeña tolerancia de redondeo). Esta es la señal dura.
Ventana de llegadaLa fecha valor del banco cae dentro de ±3 días del arrival_date del payout (los bancos liquidan con un pequeño desfase).
DescripciónUna mención STRIPE suma confianza pero nunca es requisito — la redacción varía entre bancos.

El resultado depende de cuántos payouts ingested encajen:

  • Exactamente uno → un match de payout automático.
  • Más de uno → una sugerencia con los candidatos, para que elijas.
  • Ninguno → la línea continúa al matching ordinario por factura (un abono que no es un payout debe seguir casando con una factura).

Una transacción casada contra un payout queda excluida del matching por factura, y viceversa, de modo que la misma línea bancaria nunca se concilia dos veces.

El matching es por divisa. El payout se ingiere en su divisa real y solo casa con líneas bancarias en la misma divisa — no hay conversión (esto es conciliación contable, no una operación fiscal, así que nunca emite ni altera una factura).

Confirmación del match

Cuando confirmas un match de payout en el Dashboard, Factuarea ejecuta una única transacción atómica:

  1. La transacción bancaria se marca conciliada (con tipo de match payout).
  2. El payout transiciona a reconciled (un estado terminal) y registra la referencia de la transacción bancaria en bank_transaction_ref.
  3. Cada Payment vinculado al payout queda estampado con su reconciled_at y la referencia de la transacción bancaria.

Hay guards que protegen cada paso: la transacción bancaria debe seguir pending, el payout debe seguir ingested, y los importes deben coincidir. Confirmar un payout que ya está conciliado, o una transacción que ya está casada, se rechaza sin dejar ningún estado a medias. Toda la operación es tenant-scoped: un payout o una transacción de otra empresa nunca es visible ni conciliable.

Inspeccionar payouts en la API

Lista los payouts de tu empresa con paginación por cursor, filtrados por status de conciliación y por ventana de fecha de llegada:

curl "https://api.factuarea.com/v1/payouts?status=ingested&arrival_date[gte]=2026-01-01&limit=25" \
  -H "Authorization: Bearer fact_test_…"
{
  "data": [
    {
      "id": "0192f3a4-7b2c-7e10-9c1a-1f2e3d4c5b6a",
      "object": "stripe_payout",
      "connected_account_id": "acct_1QabcDEF2ghIJklm",
      "stripe_payout_id": "po_1QabcDEF2ghIJklm",
      "amount_net": "1234.56",
      "fee_total": "37.04",
      "amount_gross": "1271.60",
      "currency": "EUR",
      "arrival_date": "2026-01-08",
      "status": "ingested",
      "reconciled_at": null,
      "bank_transaction_ref": null,
      "composition": {
        "components": [
          { "payment_intent": "pi_3QabcDEF2ghIJklm", "charge_id": "ch_3QabcDEF2ghIJklm", "amount": 121.00, "fee": 3.50 }
        ],
        "fee_total": 37.04
      }
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Cada identificador es opaco:

  • id es el UUID v7 del payout — la identidad pública del recurso.
  • connected_account_id (acct_xxx) y stripe_payout_id (po_xxx) son ids externos de Stripe, no foreign keys a otros recursos de Factuarea.
  • bank_transaction_ref es el UUID (v7) de la transacción del extracto bancario conciliada — null mientras el payout sigue ingested.
  • composition referencia ids opacos de Stripe (payment_intent = pi_xxx, charge_id = ch_xxx), no UUIDs internos de cobro. Puede estar vacío cuando no se pudo leer el desglose.

El status de un payout es ingested hasta que se concilia contra una línea bancaria, y luego reconciled (terminal). Obtén un payout concreto por su id:

curl "https://api.factuarea.com/v1/payouts/0192f3a4-7b2c-7e10-9c1a-1f2e3d4c5b6a" \
  -H "Authorization: Bearer fact_test_…"

Devuelve 404 si el payout no existe o pertenece a otra empresa.

El evento saliente

Cuando un payout se concilia, Factuarea emite el evento payout.reconciled. Su payload lleva el snapshot completo del payout (object) más el importe neto, la divisa y la referencia de la transacción bancaria, de modo que un receptor de webhooks pueda cerrar su propia contabilidad en el momento en que el dinero se confirma en el banco. Suscríbete a él como a cualquier otro evento — ver Webhooks y Eventos.

No existe un scope payouts:write: los payouts se observan, nunca se mutan, a través de la API. El único cambio de estado — la conciliación — se dispara desde el Dashboard contra tu extracto Norma 43, y el evento es lo que notifica a tu integración.

En esta página