Qué dice GoCardless
| Reason | Tipo | Texto de GoCardless |
|---|---|---|
total_amount_confirmation_invalid | invalid_state | Total amount refunded does not match the confirmation value. |
number_of_refunds_exceeded | invalid_state | Maximum of 5 refunds per payment already reached. |
La referencia de los reembolsos explica el primero: «total_amount_confirmation_invalid if the confirmation amount doesn't match the total amount refunded for the payment.». Y para qué está: «This safeguard is there to prevent two processes from creating refunds without awareness of each other.».
Ese campo, dice GoCardless, es la suma de los reembolsos que ya tiene el pago más el que se crea, en céntimos. En su ejemplo, un reembolso de 100 lleva un total_amount_confirmation de 150: de ese pago ya se habían devuelto 50.

Cómo calcula el conector esa cifra
Para cada reembolso, el conector suma los reembolsos de ese cobro que en Odoo están pendientes, autorizados o hechos, y les añade el nuevo. Los que están en error no cuentan. Esa suma va como total_amount_confirmation.
Que cuente también los pendientes importa: un reembolso en camino ya está pedido a GoCardless, y si no lo sumara, la cifra se quedaría corta y GoCardless rechazaría el siguiente.
Cuándo no cuadra
La cifra sale de lo que Odoo sabe. Si alguien devolvió dinero de ese cobro por un camino que no pasa por Odoo, por ejemplo con otro programa conectado a la misma cuenta de GoCardless, GoCardless lo tiene apuntado y Odoo no. El total que manda el conector se queda corto, y GoCardless rechaza el reembolso. Es justo el caso para el que existe esta salvaguarda: si lo aceptara, el cliente recibiría dos veces el mismo dinero.
number_of_refunds_exceeded es otra cosa: el conector permite reembolsos parciales, y GoCardless admite como mucho 5 por pago. El sexto se rechaza aunque quede importe por devolver.
Lo que hace Odoo con el conector
En Odoo, un cobro se reembolsa desde su pago, con el botón de reembolso, y solo si su transacción está confirmada. El conector manda el reembolso con su clave de idempotencia y, si GoCardless lo rechaza, la transacción del reembolso pasa a «Error» con «GoCardless rechazó la solicitud.» y, debajo, el mensaje de GoCardless con el reason y el request_id entre corchetes.
Desde la versión 1.1.5, un reembolso en error no enseña el botón «Reintentar el cobro»: un reembolso no es un cobro.

Qué hacer
- Abre la transacción del cobro desde la factura, con el botón «Transacción de pago» de arriba; el menú de transacciones solo sale en modo desarrollador, y en Odoo 20 no existe. Desde ella, el botón de reembolsos lleva a la transacción del reembolso y a su mensaje.
- Con
total_amount_confirmation_invalid, mira en el Dashboard de GoCardless los reembolsos de ese pago. Si hay alguno hecho fuera de Odoo, el dinero ya ha vuelto al cliente: no lo devuelvas otra vez desde Odoo. - Con
number_of_refunds_exceeded, ese pago ya no admite más reembolsos en GoCardless. Si aún tienes que devolver algo, tendrá que ser por otra vía. - Para no llegar al límite, junta en un solo reembolso lo que haya que devolver de un mismo cobro.
- Si necesitas a GoCardless, guarda el
request_iddel mensaje: su documentación pide incluirlo al contactar con su soporte.
¿Por qué Odoo no ve los reembolsos hechos por otro camino?
GoCardless avisa por webhook de cada reembolso creado, pero el conector solo aplica esos avisos a los reembolsos que tiene en Odoo: uno creado por otro camino no tiene transacción, y no entra en la cifra.
¿Puedo devolver solo una parte de un cobro?
Sí. El conector permite reembolsos parciales, hasta el límite de 5 por pago que pone GoCardless; cada uno lleva en su cifra de control los anteriores.
Con nuestro conector
En Odoo 17, 18, 19 y 20 el conector manda en cada reembolso el total de lo reembolsado de ese cobro, contando los que están en camino, para que GoCardless pare un reembolso doble en lugar de pagarlo, y deja el rechazo en la transacción con su request_id.
Sigue leyendo
Comprobado en el código del conector (versión 17.0, 18.0, 19.0 y 20.0) y en las fuentes enlazadas
Fuentes
- docs.gocardless.com/docs/api-reference/responses-and-errors
- docs.gocardless.com/docs/api-reference/refund
- Código del módulo: flexigo_payment_gocardless: models/payment_transaction.py, línea 550 en 17.0 (d203ee6), línea 550 en 18.0 (e2ab18b), línea 549 en 19.0 (ce7f5a3) y línea 568 en 20.0 (688d86b)
- Código del módulo: flexigo_payment_gocardless: models/payment_transaction.py, línea 389 en 17.0 (d203ee6), línea 389 en 18.0 (e2ab18b), línea 388 en 19.0 (ce7f5a3) y línea 403 en 20.0 (688d86b)
- Código del módulo: flexigo_payment_gocardless: models/payment_transaction.py, línea 383 en 17.0 (d203ee6), línea 383 en 18.0 (e2ab18b), línea 382 en 19.0 (ce7f5a3) y línea 397 en 20.0 (688d86b)
- Código del módulo: flexigo_payment_gocardless: models/payment_provider.py, línea 256 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) y 20.0 (688d86b)
- Código del módulo: flexigo_payment_gocardless: models/payment_transaction.py, línea 397 en 17.0 (d203ee6), línea 397 en 18.0 (e2ab18b), línea 396 en 19.0 (ce7f5a3) y línea 411 en 20.0 (688d86b)
- Código del módulo: flexigo_payment_gocardless: models/payment_provider.py, línea 352 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) y 20.0 (688d86b)
- Código del módulo: flexigo_payment_gocardless: models/payment_provider.py, línea 397 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) y 20.0 (688d86b)
- Código del módulo: flexigo_payment_gocardless: models/payment_provider.py, línea 462 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) y 20.0 (688d86b)
- Código del módulo: flexigo_payment_gocardless: i18n/es.po, línea 560 en 17.0 (d203ee6), línea 560 en 18.0 (e2ab18b), línea 560 en 19.0 (ce7f5a3) y línea 565 en 20.0 (688d86b)
- Código del módulo: flexigo_payment_gocardless: models/payment_transaction.py, línea 424 en 17.0 (d203ee6), línea 424 en 18.0 (e2ab18b), línea 423 en 19.0 (ce7f5a3) y línea 438 en 20.0 (688d86b)
- Código del módulo: flexigo_payment_gocardless: models/payment_transaction.py, línea 418 en 17.0 (d203ee6), línea 418 en 18.0 (e2ab18b), línea 417 en 19.0 (ce7f5a3) y línea 432 en 20.0 (688d86b)
- Código del módulo: flexigo_payment_gocardless: models/payment_transaction.py, línea 63 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) y 20.0 (688d86b)
- github.com/odoo/odoo/blob/20.0/addons/payment/models/payment_transaction.py
- github.com/odoo/odoo/blob/20.0/addons/account_payment/views/account_payment_views.xml
- github.com/odoo/odoo/blob/20.0/addons/payment/i18n/es.po
- github.com/odoo/odoo/blob/20.0/addons/account_payment/views/account_move_views.xml
- Código del módulo: flexigo_payment_gocardless: __manifest__.py, línea 31 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) y 20.0 (688d86b)
- github.com/odoo/odoo/blob/17.0/odoo/http.py
