Saltar para o conteúdo principal
API GoCardless · invalid_state · reembolsos

GoCardless total_amount_confirmation_invalid: o total reembolsado não bate certo

Cada reembolso pedido à GoCardless leva um valor de controlo: tudo o que foi reembolsado desse pagamento, contando o novo. Se não coincidir com o que a GoCardless tem registado, rejeita o reembolso com total_amount_confirmation_invalid. É uma salvaguarda contra dois sistemas que reembolsam a mesma cobrança sem saber um do outro.

FlexigoTech · Responsável: Víctor Gómez · Atualizado em 6 de novembro de 2026

O essencial

Módulo
GoCardless
Versões
Odoo 17, 18, 19 e 20
Verificado
no código do conector, versão 17.0, 18.0, 19.0 e 20.0 · nas fontes indicadas no fim
Leitura
4 min

O que diz a GoCardless

ReasonTipoTexto da 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.

A referência dos reembolsos explica o primeiro: «total_amount_confirmation_invalid if the confirmation amount doesn't match the total amount refunded for the payment.». E para que serve: «This safeguard is there to prevent two processes from creating refunds without awareness of each other.».

Esse campo, diz a GoCardless, é a soma dos reembolsos que o pagamento já tem mais o que se cria, em cêntimos. No exemplo deles, um reembolso de 100 leva um total_amount_confirmation de 150: desse pagamento já tinham sido devolvidos 50.

Cartão do erro total_amount_confirmation_invalid da GoCardless
O reason, o seu tipo invalid_state, o campo total_amount_confirmation e o limite de 5 reembolsos por pagamento.

Como o conector calcula esse valor

Para cada reembolso, o conector soma os reembolsos dessa cobrança que, no Odoo, estão pendentes, autorizados ou concluídos, e acrescenta o novo. Os que estão em erro não contam. Essa soma vai como total_amount_confirmation.

Que contem também os pendentes é importante: um reembolso em curso já foi pedido à GoCardless, e se não fosse somado, o valor ficaria aquém e a GoCardless rejeitaria o seguinte.

Quando não bate certo

O valor sai do que o Odoo sabe. Se alguém devolveu dinheiro dessa cobrança por um caminho que não passa pelo Odoo, por exemplo com outro programa ligado à mesma conta GoCardless, a GoCardless tem esse registo e o Odoo não. O total enviado pelo conector fica aquém, e a GoCardless rejeita o reembolso. É exatamente o caso para que existe esta salvaguarda: se o aceitasse, o cliente receberia duas vezes o mesmo dinheiro.

number_of_refunds_exceeded é outra coisa: o conector permite reembolsos parciais, e a GoCardless admite no máximo 5 por pagamento. O sexto é rejeitado mesmo que ainda falte devolver valor.

O que faz o Odoo com o conector

No Odoo, uma cobrança reembolsa-se a partir do seu pagamento, com o botão de reembolso, e só se a sua transação estiver confirmada. O conector envia o reembolso com a sua chave de idempotência e, se a GoCardless o rejeitar, a transação do reembolso passa a «Erro» com «A GoCardless rejeitou o pedido.» e, por baixo, a mensagem da GoCardless com o reason e o request_id entre parênteses retos.

Desde a versão 1.1.5, um reembolso em erro não mostra o botão «Tentar cobrar novamente»: um reembolso não é uma cobrança.

Esquema: o que responde a GoCardless quando o total não bate certo e o que faz o Odoo com o conector
Esquema feito a partir do código do conector (17.0, 18.0, 19.0 e 20.0) e da documentação da GoCardless.

O que fazer

  1. Abra a transação da cobrança a partir da fatura, com o botão «Transação de Pagamento» no topo; o menu de transações só aparece em modo de programador, e no Odoo 20 não existe. A partir dela, o botão de reembolsos leva à transação do reembolso e à sua mensagem.
  2. Com total_amount_confirmation_invalid, consulte no Dashboard da GoCardless os reembolsos desse pagamento. Se houver algum feito fora do Odoo, o dinheiro já voltou ao cliente: não o devolva outra vez a partir do Odoo.
  3. Com number_of_refunds_exceeded, esse pagamento já não aceita mais reembolsos na GoCardless. Se ainda tiver de devolver algo, terá de ser por outra via.
  4. Para não chegar ao limite, junte num único reembolso tudo o que haja a devolver de uma mesma cobrança.
  5. Se precisar da GoCardless, guarde o request_id da mensagem: a documentação deles pede que o inclua ao contactar o suporte.

Porque é que o Odoo não vê os reembolsos feitos por outra via?

A GoCardless avisa por webhook de cada reembolso criado, mas o conector só aplica esses avisos aos reembolsos que tem no Odoo: um criado por outra via não tem transação e não entra no valor.

Posso devolver apenas uma parte de uma cobrança?

Sim. O conector permite reembolsos parciais, até ao limite de 5 por pagamento que a GoCardless impõe; cada um leva no seu valor de controlo os anteriores.

Com o nosso conector

No Odoo 17, 18, 19 e 20, o conector envia em cada reembolso o total reembolsado dessa cobrança, contando os que estão em curso, para que a GoCardless trave um reembolso duplicado em vez de o pagar, e deixa a rejeição na transação com o seu request_id.

Continue a ler

GoCardless refund_payment_invalid_state: esta cobrança ainda não pode ser reembolsadaA GoCardless responde refund_payment_invalid_state se o pagamento não estiver confirmed nem paid_out. As regras de prazo da GoCardless e do conector no Odoo.GoCardless 409 idempotent_creation_conflict: a cobrança já existiaA GoCardless devolve 409 idempotent_creation_conflict se uma chave de idempotência já criou algo. Porque não é falha e como o conector evita cobrar a dobrar.GoCardless MD06: o cliente pede ao banco o estorno de uma cobrançaO cliente pede ao banco o estorno de um débito GoCardless: charged_back, refund_requested e MD06. O que acontece no Odoo à fatura e ao mandato.
Verificado no código do conector (versão 17.0, 18.0, 19.0 e 20.0) e nas fontes indicadas

Fontes

  • docs.gocardless.com/docs/api-reference/responses-and-errors
  • docs.gocardless.com/docs/api-reference/refund
  • Código do módulo: flexigo_payment_gocardless: models/payment_transaction.py, linha 550 em 17.0 (d203ee6), linha 550 em 18.0 (e2ab18b), linha 549 em 19.0 (ce7f5a3) e linha 568 em 20.0 (688d86b)
  • Código do módulo: flexigo_payment_gocardless: models/payment_transaction.py, linha 389 em 17.0 (d203ee6), linha 389 em 18.0 (e2ab18b), linha 388 em 19.0 (ce7f5a3) e linha 403 em 20.0 (688d86b)
  • Código do módulo: flexigo_payment_gocardless: models/payment_transaction.py, linha 383 em 17.0 (d203ee6), linha 383 em 18.0 (e2ab18b), linha 382 em 19.0 (ce7f5a3) e linha 397 em 20.0 (688d86b)
  • Código do módulo: flexigo_payment_gocardless: models/payment_provider.py, linha 256 em 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) e 20.0 (688d86b)
  • Código do módulo: flexigo_payment_gocardless: models/payment_transaction.py, linha 397 em 17.0 (d203ee6), linha 397 em 18.0 (e2ab18b), linha 396 em 19.0 (ce7f5a3) e linha 411 em 20.0 (688d86b)
  • Código do módulo: flexigo_payment_gocardless: models/payment_provider.py, linha 352 em 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) e 20.0 (688d86b)
  • Código do módulo: flexigo_payment_gocardless: models/payment_provider.py, linha 397 em 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) e 20.0 (688d86b)
  • Código do módulo: flexigo_payment_gocardless: models/payment_provider.py, linha 462 em 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) e 20.0 (688d86b)
  • Código do módulo: flexigo_payment_gocardless: i18n/pt.po, linha 558 em 17.0 (d203ee6), linha 558 em 18.0 (e2ab18b), linha 558 em 19.0 (ce7f5a3) e linha 564 em 20.0 (688d86b)
  • Código do módulo: flexigo_payment_gocardless: models/payment_transaction.py, linha 424 em 17.0 (d203ee6), linha 424 em 18.0 (e2ab18b), linha 423 em 19.0 (ce7f5a3) e linha 438 em 20.0 (688d86b)
  • Código do módulo: flexigo_payment_gocardless: models/payment_transaction.py, linha 418 em 17.0 (d203ee6), linha 418 em 18.0 (e2ab18b), linha 417 em 19.0 (ce7f5a3) e linha 432 em 20.0 (688d86b)
  • Código do módulo: flexigo_payment_gocardless: models/payment_transaction.py, linha 63 em 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) e 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/pt.po
  • github.com/odoo/odoo/blob/20.0/addons/account_payment/views/account_move_views.xml
  • Código do módulo: flexigo_payment_gocardless: __manifest__.py, linha 31 em 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) e 20.0 (688d86b)
  • github.com/odoo/odoo/blob/17.0/odoo/http.py