Saltar al contenido principal

GitHub Repository

Completa el boilerplate de FastAPI + Dodo Payments

Descripción general

La plantilla de FastAPI proporciona un punto de partida listo para producción para integrar Dodo Payments con tu backend de Python. Esta plantilla incluye manejo de sesiones de pago, verificación de webhooks, integración de portal de clientes y patrones de API asíncronos para ayudarte a comenzar a aceptar pagos rápidamente.
Este boilerplate utiliza FastAPI con patrones async/await, Pydantic para la validación y el dodopayments SDK de Python para una integración fluida con la API.

Características

  • Configuración rápida - Comienza en menos de 5 minutos
  • Soporte asíncrono - Construido con los patrones nativos async/await de FastAPI
  • Sesiones de pago - Flujo de pago preconfigurado utilizando el SDK de Python
  • Manejo de webhooks - Punto final de webhook seguro con verificación de firma
  • Portal de clientes - Creación fácil de sesiones del portal de clientes
  • Seguridad de tipos - Validación completa de Pydantic y sugerencias de tipo
  • Configuración del entorno - Configuración de variables de entorno lista para usar

Requisitos previos

Antes de comenzar, asegúrate de tener:
  • Python 3.9+ (recomendado: Python 3.11+)
  • pip o uv para la gestión de paquetes
  • Cuenta de Dodo Payments (para acceder a las claves de API y Webhook desde el panel)

Inicio rápido

1

Clone the Repository

git clone https://github.com/dodopayments/fastapi-boilerplate.git
cd fastapi-boilerplate
2

Create Virtual Environment

Configura un entorno de Python aislado:
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
O usando uv para una gestión de dependencias más rápida:
uv venv
source .venv/bin/activate
3

Install Dependencies

pip install -r requirements.txt
O con uv:
uv pip install -r requirements.txt
4

Get API Credentials

Regístrate en Dodo Payments y obtén tus credenciales desde el panel:
¡Asegúrate de estar en Modo de Prueba mientras desarrollas!
5

Configure Environment Variables

Crea un archivo .env en el directorio raíz:
cp .env.example .env
Actualiza los valores con tus credenciales de Dodo Payments:
.env
DODO_PAYMENTS_API_KEY=your_api_key_here
DODO_PAYMENTS_WEBHOOK_KEY=your_webhook_signing_key_here
DODO_PAYMENTS_ENVIRONMENT=test_mode
Nunca subas tu archivo .env al control de versiones. Ya está incluido en .gitignore.
6

Run the Development Server

uvicorn main:app --reload
Abre http://localhost:8000/docs para ver la documentación interactiva de la API!
Deberías ver la interfaz Swagger UI de FastAPI con todos los endpoints disponibles listos para probar.

Estructura del Proyecto

fastapi-boilerplate/
├── main.py                 # FastAPI application entry point
├── routers/
│   ├── checkout.py         # Checkout session endpoints
│   ├── webhook.py          # Webhook handler endpoint
│   └── customer_portal.py  # Customer portal endpoints
├── config.py               # Environment configuration
├── requirements.txt        # Python dependencies
├── .env.example            # Environment template
└── README.md

Puntos finales de la API

La plantilla incluye los siguientes puntos finales preconfigurados:
EndpointMétodoDescripción
/checkoutPOSTCrear una nueva sesión de pago
/webhookPOSTProcesar webhooks de Dodo Payments
/customer-portalPOSTGenerar URL del portal del cliente

Ejemplos de Código

Creando una Sesión de Pago

from fastapi import APIRouter, HTTPException
from dodopayments import AsyncDodoPayments
from pydantic import BaseModel
from config import settings

router = APIRouter()
dodo = AsyncDodoPayments(
    bearer_token=settings.DODO_PAYMENTS_API_KEY,
    environment=settings.DODO_PAYMENTS_ENVIRONMENT
)

class CheckoutRequest(BaseModel):
    product_id: str
    quantity: int = 1
    customer_email: str | None = None
    customer_name: str | None = None

@router.post("/checkout")
async def create_checkout(request: CheckoutRequest):
    try:
        session = await dodo.checkout_sessions.create(
            product_cart=[{
                "product_id": request.product_id,
                "quantity": request.quantity
            }],
            customer={
                "email": request.customer_email,
                "name": request.customer_name
            } if request.customer_email else None,
            return_url="http://localhost:8000/success"
        )
        return {"checkout_url": session.url, "session_id": session.session_id}
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))

Manejo de Webhooks

from fastapi import APIRouter, Request, HTTPException
import hmac
import hashlib
from config import settings

router = APIRouter()

def verify_webhook_signature(payload: bytes, signature: str) -> bool:
    expected = hmac.new(
        settings.DODO_PAYMENTS_WEBHOOK_KEY.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

@router.post("/webhook")
async def handle_webhook(request: Request):
    payload = await request.body()
    signature = request.headers.get("webhook-signature", "")
    
    if not verify_webhook_signature(payload, signature):
        raise HTTPException(status_code=401, detail="Invalid signature")
    
    event = await request.json()
    event_type = event.get("type")
    
    match event_type:
        case "payment.succeeded":
            # Handle successful payment
            payment_id = event["data"]["payment_id"]
            print(f"Payment succeeded: {payment_id}")
            
        case "subscription.active":
            # Handle subscription activation
            subscription_id = event["data"]["subscription_id"]
            print(f"Subscription activated: {subscription_id}")
            
        case "refund.succeeded":
            # Handle refund
            refund_id = event["data"]["refund_id"]
            print(f"Refund processed: {refund_id}")
    
    return {"status": "received"}

Integración del Portal de Clientes

from fastapi import APIRouter, HTTPException
from dodopayments import AsyncDodoPayments
from pydantic import BaseModel
from config import settings

router = APIRouter()
dodo = AsyncDodoPayments(
    bearer_token=settings.DODO_PAYMENTS_API_KEY,
    environment=settings.DODO_PAYMENTS_ENVIRONMENT
)

class PortalRequest(BaseModel):
    customer_id: str

@router.post("/customer-portal")
async def create_portal_session(request: PortalRequest):
    try:
        session = await dodo.customers.create_customer_portal(
            customer_id=request.customer_id
        )
        return {"portal_url": session.url}
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))

Eventos de Webhook

La plantilla demuestra el manejo de eventos comunes de webhook:
EventoDescripción
payment.succeededPago completado con éxito
payment.failedIntento de pago fallido
subscription.activeLa suscripción está activa ahora
subscription.cancelledLa suscripción fue cancelada
refund.succeededReembolso procesado con éxito
Agrega tu lógica de negocio dentro del manejador de webhook para:
  • Actualizar permisos de usuario en tu base de datos
  • Enviar correos electrónicos de confirmación
  • Proveer acceso a productos digitales
  • Rastrear análisis y métricas

Pruebas de Webhooks Localmente

Para el desarrollo local, utiliza herramientas como ngrok para exponer tu servidor local:
ngrok http 8000
Actualiza la URL del webhook en tu Panel de Dodo Payments:
https://your-ngrok-url.ngrok.io/webhook

Despliegue

Docker

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Construir y ejecutar:
docker build -t fastapi-dodo .
docker run -p 8000:8000 --env-file .env fastapi-dodo

Consideraciones de Producción

Antes de desplegar en producción:
  • Cambia DODO_PAYMENTS_ENVIRONMENT a live_mode
  • Usa claves de API de producción del panel
  • Actualiza la URL del webhook a tu dominio de producción
  • Habilita HTTPS para todos los endpoints

Solución de Problemas

Asegúrate de que tu entorno virtual esté activado y que las dependencias estén instaladas:
source venv/bin/activate
pip install -r requirements.txt
Causas comunes:
  • ID de producto inválido: verifica que exista en tu panel de Dodo
  • Clave de API o configuración de entorno incorrecta en .env
  • Revisa los registros de FastAPI para obtener mensajes de error detallados
Para pruebas locales, usa ngrok para exponer tu servidor:
ngrok http 8000
Actualiza la URL del webhook en tu panel de Dodo a la URL de ngrok. Asegúrate de actualizar tu archivo .env con la clave correcta de verificación del webhook.
  • Asegúrate de que DODO_PAYMENTS_WEBHOOK_KEY esté configurado correctamente en tu .env
  • Verifica que estés usando el cuerpo de solicitud sin procesar para la verificación de la firma
  • Comprueba que estés leyendo correctamente el encabezado webhook-signature

Aprende Más

Soporte

¿Necesitas ayuda con la plantilla?