Saltar al contenido principal

Repositorio de GitHub

Plantilla completa 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.
Esta plantilla utiliza FastAPI con patrones async/await, Pydantic para validación y el dodopayments SDK de Python para una integración de API sin problemas.

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

Clonar el Repositorio

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

Crear Entorno Virtual

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

Instalar Dependencias

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

Obtener Credenciales de API

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

Configurar Variables de Entorno

Crea un .env archivo 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 cometas tu .env archivo en el control de versiones. Ya está incluido en .gitignore.
6

Ejecutar el Servidor de Desarrollo

uvicorn main:app --reload
Abre http://localhost:8000/docs para ver la documentación interactiva de la API!
Deberías ver la interfaz Swagger de FastAPI con todos los puntos finales 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:
Punto finalMétodoDescripción
/checkoutPOSTCrear una nueva sesión de pago
/webhookPOSTManejar webhooks de Dodo Payments
/customer-portalPOSTGenerar URL del portal de clientes

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 ahora está activa
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 desde el panel
  • Actualiza la URL del webhook a tu dominio de producción
  • Habilita HTTPS para todos los puntos finales

Solución de Problemas

Asegúrate de que tu entorno virtual esté activado y 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 incorrecta o configuración de entorno en .env
  • Revisa los registros de FastAPI para mensajes de error detallados
Para pruebas locales, utiliza 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 .env archivo con la clave de verificación de webhook correcta.
  • Asegúrate de que DODO_PAYMENTS_WEBHOOK_KEY esté configurado correctamente en tu .env
  • Verifica que estés usando el cuerpo de la solicitud sin procesar para la verificación de la firma
  • Asegúrate de que estás leyendo correctamente el encabezado webhook-signature

Aprende Más

Soporte

¿Necesitas ayuda con la plantilla?