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:
- Listar payouts de Stripe
(
payouts:read). - Obtener un payout de Stripe
(
payouts:read).
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:
- 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 — constatus: ingested. - 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
compositioninformativa.
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ñal | Regla |
|---|---|
| Importe | El abono bancario equivale al importe neto del payout (dentro de una pequeña tolerancia de redondeo). Esta es la señal dura. |
| Ventana de llegada | La fecha valor del banco cae dentro de ±3 días del arrival_date del payout (los bancos liquidan con un pequeño desfase). |
| Descripción | Una 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:
- La transacción bancaria se marca conciliada (con tipo de match
payout). - El payout transiciona a
reconciled(un estado terminal) y registra la referencia de la transacción bancaria enbank_transaction_ref. - Cada
Paymentvinculado al payout queda estampado con sureconciled_aty 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:
ides el UUID v7 del payout — la identidad pública del recurso.connected_account_id(acct_xxx) ystripe_payout_id(po_xxx) son ids externos de Stripe, no foreign keys a otros recursos de Factuarea.bank_transaction_refes el UUID (v7) de la transacción del extracto bancario conciliada —nullmientras el payout sigueingested.compositionreferencia 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.
Auto-facturación con Stripe
Emite facturas automáticamente desde los cobros de Stripe Connect — captura de NIF en el Checkout, umbral de factura simplificada, exigir NIF y qué cobros se derivan a revisión manual.
Verificación censal AEAT
Contrasta el par razón social + NIF de tu empresa — y el de tus clientes — contra el censo de la AEAT antes de emitir facturas VeriFactu — estados deterministas, NIFs mágicos del sandbox y comportamiento fail-open.