Saltar para o conteúdo principal
GoCardless API · invalid_api_usage · 429

GoCardless 429 rate_limit_exceeded: demasiados pedidos por minuto

A GoCardless limita os pedidos que aceita por minuto. Quem ultrapassa o limite recebe um 429 com o reason rate_limit_exceeded e um cabeçalho que indica quando pode continuar. O conector não lhe mostra isto à primeira: espera o tempo que a GoCardless pede e repete o pedido uma vez. Só se voltar a bater no limite verá o erro no Odoo.

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

ReasonTipoHTTPTexto da GoCardless
rate_limit_exceededinvalid_api_usage429Rate limit reached. Check headers for reset time.

A página de limites da GoCardless indica o número: 1 600 pedidos por minuto numa integração padrão e 1 600 por minuto e por comerciante numa integração de parceiro. Ao ultrapassá-lo, a API devolve o 429, e a GoCardless esclarece que estes pedidos podem ser repetidos sem problema: «These requests are safe to retry.». Para saber quando, remete para os cabeçalhos da resposta: ratelimit-limit, ratelimit-remaining e ratelimit-reset.

Cartão do erro rate_limit_exceeded da GoCardless
O reason, o código HTTP 429, o cabeçalho ratelimit-reset e o limite de 1 600 pedidos por minuto publicado pela GoCardless.

De onde vêm tantos pedidos

O limite conta todos os pedidos à API, não só os que criam cobranças. Com o conector, cada cobrança com um mandato guardado é um pedido, quer venha de uma subscrição que se renova quer de um pagamento registado com o método de pagamento do cliente. Cada evento de um pagamento que chega ao Odoo é outro, porque o conector não confia apenas no aviso: pede esse pagamento à GoCardless e aplica o estado que ela devolve. Um lote grande no mesmo momento, como muitas renovações ao mesmo tempo enquanto chegam os eventos das cobranças anteriores, soma as duas coisas.

A GoCardless classifica este reason entre os erros invalid_api_usage, os que vêm da forma como o pedido é feito, e para estes pede que se avise a equipa técnica («alert your dev team»). Um 429 isolado não o exige; um que se repete todos os dias, sim.

O que faz o conector

  1. Lê o cabeçalho ratelimit-reset e calcula quanto falta: a hora que indica menos a do servidor do Odoo.
  2. Espera esse tempo, no mínimo 1 segundo e no máximo 65. Se o cabeçalho faltar ou não puder ser lido, espera 1 segundo. O teto existe para que um relógio mal configurado não deixe bloqueado o processo do Odoo que aguarda.
  3. Repete o pedido uma única vez.
  4. Se a repetição voltar a receber um 429, já não espera mais: trata-o como qualquer outra rejeição da API.

O conector não conta os seus pedidos nem os trava antecipadamente. Não lê ratelimit-remaining: só espera quando a GoCardless já respondeu com 429.

Esquema: o que a GoCardless responde com um 429 e o que o Odoo faz 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.

Se o segundo pedido também falhar

Depende do que o Odoo estava a fazer naquele momento.

  • Se era uma cobrança, a transação passa a «Erro» com «A GoCardless rejeitou o pedido.» e, por baixo, a mensagem da GoCardless com rate_limit_exceeded e o request_id entre parênteses retos. A fatura continua pendente de cobrança.
  • Se estava a aplicar um evento da GoCardless, 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: volta a pedi-lo na passagem seguinte.

Um 429 não é o mesmo que uma cobrança sem resposta. Sem resposta, o conector não sabe se a GoCardless criou a cobrança, por isso deixa-a pendente e volta a enviá-la, com a mesma chave, em menos de uma hora. Com um 429 há resposta: a GoCardless não aceitou o pedido, e por isso a transação fica em erro.

Esta mensagem aparece no idioma de quem lança a cobrança. Se a lança uma ação agendada, como a renovação de uma subscrição, escreve-se sem ninguém à frente: numa base de dados criada em português aparece assim, e numa criada em inglês e passada depois para português, em inglês: «GoCardless rejected the request.».

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 mencionar rate_limit_exceeded, a GoCardless rejeitou esse pedido por causa do limite, não por causa do cliente nem do seu mandato.
  • Passado algum tempo, volte a cobrar a fatura com o método de pagamento guardado do cliente.
  • Se acontecer com frequência, verifique a hora do servidor do Odoo: a espera resulta de subtraí-la à de ratelimit-reset, e um relógio adiantado encurta-a.
  • Se precisar da GoCardless, guarde o request_id da mensagem: a documentação pede que o inclua ao contactar o seu suporte.

O conector distribui os pedidos para não chegar ao limite?

Não. Não os conta nem os trava antecipadamente: reage quando a GoCardless responde com 429, com uma espera e uma única repetição.

Porque espera no máximo 65 segundos?

Enquanto espera, o processo do Odoo que faz o pedido não faz mais nada. O código do conector define esse teto para que um relógio mal configurado não o deixe bloqueado.

Perde-se algum evento da GoCardless por causa do limite?

Não se considera perdido: o webhook pede à GoCardless que o volte a enviar, e a recuperação de cada hora volta a pedi-lo na passagem seguinte.

Com o nosso conector

No Odoo 17, 18, 19 e 20 o conector trata o 429 como uma pausa: espera o tempo que a GoCardless pede, repete uma vez e, se o limite continuar, deixa a transação em erro com o request_id, para que saiba o que aconteceu e o que dar à GoCardless.

Continue a ler

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.Webhook do GoCardless: 498 Token Invalid, 204 e a assinatura Webhook-SignatureO GoCardless pede 498 se a Webhook-Signature não coincidir e 204 se não reconhecer o evento. O que responde o Odoo 17, 18, 19 e 20 e porque no 20 é um 401.Erro mandate_is_inactive da GoCardless ao criar uma cobrança a partir do OdooA GoCardless responde mandate_is_inactive ao criar um pagamento com um mandato cancelado, falhado ou expirado. Porquê e como o conector o resolve no Odoo.
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/limits
  • docs.gocardless.com/docs/api-reference/responses-and-errors
  • Código do módulo: flexigo_payment_gocardless: const.py, linha 113 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 378 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 408 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 379 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 383 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: 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 247 em 17.0 (d203ee6), linha 247 em 18.0 (e2ab18b), linha 247 em 19.0 (ce7f5a3) e linha 258 em 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_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: controllers/main.py, linha 96 em 20.0 (688d86b)
  • Código do módulo: flexigo_payment_gocardless: models/gocardless_webhook_event.py, linha 7 em 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) e 20.0 (688d86b)
  • Código do módulo: flexigo_payment_gocardless: const.py, linha 117 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 603 em 17.0 (d203ee6), linha 603 em 18.0 (e2ab18b), linha 603 em 19.0 (ce7f5a3) e linha 605 em 20.0 (688d86b)
  • docs.gocardless.com/docs/api-reference/webhooks
  • 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)
  • github.com/odoo/odoo/blob/20.0/addons/payment/i18n/pt.po
  • github.com/odoo/odoo/blob/20.0/addons/payment/views/payment_transaction_views.xml
  • github.com/odoo/odoo/blob/17.0/odoo/http.py
  • 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)