Saltar al contenido principal
GoCardless API · invalid_api_usage · 429

GoCardless 429 rate_limit_exceeded: demasiadas peticiones por minuto

GoCardless limita las peticiones que acepta por minuto. Quien se pasa recibe un 429 con el reason rate_limit_exceeded y una cabecera que dice cuándo puede seguir. El conector no te lo enseña a la primera: espera lo que pide GoCardless y repite la petición una vez. Solo si vuelve a chocar con el límite verás el error en Odoo.

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
4 min

Qué dice GoCardless

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

La página de límites de GoCardless pone la cifra: 1.600 peticiones por minuto en una integración estándar y 1.600 por minuto y comercio en una integración de partner. Al pasarse, la API devuelve el 429, y GoCardless aclara que esas peticiones se pueden repetir sin problema: «These requests are safe to retry.». Para saber cuándo, remite a las cabeceras de la respuesta: ratelimit-limit, ratelimit-remaining y ratelimit-reset.

Tarjeta del error rate_limit_exceeded de GoCardless
El reason, el código HTTP 429, la cabecera ratelimit-reset y el límite de 1.600 peticiones por minuto que publica GoCardless.

De dónde salen tantas peticiones

El límite cuenta todas las peticiones a la API, no solo las que crean cobros. Con el conector, cada cobro con un mandato guardado es una petición, venga de una suscripción que se renueva o de un pago registrado con el método de pago del cliente. Cada evento de un pago que llega a Odoo es otra, porque el conector no se fía solo del aviso: pide ese pago a GoCardless y aplica el estado que le devuelve. Una tanda grande en el mismo momento, como muchas renovaciones a la vez mientras llegan los eventos de los cobros anteriores, suma las dos cosas.

GoCardless clasifica este reason entre los errores invalid_api_usage, los que vienen de cómo se hace la petición, y para esos pide avisar al equipo técnico («alert your dev team»). Un 429 suelto no lo necesita; uno que se repite cada día, sí.

Lo que hace el conector

  1. Lee la cabecera ratelimit-reset y calcula cuánto falta: la hora que trae menos la del servidor de Odoo.
  2. Espera ese tiempo, como mínimo 1 segundo y como mucho 65. Si la cabecera falta o no se puede leer, espera 1 segundo. El tope está para que un reloj mal puesto no deje colgado el proceso de Odoo que espera.
  3. Repite la petición una sola vez.
  4. Si la repetición vuelve a recibir un 429, ya no espera más: lo trata como cualquier otro rechazo de la API.

El conector no cuenta sus peticiones ni las frena por adelantado. No lee ratelimit-remaining: solo espera cuando GoCardless ya ha contestado 429.

Esquema: qué responde GoCardless con un 429 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.

Si el segundo intento también choca

Depende de lo que estaba haciendo Odoo en ese momento.

  • Si era un cobro, la transacción pasa a «Error» con «GoCardless rechazó la solicitud.» y, debajo, el mensaje de GoCardless con rate_limit_exceeded y el request_id entre corchetes. La factura sigue pendiente de cobro.
  • Si estaba aplicando un evento de GoCardless, el webhook contesta 500 para que GoCardless vuelva a mandar el envío, y los eventos que ya se aplicaron no se aplican dos veces. La recuperación de cada hora tampoco deja atrás un evento que falló: lo vuelve a pedir en la pasada siguiente.

Un 429 no es lo mismo que un cobro sin respuesta. Sin respuesta, el conector no sabe si GoCardless creó el cobro, así que lo deja pendiente y lo vuelve a mandar, con la misma clave, en menos de una hora. Con un 429 sí hay respuesta: GoCardless no aceptó la petición, y por eso la transacción queda en error.

Ese mensaje sale en el idioma de quien lanza el cobro. Si lo lanza una tarea programada, como la renovación de una suscripción, se escribe sin nadie delante: en una base de datos creada en castellano sale así, y en una creada en inglés y pasada después a castellano, en inglés: «GoCardless rejected the request.».

Qué hacer

  • Abre la transacción 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. Si el mensaje nombra rate_limit_exceeded, GoCardless rechazó esa petición por el límite, no por el cliente ni por su mandato.
  • Pasado un rato, vuelve a cobrar la factura con el método de pago guardado del cliente.
  • Si te pasa a menudo, comprueba la hora del servidor de Odoo: la espera sale de restarla a la de ratelimit-reset, y un reloj adelantado la acorta.
  • Si necesitas a GoCardless, guarda el request_id del mensaje: su documentación pide incluirlo al contactar con su soporte.

¿El conector reparte las peticiones para no llegar al límite?

No. No las cuenta ni las frena por adelantado: reacciona cuando GoCardless contesta 429, con una espera y una sola repetición.

¿Por qué espera como mucho 65 segundos?

Mientras espera, el proceso de Odoo que hace la petición no hace otra cosa. El código del conector pone ese tope para que un reloj mal puesto no lo deje colgado.

¿Se pierde algún evento de GoCardless por el límite?

No se da por perdido: el webhook pide a GoCardless que lo vuelva a mandar, y la recuperación de cada hora lo vuelve a pedir en la pasada siguiente.

Con nuestro conector

En Odoo 17, 18, 19 y 20 el conector trata el 429 como una pausa: espera lo que pide GoCardless, repite una vez y, si el límite sigue, deja la transacción en error con el request_id para que sepas qué pasó y qué darle a GoCardless.

Sigue leyendo

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.Webhook de GoCardless: 498 Token Invalid, 204 y la firma Webhook-SignatureGoCardless pide 498 si la firma Webhook-Signature no cuadra y 204 si no reconoce el evento. Qué contesta Odoo 17, 18, 19 y 20 y por qué en 20 es un 401.Error mandate_is_inactive de GoCardless al crear un cobro desde OdooGoCardless responde mandate_is_inactive al crear un pago con un mandato cancelado, fallido o caducado. Por qué pasa y cómo lo resuelve el conector en Odoo.
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/limits
  • docs.gocardless.com/docs/api-reference/responses-and-errors
  • Código del módulo: flexigo_payment_gocardless: const.py, línea 113 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 378 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 408 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 379 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 383 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: models/payment_transaction.py, línea 281 en 17.0 (d203ee6), línea 281 en 18.0 (e2ab18b), línea 281 en 19.0 (ce7f5a3) y línea 292 en 20.0 (688d86b)
  • Código del módulo: flexigo_payment_gocardless: models/payment_transaction.py, línea 247 en 17.0 (d203ee6), línea 247 en 18.0 (e2ab18b), línea 247 en 19.0 (ce7f5a3) y línea 258 en 20.0 (688d86b)
  • Código del módulo: flexigo_payment_gocardless: models/payment_transaction.py, línea 299 en 17.0 (d203ee6), línea 299 en 18.0 (e2ab18b), línea 299 en 19.0 (ce7f5a3) y línea 310 en 20.0 (688d86b)
  • Código del módulo: flexigo_payment_gocardless: models/payment_transaction.py, línea 589 en 17.0 (d203ee6), línea 589 en 18.0 (e2ab18b), línea 588 en 19.0 (ce7f5a3) y línea 607 en 20.0 (688d86b)
  • Código del módulo: flexigo_payment_gocardless: controllers/main.py, línea 124 en 17.0 (d203ee6), línea 124 en 18.0 (e2ab18b), línea 124 en 19.0 (ce7f5a3) y línea 127 en 20.0 (688d86b)
  • Código del módulo: flexigo_payment_gocardless: controllers/main.py, línea 96 en 20.0 (688d86b)
  • Código del módulo: flexigo_payment_gocardless: models/gocardless_webhook_event.py, línea 7 en 17.0 (d203ee6), 18.0 (e2ab18b), 19.0 (ce7f5a3) y 20.0 (688d86b)
  • Código del módulo: flexigo_payment_gocardless: const.py, línea 117 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 603 en 17.0 (d203ee6), línea 603 en 18.0 (e2ab18b), línea 603 en 19.0 (ce7f5a3) y línea 605 en 20.0 (688d86b)
  • docs.gocardless.com/docs/api-reference/webhooks
  • 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)
  • github.com/odoo/odoo/blob/20.0/addons/payment/i18n/es.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 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)