ROKIConnect

Anulación, reembolso y recibos

Estas operaciones actúan sobre una transacción, identificada por el UUID transaction_id de la respuesta del pago, nunca por el id numérico del pago.

Esa distinción importa porque un enlace reutilizable puede llevar varias transacciones: anular o reembolsar la transacción de un cliente deja las demás intactas.

Operación Ruta
Anulación POST /payments/{transaction_id}/void
Reembolso POST /payments/{transaction_id}/refund
Metadatos del recibo GET /payments/{transaction_id}/receipt
PDF del recibo GET /payments/{transaction_id}/receipt/download

13.1 Pasar el identificador equivocado parece un endpoint inexistente

La ruta solo coincide con el formato UUID, así que un id numérico de pago produce un 404 de ruteo:

POST /payments/9e2b6a34-6f1d-4e2a-8c9b-2f7a1d4e5c6b/void  ->  the route matched
POST /payments/873/void                                    ->  "The route ... could not be found."

Si ves ese mensaje en una anulación, un reembolso o un recibo, pasaste el id del pago donde va el UUID de la transacción. El endpoint está ahí.

13.2 ¿Anulación o reembolso?

Anulación Reembolso
Cuándo El mismo día, antes de la liquidación Después de la liquidación
Monto Solo total Total o parcial
Velocidad Inmediata 3-5 días hábiles de vuelta a la tarjeta
El cliente ve Que en realidad nunca se le cobró Dinero devuelto
Webhook payment.voided payment.refunded / payment.partially_refunded
Caso típico Error, cancelación inmediata Devolución, disputa, cobro de más

La elegibilidad la gobierna la ventana de tiempo configurada de la transacción, no solo el estado de liquidación. Intentar un reembolso demasiado pronto puede devolver 422 con un mensaje del procesador como "Invalid transaction" - ese texto viene del procesador y no es una respuesta que ROKI garantice.

Implementá la reversión así: probá primero la anulación; si se rechaza porque no es anulable o porque ya está liquidada, reembolsá en su lugar.

13.3 Anulación

POST /api/connect/v1/payments/{transaction_id}/void
{ "reason": "Customer cancelled" }        # optional, max 2000 chars

Devuelve el pago con status: "voided". Los rechazos llegan como 422 bajo errors.void: ya anulado, ya reembolsado (usá reembolso), no está en un estado anulable, o ya liquidado.

Una anulación también llena los campos de reembolso. Verificado en dos transacciones reales el 2026-08-14: después de anular, el pago lleva

{ "status": "voided", "refunded_amount": 25, "refund_status": "full" }

aunque no se reembolsó nada. Así que refund_status === 'full' no significa "esto fue reembolsado" - es igual de cierto para una anulación. Ramificá según status (voided vs refunded vs partially_refunded) y tratá los campos de reembolso como el monto devuelto al tarjetahabiente por cualquier vía, no como evidencia de qué operación se usó. Un reporte que cuente reembolsos por refund_status va a contar anulaciones como reembolsos sin avisar, y las dos son comercialmente distintas: una anulación nunca llega al estado de cuenta del cliente, un reembolso sí.

El webhook payment.voided llegó como un segundo después en ambas transacciones, con los mismos campos.

13.4 Reembolso

POST /api/connect/v1/payments/{transaction_id}/refund
{ "amount": 500.00, "reason": "Partial return" }

amount es obligatorio, mínimo 0.01, hasta el monto reembolsable restante. Un reembolso parcial deja partially_refunded; uno total pone refunded. 422 bajo errors.amount (debajo del mínimo, arriba del restante) o errors.refund (transacción anulada, no reembolsable).

El reembolso funciona igual para una transacción creada por cualquier modo, incluido un checkout embebido o un cobro con tarjeta guardada. No hay un endpoint de reembolso aparte para cobros con token: usá acá como transaction_id el id que devolvió el cobro.

13.5 Recibos

GET /payments/{transaction_id}/receipt devuelve payment_id, transaction_id y un receipt_url público. Agregá /download para el PDF. Los recibos sobreviven a una anulación o un reembolso mientras el cobro original siga teniendo una transacción.

13.6 Una nota sobre los identificadores

Dos referencias distintas, y mezclarlas es el error más común:

Vale la pena guardar los dos cuando se cobra un pago. El listado (9.2) puede recuperar un id perdido, pero solo si sabés qué estás buscando.