Concilia cobros Bitcoin y Lightning con tus pedidos en BTCPay

Aprende a conciliar cobros Bitcoin y Lightning con pedidos en BTCPay Server. Distingue invoice, pago y entrega; evita duplicados y detecta excepciones.

🐥 Tutorial práctico · Cobros para negocios

Concilia cobros Bitcoin y Lightning con tus pedidos en BTCPay

Una factura pagada no identifica por sí sola qué pedido hay que entregar. Aprende a relacionar pedido, invoice, pagos detectados y liquidación con BTCPay Server, sin duplicar entregas ni exponer datos de clientes.

⏱ 25–35 min🌱 Intermedio🧪 Simulación sin dinero
IDENTIFICA LAS PIEZAS

Pedido, invoice, pago y liquidación

El ID de pedido pertenece al comercio: por ejemplo P-0042. El ID de invoice lo emite BTCPay Server para una solicitud concreta de cobro. Una misma compra podría generar más de una factura si el cliente reintenta el checkout; eso no significa que el negocio haya vendido dos productos.

La transacción on-chain puede identificarse por una TXID; una operación Lightning utiliza otros identificadores, entre ellos un payment hash. No confundas TXID, payment hash, invoice ID ni order ID: representan objetos diferentes, y su disponibilidad depende del método.

BTCPay expone un estado base (status: New, Processing, Settled, Expired o Invalid) y una posible excepción (additionalStatus: PaidPartial, PaidOver, PaidLate, Marked, Invalid o None). La guía oficial insiste en consultar ambos campos: una factura puede figurar Expired y, a la vez, haber cobrado tarde. Un estado Marked no es prueba criptográfica de recepción.

PREPARA EL EJERCICIO

Tres pedidos ficticios para una conciliación

Dibuja tres filas en papel o en un CSV local de laboratorio. Cada una tiene orderId, invoiceId, método, importe cotizado, estado BTCPay, excepción, acción y fecha de revisión. No añadas claves de API, direcciones privadas, xpub ni datos de compradores reales.

Usaremos tres escenarios inventados: P-0042, un pedido de 12 EUR con invoice A; P-0043, un servicio de 25 EUR con invoice B; y P-0044, una compra de 18 EUR cuya primera invoice caducó y fue sustituida por otra. Las equivalencias en sats se leen de cada factura real: no calcules una conversión usando una cotización de hoy para reconciliar un pedido antiguo.

Si tienes una tienda BTCPay configurada, puedes abrir Payments → Invoices y observar los filtros sin crear pagos; las versiones recientes incluyen además una sección de informes (Reporting) exportable a CSV. La simulación completa puede hacerse sin solicitar fondos ni tocar la base de datos.

PASO A PASO

Reconstruye la historia de cada pedido

  1. PASO 1 · Identifica el pedido: registra su ID comercial único, producto, precio y moneda de referencia. No uses el email como clave primaria de reconciliación.
  2. PASO 2 · Relaciona la factura: apunta el invoice ID y su metadata.orderId si la integración lo ha establecido. Si falta, comprueba manualmente la asociación antes de modificarla.
  3. PASO 3 · Consulta la factura: abre sus detalles en BTCPay y observa status, additionalStatus, importes recibidos, método, historial y momento del último cambio.
  4. PASO 4 · Distingue método: on-chain puede necesitar confirmaciones; Lightning normalmente se liquida sin esas confirmaciones. No esperes una TXID on-chain para cada pago Lightning.
  5. PASO 5 · Separa incidencia de entrega: un pago parcial, excesivo, tardío o marcado manualmente debe pasar por la política comercial antes de liberar el pedido.
  6. PASO 6 · Protege la idempotencia: guarda que P-0042 ya fue entregado; un webhook repetido o un segundo proceso de conciliación no debe ejecutar de nuevo esa acción.
  7. PASO 7 · Verifica excepciones: busca facturas vencidas que recibieron fondos y pedidos con más de una invoice, sin asumir que la invoice más reciente es la única que importa.
  8. PASO 8 · Cierra el registro: anota la decisión y la evidencia que la justificó; si hay reembolso, regístralo como otra operación que debe comprobarse.

Este procedimiento es una conciliación, no una creación de facturas. Si todavía no distingues los estados de BTCPay, comienza por el recorrido de una factura desde el checkout hasta su liquidación.

EJERCICIO RESUELTO

Tres resultados y tres decisiones diferentes

P-0042

Settled sin excepción

La factura está liquidada, pertenece al pedido correcto y este no fue entregado antes: puede seguir el procedimiento normal de entrega.

P-0043

Processing on-chain

BTCPay detectó el pago completo, pero todavía faltan las confirmaciones que exige la tienda. No confundas «recibido en mempool» con el criterio de liquidación.

P-0044

Expired + PaidLate

La primera invoice caducó, pero después recibió fondos. No ignores ese dinero ni dupliques automáticamente el pedido cuando aparece una segunda invoice.

En el tercer caso, consulta ambas facturas y la política de cobro antes de decidir si entregar, solicitar una diferencia o devolver fondos. La expiración fija un plazo comercial; no revierte una transacción enviada.

AUTOMATIZAR SIN CEDER CONTROL

Metadatos, webhooks y Greenfield API

BTCPay dispone de la Greenfield API para consultar facturas con permisos acotados a una tienda. GET /api/v1/stores/{storeId}/invoices/{invoiceId} devuelve el status y el additionalStatus de una factura, y el listado de facturas de la tienda admite filtrar por orderId: así localizas todas las invoices de un mismo pedido, no solo la última.

Crea la API key con el permiso mínimo de ver facturas de esa tienda (btcpay.store.canviewinvoices), sin permisos de gestión de wallets ni de servidor. Guárdala fuera de HTML público y de los registros accesibles por clientes.

La guía oficial de integración considera que los webhooks firmados suelen bastar para actualizar el estado del pedido, y deja la consulta directa como respaldo. Aun así, antes de una acción irreversible (enviar un producto caro, emitir una licencia) consultar la factura es una comprobación barata. Suscribe también InvoiceReceivedPayment e InvoicePaymentSettled: son los eventos que te avisan de pagos que llegan después de la expiración.

Una regla idempotente para entrega sería: «si el pedido está pendiente y la invoice relevante cumple nuestra política, marcar una única vez como entregado». Para lograrlo necesitas una operación de actualización atómica o un mecanismo equivalente; una comprobación aislada en memoria no evita carreras entre dos workers.

QUÉ GUARDAR Y QUÉ EVITAR

Un registro útil no es un dossier de clientes

Conserva referencias mínimas: IDs, moneda cotizada, importe de referencia, resultado, hora, método, excepción y responsable. Si el comercio debe mantener otra documentación por obligaciones legales, sepárala del historial técnico de facturas.

No incluyas seeds, macaroons Lightning, claves de API ni xpub en reportes exportados. Una exportación de facturas puede revelar hábitos de cobro aunque sus direcciones sean públicas en la cadena. Limita quién accede al informe y durante cuánto tiempo se conserva.

Si comparas importes recibidos y cotizados, recuerda distinguir comisión minera, comisión de canal, comisión de servicio y conversión monetaria. No todos esos costes los asume el mismo participante, y algunos no aparecen como descuentos en la factura.

CUATRO CASOS QUE DEBEN DETENERTE

No fuerces un resultado para cuadrar el libro

🐥 ¿Una factura Settled tiene un orderId que no reconozco?

No la asignes por semejanza de precio. Verifica metadatos, registros de creación y procedimiento de la tienda. Un importe idéntico no identifica a un cliente.

🐥 ¿Aparecen dos invoices para un pedido?

Revisa si alguna recibió fondos y su estado. Nunca des por hecho que solo la más reciente puede cobrar. El objetivo es una entrega por pedido, no una factura por clic.

🐥 ¿Una factura fue marcada manualmente como liquidada?

Ese cambio puede reflejar una decisión administrativa y no prueba de liquidación en la red. Comprueba pagos subyacentes y deja trazabilidad de quién autorizó el cambio.

🐥 ¿El cliente solicita devolución?

Una devolución Bitcoin es otro pago, no una reversión. Verifica la identidad del pedido y un nuevo destino acordado. Sigue la guía de devoluciones Bitcoin.

RUTINA PARA CADA CIERRE

Qué revisar antes de emitir el informe diario

Antes de cerrar una jornada, revisa facturas sin pedido, pedidos sin factura, pagos parciales, facturas caducadas con pagos, pedidos con varias facturas y devoluciones pendientes. No es necesario procesar manualmente cada transacción si tienes una conciliación automatizada correcta, pero debes poder reproducir el diagnóstico cuando aparezca una excepción.

La pregunta final es sencilla: ¿puedes reconstruir qué factura justificó qué decisión y demostrar que esa decisión solo se ejecutó una vez? Ese es un objetivo más preciso que «el dashboard muestra todo en verde».

Para entrenar las excepciones, usa seis incidencias de cobro que puedes ensayar y, al final de la ruta, completa el reto integral del cobro Bitcoin.

VERIFICA EL RESULTADO

¿Puedes demostrar que cada pedido tiene una decisión justificada?

  1. Identificadores: diferencio orderId, invoice ID, TXID y payment hash.
  2. Estados: compruebo status y additionalStatus, no solo un aviso.
  3. Incidencias: detecto pagos parciales, tardíos y facturas duplicadas.
  4. Control: una notificación repetida no produce una segunda entrega.
  5. Privacidad: mi registro no contiene secretos ni datos personales innecesarios.
RESULTADO COMPROBABLE

Facturas conciliadas, entregas únicas

Has construido un proceso que puede distinguir una solicitud, un pago y una entrega, incluso cuando hay reintentos o una factura expirada. La evidencia queda asociada al pedido correcto.

FUENTES OFICIALES

Verifica los detalles en tu versión

Para automatizar la recepción del aviso, repasa los webhooks BTCPay verificados. Siguiente práctica: crea un punto de venta Bitcoin con BTCPay Server sin programar.

Ilustración de Pajarito sobre la conciliación de cobros Bitcoin y Lightning con pedidos.