Saltar al contenido principal
GoCardless API · invalid_state · reembolsos

GoCardless total_amount_confirmation_invalid: el total reembolsado no cuadra

Cada reembolso que se pide a GoCardless lleva una cifra de control: todo lo reembolsado de ese pago, contando el nuevo. Si no coincide con lo que GoCardless tiene apuntado, rechaza el reembolso con total_amount_confirmation_invalid. Es una salvaguarda contra dos sistemas que reembolsan el mismo cobro sin saber uno del otro.

FlexigoTech · Responsable: Víctor Gómez · Actualizado el 6 de noviembre de 2026

Lo esencial

Módulo
GoCardless
Versiones
Odoo 17, 18, 19 y 20
Comprobado
en el código del conector, versión 17.0, 18.0, 19.0 y 20.0 · en las fuentes enlazadas al final
Lectura
3 min

Qué dice GoCardless

ReasonTipoTexto de GoCardless
total_amount_confirmation_invalidinvalid_stateTotal amount refunded does not match the confirmation value.
number_of_refunds_exceededinvalid_stateMaximum 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.

Tarjeta del error total_amount_confirmation_invalid de GoCardless
El reason, su tipo invalid_state, el campo total_amount_confirmation y el límite de 5 reembolsos por pago.

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.

Esquema: qué responde GoCardless cuando el total no cuadra y qué hace Odoo con el conector
Esquema hecho a partir del código del conector (17.0, 18.0, 19.0 y 20.0) y de la documentación de GoCardless.

Qué hacer

  1. 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.
  2. 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.
  3. 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.
  4. Para no llegar al límite, junta en un solo reembolso lo que haya que devolver de un mismo cobro.
  5. Si necesitas a GoCardless, guarda el request_id del 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

GoCardless refund_payment_invalid_state: ese cobro aún no se puede reembolsarGoCardless responde refund_payment_invalid_state si el pago no está confirmed ni paid_out. Las reglas de plazo de GoCardless y del conector en Odoo.GoCardless 409 idempotent_creation_conflict: el cobro ya existíaGoCardless devuelve 409 idempotent_creation_conflict si una clave de idempotencia ya creó algo. Por qué no es un fallo y cómo evita el conector un doble cobro.GoCardless MD06: el cliente pide a su banco que le devuelva un cobroEl cliente pide a su banco que le devuelva un adeudo de GoCardless: charged_back, refund_requested y MD06. Qué pasa en Odoo con la factura y el mandato.
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