Skip to Content
ConceptosÓrdenes

Órdenes

Si CheckoutSession es lo que ve el comprador, Order es lo que te importa a ti. Es el registro permanente de:

  • Qué se estaba comprando (line items)
  • Cuánto se debía y cuánto se ha pagado efectivamente
  • Reembolsos pendientes y aplicados
  • Tu referencia externa (external_ref): típicamente tu propio order ID, almacenado en la Order y devuelto en GET /b2b/v1/orders/{id} (no se replica en los payloads de webhook: ver abajo)

Una CheckoutSession muere después de que uno de sus PaymentIntents liquide o el TTL expire. La Order vive para siempre.

Cuándo se crea una Order

Cuando llamas a POST /b2b/v1/checkout-sessions/quick, payment-service crea tanto una nueva Order como una nueva CheckoutSession en una transacción. Si ya tienes una Order y quieres reintentar el checkout (p. ej., tras el abandono del comprador), usa POST /b2b/v1/checkout-sessions en su lugar para adjuntar una sesión nueva a la orden existente, preservando el rastro de auditoría.

Ciclo de vida

EstadoSignifica
DRAFTReservado para un futuro flujo de borradores. Ninguna ruta de código crea órdenes DRAFT hoy: toda orden se crea PENDING, así que no observarás este estado.
PENDINGUna CheckoutSession está activa y sin resolver.
PAIDImporte total liquidado. El webhook payment.settled se dispara aquí. Seguro para fulfillment.
PARTIAL_PAIDEl dinero llegó pero por menos del total. Ver “Pago insuficiente” abajo.
CANCELEDSesión expirada o cancelada por el comerciante. metadata.canceled_reason explica el motivo (payment_timeout, merchant_canceled, …).
REFUNDEDTodo el importe pagado ha sido reembolsado.
PARTIALLY_REFUNDEDSe ejecutó algún reembolso pero queda saldo pagado.

El estado sobre el que ramificar tu lógica de fulfillment es PAID, no el COMPLETED de la CheckoutSession. El webhook payment.settled es la señal canónica.

El campo external_ref

Al crear una sesión puedes incluir external_ref (cualquier cadena de hasta 255 caracteres: típicamente tu propio order ID). Se enhebra a través de todo el pipeline:

  • Almacenado en la Order
  • Visible en el dashboard del comerciante para búsquedas de soporte
  • Devuelto en GET /b2b/v1/orders/{id} para que un manejador de webhook pueda obtenerlo tras recibir payment.settled

Los payloads de webhook no replican external_ref directamente hoy: borradores anteriores de esta documentación afirmaban que data.external_ref fluía a través de cada evento, y eso era incorrecto. Para mapear un webhook payment.* de vuelta a tu fila de DB, toma order_id del payload y obtén la orden. El campo nativo external_ref en los payloads de webhook está en el roadmap.

Pago insuficiente

Si la transferencia on-chain del comprador se confirma por menos del total de la orden, la Order va a PARTIAL_PAID. Tienes tres opciones:

  1. Aceptar y resolver. Cambia la orden a PAID y dispara order.resolved. Esto no es un endpoint REST público: la resolución es una acción interna/operativa hoy, así que para un flujo self-serve prefiere la opción 2 (cobrar el remanente).
  2. Esperar el remanente. Crea una nueva CheckoutSession contra la misma Order con amount_due = residual. El comprador paga la diferencia; cuando eso liquide, la Order se mueve a PAID.
  3. Cancelar y reembolsar. Reembolsa el importe parcial y cancela la Order. El comprador es responsable de cualquier tarifa de cadena.

El producto no ha hecho una recomendación aquí: distintos comerciantes quieren políticas distintas. Elige una e intégrala en tu admin.

Reembolsos

Los reembolsos son una superficie de API separada y una página de concepto separada. Consulta Conceptos → Reembolsos.

Endpoints de la API

MétodoRutaNotas
POST/b2b/v1/ordersCrea una Order sin una sesión (raro)
GET/b2b/v1/orders/:order_idLee una orden completa con line items + historial de pagos
PATCH/b2b/v1/orders/:order_id/cancelCancela una orden no pagada
PATCH/b2b/v1/orders/:order_id/reopenReabre una orden autocancelada (payment_timeout)

Qué sigue