Skip to main content

GitHub Repository

Código fuente del boilerplate de FastAPI y Dodo Payments.

Descripción general

El boilerplate de FastAPI es un backend de Python con Dodo Payments ya conectado. Incluye endpoints que crean sesiones de checkout y sesiones del Customer Portal, un endpoint de webhook que verifica firmas y una página de precios renderizada con plantillas de Jinja2.
Este boilerplate usa FastAPI con los controladores de rutas async, Pydantic para la validación y la configuración, y el SDK de Python dodopayments. Los controladores llaman al cliente síncrono DodoPayments. Para evitar bloquear el bucle de eventos, cambia a AsyncDodoPayments y await sus llamadas.

Características

El boilerplate incluye:
  • Configuración rápida: pasa de clonar el repositorio a tener un servidor en ejecución en unos cinco minutos.
  • Controladores asíncronos: los controladores de rutas son funciones async def de FastAPI.
  • Sesiones de checkout: un endpoint de checkout preconfigurado que usa el SDK de Python.
  • Gestión de webhooks: un endpoint de webhook que verifica cada firma con el método unwrap del SDK.
  • Customer Portal: un endpoint que crea sesiones del Customer Portal.
  • Seguridad de tipos: los modelos de Pydantic validan los cuerpos de las solicitudes y el código usa sugerencias de tipos.
  • Configuración del entorno: pydantic-settings carga y valida la configuración desde .env.

Requisitos previos

Antes de comenzar, necesitas:
  • Python 3.9 o posterior, que es lo que requiere el SDK dodopayments. Se recomienda Python 3.11 o posterior.
  • pip o uv para la gestión de paquetes.
  • Una cuenta de Dodo Payments, para crear una API key y un secreto de firma de webhook en el dashboard.

Inicio rápido

1

Clone the Repository

2

Create Virtual Environment

Configura un entorno de Python aislado:
También puedes usar uv para gestionar las dependencias más rápidamente:
3

Install Dependencies

O con uv:
4

Get API Credentials

Regístrate en Dodo Payments y obtén tus credenciales desde el dashboard:
Crea ambas mientras el interruptor de Live Mode en la barra lateral esté desactivado. Una clave de modo de prueba solo funciona con DODO_PAYMENTS_ENVIRONMENT=test_mode y los pagos en modo de prueba no mueven dinero real.
5

Configure Environment Variables

Copia el archivo de ejemplo para crear un archivo .env en el directorio raíz:
Establece los valores con tus credenciales de Dodo Payments:
.env
Las cuatro variables son obligatorias. app/core/config.py las carga con pydantic-settings y la aplicación no se inicia si falta alguna o está vacía. DODO_PAYMENTS_RETURN_URL es el lugar al que checkout envía al cliente después del pago.
No confirmes el archivo .env en el control de versiones. El .gitignore del repositorio ya lo excluye.
6

Add Your Products

Sustituye los productos de ejemplo en app/lib/products.py por los tuyos. Establece cada product_id con el ID de un producto en Products en tu dashboard. La página de precios muestra estos productos.
7

Run the Development Server

Abre http://localhost:8000/docs para ver la documentación interactiva de la API.
Swagger UI muestra los endpoints /api/checkout/, /api/webhook/ y /api/customer-portal/, listos para probar.
La URL raíz, http://localhost:8000, sirve la página de precios.
app/main.py llama a templates.TemplateResponse("index.html", {"request": request, ...}), una firma que Starlette 1.x ya no acepta, por lo que la página de precios devuelve un error 500 en una instalación nueva. Para solucionarlo, cambia la llamada a templates.TemplateResponse(request, "index.html", {"products": products}).

Estructura del proyecto

Endpoints de la API

app/main.py monta cada router con un prefijo /api: Cada ruta termina con una barra. FastAPI responde a una solicitud a la ruta sin la barra con una redirección 307, así que usa la ruta exacta, especialmente en la URL de tu webhook.

Ejemplos de código

Estos ejemplos están resumidos a partir de los archivos de app/api/.

Crear una sesión de checkout

app/api/checkout.py crea una sesión de checkout y devuelve su checkout_url. El cuerpo de la solicitud acepta un product_id, un quantity opcional y un objeto customer opcional con name y email:

Gestionar webhooks

app/api/webhook.py verifica la firma con el método unwrap del SDK y, a continuación, distingue según el tipo de evento:

Integración con Customer Portal

app/api/portal.py crea una sesión de Customer Portal para un ID de cliente y devuelve el enlace al portal como url:
La página de precios en app/templates/index.html envía un ID de cliente codificado directamente (cus_001) a este endpoint, y un nombre y correo electrónico codificados directamente al endpoint de checkout. Sustitúyelos por los valores del usuario que ha iniciado sesión.

Eventos de webhook

El controlador en app/api/webhook.py distingue entre estos eventos: Para gestionar otro evento, añade una rama para su tipo, como refund.succeeded para un reembolso procesado correctamente. Consulta todos los tipos de eventos en la guía de eventos de webhook. Añade tu lógica de negocio dentro del controlador del webhook para:
  • Actualizar los permisos de usuario en tu base de datos
  • Enviar correos electrónicos de confirmación
  • Aprovisionar acceso a productos digitales
  • Hacer seguimiento de análisis y métricas

Probar webhooks localmente

Dodo Payments no puede acceder a localhost. Para el desarrollo local, usa una herramienta como ngrok para exponer tu servidor local:
Añade la URL HTTPS de ngrok, seguida de /api/webhook/, como endpoint en tu panel de Dodo Payments:
Copia el secreto de firma del endpoint en DODO_PAYMENTS_WEBHOOK_KEY dentro de .env y reinicia el servidor. La aplicación lee .env únicamente al iniciarse.

Implementación

Docker

El repositorio no incluye un Dockerfile. Para ejecutar la aplicación en un contenedor, añade este Dockerfile a la raíz del repositorio:
COPY . . copia todos los archivos del contexto de compilación, incluido .env. Para mantener tus claves fuera de la imagen, añade un archivo .dockerignore que incluya .env. Después, compila la imagen y ejecútala con tu archivo de entorno:

Consideraciones para producción

Antes de implementar en producción:
  • Cambia DODO_PAYMENTS_ENVIRONMENT a live_mode.
  • Usa una clave de API del modo live del panel.
  • Añade un endpoint de webhook para tu dominio de producción y establece DODO_PAYMENTS_WEBHOOK_KEY en su secreto de firma.
  • Establece DODO_PAYMENTS_RETURN_URL en tu URL de producción.
  • Habilita HTTPS para todos los endpoints.

Solución de problemas

Asegúrate de que tu entorno virtual esté activado y de que las dependencias estén instaladas:
app/main.py sirve archivos estáticos desde app/static, pero el repositorio no incluye ese directorio. Créalo con mkdir app/static y vuelve a iniciar el servidor.
Comprueba estas causas habituales:
  • El ID del producto no existe en tu panel de Dodo Payments.
  • La clave de API o DODO_PAYMENTS_ENVIRONMENT en .env es incorrecta. Una clave del modo de prueba solo funciona con test_mode.
El endpoint devuelve el error del SDK en una respuesta 400. Comprueba los registros de FastAPI para ver mensajes de error detallados.
Para realizar pruebas locales, usa ngrok para exponer tu servidor:
En tu panel de Dodo, añade un endpoint con la URL de ngrok seguida de /api/webhook/, incluida la barra final. Copia el secreto de firma de ese endpoint en DODO_PAYMENTS_WEBHOOK_KEY dentro de tu archivo .env.
  • Asegúrate de que DODO_PAYMENTS_WEBHOOK_KEY en .env coincida con el secreto de firma del endpoint.
  • Verifica la firma con el cuerpo sin procesar de la solicitud, antes de analizarlo como JSON.
  • Pasa los tres encabezados webhook-id, webhook-timestamp y webhook-signature a client.webhooks.unwrap(). La firma de Standard Webhooks cubre id.timestamp.body, no solo el cuerpo.

Más información

Python SDK

Documentación completa del SDK de Python con compatibilidad con async

Webhooks Documentation

Aprende sobre todos los eventos de webhook y las prácticas recomendadas

Checkout Sessions

Análisis detallado de la configuración de la sesión de checkout

API Reference

Documentación completa de la API de Dodo Payments

Soporte

Para obtener ayuda con el boilerplate:
Última modificación el 26 de septiembre de 2026