O que diz a GoCardless
| Reason | Tipo | Texto de GoCardless |
|---|---|---|
internal_server_error | gocardless | An internal error occurred. Report to support with request_id. |
request_timed_out | gocardless | Request did not complete in time. Retry, report if persistent. |
A GoCardless agrupa estes reasons no tipo gocardless, o dos erros que se produzem dentro da GoCardless: «These errors occurred within GoCardless while processing your request.». A sua tabela de códigos HTTP diz isto sobre os dois códigos:
| HTTP | Texto de GoCardless |
|---|---|
| 500 | Server-side error. Retry, and report to support with the request_id if it persists. |
| 504 | Request timed out. Retry, and report with request_id if it persists. |
Na página de limites, a GoCardless fixa ainda quanto pode durar um pedido: 29 segundos («Request timeout 29 seconds»).

Três casos que o conector não trata da mesma forma
O conector espera a resposta da GoCardless até 30 segundos em cada pedido. Com uma cobrança, um reembolso ou uma nova tentativa, o Odoo pode deparar-se com três situações diferentes:
- A GoCardless responde com um
500ou um504, com o reason na resposta. - A GoCardless não responde: a ligação corta-se ou esgotam-se os 30 segundos.
- A falha surge ao aplicar um evento, quando o conector pede à GoCardless o pagamento a que o evento se refere.
O que faz o conector
Com um 500 ou um 504. O conector só repete um pedido quando fica sem resposta ou depois de um 429. Com um 500 ou um 504 há resposta, por isso dá-a como rejeitada. Numa cobrança, a transação 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. A tarefa de cada hora não reenvia uma transação em erro. Se a GoCardless chegasse a criar a cobrança mesmo assim, o seu primeiro evento liga-a: cada cobrança leva nos seus metadados a referência da transação do Odoo, o conector procura-a com essa referência e aplica-lhe o estado do pagamento. Uma transação em erro volta assim a «Pendente» ou passa a «Confirmado».
Sem resposta. O conector repete o pedido uma vez, com a mesma chave de idempotência. Se também ninguém responder, não dá a cobrança por perdida: a transação fica pendente com «A GoCardless não respondeu, por isso ainda não se sabe se aceitou o pedido. Será enviado novamente, em segurança, dentro de uma hora.». A tarefa de cada hora volta a enviá-la com a mesma chave; se a GoCardless já a tiver criado, responde 409 e o conector adota o que já existe.
Ao aplicar um evento. Com cada evento de um pagamento, o conector pede esse pagamento à GoCardless. Se essa consulta falhar, o webhook responde 500 para que a GoCardless volte a enviar, e os eventos que já foram aplicados não são aplicados duas vezes. A recuperação de cada hora também não deixa para trás um evento que falhou.
Estes textos saem no idioma de quem lança a cobrança; se for uma ação agendada, como a renovação de uma subscrição, são escritos sem ninguém à frente: numa base de dados criada em português saem assim, e numa criada em inglês e passada depois para português, em inglês: «GoCardless rejected the request.» e «GoCardless did not answer, so it is not known yet whether it took the request. It will be sent again, safely, within the hour.».

O que fazer
- Abra a transação 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. Se a mensagem indicar
internal_server_errorourequest_timed_out, a falha foi da GoCardless, não do cliente nem do seu mandato. - Antes de voltar a cobrar a fatura, procure a cobrança no Dashboard da GoCardless: o conector põe como descrição de cada cobrança a referência da sua transação do Odoo. Se estiver lá, não cobre de novo; o seu evento vai ligar a transação.
- Se não estiver, volte a cobrar a fatura com o método de pagamento guardado do cliente. Uma cobrança nova é outra transação, com outra chave de idempotência: por isso convém verificar antes.
- Se se repetir, escreva ao suporte da GoCardless com o
request_idda mensagem: a sua documentação pede que o inclua ao contactar o suporte.
Porque é que o conector não repete um 500 como faz quando não há resposta?
Porque só repete às cegas o que se pode repetir sem risco: um pedido sem resposta, com a mesma chave, ou um que recebeu um 429 (segundo a GoCardless, esses podem ser repetidos sem problema). Um 500 ou um 504 é uma resposta, e o conector trata-a como uma rejeição.
Pode ficar uma cobrança duplicada?
Com a mesma chave, não: a GoCardless responde 409 e o conector adota a cobrança que já existe. O risco está em cobrar outra vez a partir da fatura, porque isso cria outra transação com outra chave. Por isso convém procurar antes a cobrança no Dashboard.
Com o nosso conector
No Odoo 17, 18, 19 e 20 o conector separa um erro da GoCardless de um pedido sem resposta: o primeiro fica em erro com o seu request_id, o segundo fica pendente e é reenviado com a mesma chave, e nos dois casos o evento de uma cobrança que existe liga-a à sua transação.
Continue a ler
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/limits
- Código do módulo: flexigo_payment_gocardless: models/payment_provider.py, linha 361 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 394 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 357 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 373 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 476 em 17.0 (d203ee6), linha 476 em 18.0 (e2ab18b), linha 476 em 19.0 (ce7f5a3) e linha 482 em 20.0 (688d86b)
- Código do módulo: flexigo_payment_gocardless: i18n/pt.po, linha 30 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 299 em 17.0 (d203ee6), linha 299 em 18.0 (e2ab18b), linha 299 em 19.0 (ce7f5a3) e linha 310 em 20.0 (688d86b)
- Código do módulo: flexigo_payment_gocardless: models/payment_provider.py, linha 391 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 68 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 281 em 17.0 (d203ee6), linha 281 em 18.0 (e2ab18b), linha 281 em 19.0 (ce7f5a3) e linha 292 em 20.0 (688d86b)
- Código do módulo: flexigo_payment_gocardless: models/payment_transaction.py, linha 258 em 17.0 (d203ee6), linha 258 em 18.0 (e2ab18b), linha 258 em 19.0 (ce7f5a3) e linha 269 em 20.0 (688d86b)
- Código do módulo: flexigo_payment_gocardless: models/payment_transaction.py, linha 115 em 17.0 (d203ee6), linha 115 em 18.0 (e2ab18b), linha 115 em 19.0 (ce7f5a3) e linha 118 em 20.0 (688d86b)
- Código do módulo: flexigo_payment_gocardless: models/payment_transaction.py, linha 572 em 17.0 (d203ee6), linha 572 em 18.0 (e2ab18b), linha 571 em 19.0 (ce7f5a3) e linha 590 em 20.0 (688d86b)
- Código do módulo: flexigo_payment_gocardless: models/payment_transaction.py, linha 697 em 17.0 (d203ee6), linha 697 em 18.0 (e2ab18b), linha 696 em 19.0 (ce7f5a3) e linha 720 em 20.0 (688d86b)
- Código do módulo: flexigo_payment_gocardless: models/payment_provider.py, linha 623 em 17.0 (d203ee6), linha 623 em 18.0 (e2ab18b), linha 623 em 19.0 (ce7f5a3) e linha 625 em 20.0 (688d86b)
- Código do módulo: flexigo_payment_gocardless: models/payment_transaction.py, linha 589 em 17.0 (d203ee6), linha 589 em 18.0 (e2ab18b), linha 588 em 19.0 (ce7f5a3) e linha 607 em 20.0 (688d86b)
- Código do módulo: flexigo_payment_gocardless: controllers/main.py, linha 124 em 17.0 (d203ee6), linha 124 em 18.0 (e2ab18b), linha 124 em 19.0 (ce7f5a3) e linha 127 em 20.0 (688d86b)
- Código do módulo: flexigo_payment_gocardless: models/payment_provider.py, linha 603 em 17.0 (d203ee6), linha 603 em 18.0 (e2ab18b), linha 603 em 19.0 (ce7f5a3) e linha 605 em 20.0 (688d86b)
- 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
- github.com/odoo/odoo/blob/17.0/odoo/http.py
- 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)
