Guía para desplegar una API REST con Flask en Heroku y añadir un plan de pago
En este artículo encontrarás un recorrido detallado y muy extenso para crear y desplegar una API RESTful con Flask, alojarla en Heroku y añadir un sistema de plan de pago usando Stripe. Se incluyen ejemplos de código, configuración, comandos y buenas prácticas.
Índice de contenidos
- Requisitos previos
- Estructura del proyecto
- Configuración del entorno virtual
- Desarrollo de la API con Flask
- Preparativos para Heroku (Procfile, requirements.txt)
- Despliegue en Heroku
- Configuración de la base de datos en Heroku
- Integración de Stripe para planes de pago
- Gestión de suscripciones y webhooks
- Pruebas y monitoreo
- Conclusiones y recomendaciones
1. Requisitos previos
Antes de empezar, asegúrate de contar con:
- Una cuenta en Heroku.
- Heroku CLI instalado (
heroku --version). - Cuenta y credenciales de Stripe (para pagos).
- Python 3.7 instalado y
pip. - Git instalado y básico conocimiento de control de versiones.
2. Estructura del proyecto
Organizaremos el proyecto con este esquema:
- app.py – Archivo principal con la aplicación Flask.
- config.py – Configuraciones generales.
- requirements.txt – Dependencias.
- Procfile – Comando para Heroku.
- routes/ – Módulo con rutas de la API.
- models/ – Definiciones de modelos (SQLAlchemy).
- static/ y templates/ – (Opcional).
3. Configuración del entorno virtual
Creamos y activamos un entorno virtual para aislar dependencias:
source venv/bin/activate
Instalamos las librerías base:
4. Desarrollo de la API con Flask
4.1 app.py
from flask_sqlalchemy import SQLAlchemy
from stripe import StripeError, api_key, Subscription, Customer, Plan
import os
app = Flask(__name__)
app.config.from_object(config.DevelopmentConfig)
db = SQLAlchemy(app)
api_key = os.getenv(STRIPE_SECRET_KEY)
@app.route(/ping)
def ping():
return jsonify({message:pong})
# Rutas de CRUD y suscripciones…
if __name__ == __main__:
app.run()
4.2 config.py
class BaseConfig:
SQLALCHEMY_TRACK_MODIFICATIONS = False
STRIPE_SECRET_KEY = os.getenv(STRIPE_SECRET_KEY)
STRIPE_PUBLISHABLE_KEY = os.getenv(STRIPE_PUBLISHABLE_KEY)
class DevelopmentConfig(BaseConfig):
DEBUG = True
SQLALCHEMY_DATABASE_URI = os.getenv(DATABASE_URL, sqlite:///dev.db)
class ProductionConfig(BaseConfig):
DEBUG = False
SQLALCHEMY_DATABASE_URI = os.getenv(DATABASE_URL)
5. Preparativos para Heroku
5.1 requirements.txt
Genera este archivo:
Flask-RESTful==0.3.9
Flask-SQLAlchemy==2.5.1
gunicorn==20.1.0
stripe==2.60.0
python-dotenv==0.19.0
5.2 Procfile
6. Despliegue en Heroku
Ejecuta los siguientes pasos:
- Inicializa git:
git init. - Agrega todos los archivos:
git add .. - Commit:
git commit -m Inicial API Flask. - Crea la app en Heroku:
heroku create nombre-app. - Configura buildpacks (opcional):
heroku buildpacks:set heroku/python. - Empuja al remoto:
git push heroku main(omaster).
7. Configuración de la base de datos en Heroku
Agrega el addon de Postgres:
Obten la URI y ejecútala localmente:
Para crear tablas:
8. Integración de Stripe para planes de pago
Para ofrecer un plan de pago, usaremos Stripe Subscriptions. Esquema:
- Define planes en el dashboard de Stripe (precio, intervalo).
- Crea clientes y suscripciones vía API.
- Gestiona actualizaciones y cancelaciones.
8.1 Creación de planes en Stripe
En Dashboard ➔ Productos, crea un producto y asigna precios recurrentes (mensual/anual).
| ID del Plan | Precio | Intervalo |
|---|---|---|
| plan_monthly_001 | 10.00 | Mensual |
| plan_yearly_001 | 100.00 | Anual |
8.2 Rutas para suscripción
Añadimos en routes/subscription.py:
import stripe, os
stripe.api_key = os.getenv(STRIPE_SECRET_KEY)
sub_bp = Blueprint(subscription, __name__)
@sub_bp.route(/subscribe, methods=[POST])
def subscribe():
data = request.json
try:
customer = stripe.Customer.create(email=data[email])
subscription = stripe.Subscription.create(
customer=customer.id,
items=[{plan: data[plan_id]}],
expand=[latest_invoice.payment_intent]
)
return jsonify(subscription), 200
except stripe.error.StripeError as e:
return jsonify({error: str(e)}), 400
9. Gestión de suscripciones y webhooks
Para reaccionar a eventos (pagos exitosos, renovaciones, cancelaciones) registramos un webhook:
- En Stripe Dashboard ➔ Developers ➔ Webhooks, crea un endpoint:
https://tu-app.herokuapp.com/webhook. - Define eventos:
invoice.payment_succeeded,customer.subscription.deleted, etc. - Implementa ruta:
def stripe_webhook():
payload = request.data
sig_header = request.headers.get(Stripe-Signature)
endpoint_secret = os.getenv(STRIPE_WEBHOOK_SECRET)
try:
event = stripe.Webhook.construct_event(payload, sig_header, endpoint_secret)
except ValueError:
return , 400
except stripe.error.SignatureVerificationError:
return , 400
# Procesar evento
if event[type] == invoice.payment_succeeded:
# Actualizar estado de usuario
pass
return , 200
10. Pruebas y monitoreo
- Pruebas unitarias con pytest o unittest.
- Usar Stripe Test keys y tarjetas de prueba.
- Habilitar Heroku Logs:
heroku logs --tail. - Monitoreo con New Relic o Logentries.
- Configurar alertas de fallos y latencia.
11. Conclusiones y recomendaciones
En esta guía has visto desde la creación básica de una API RESTful con Flask hasta su despliegue en Heroku y la incorporación de un sistema de suscripción con Stripe. Los pasos clave incluyen:
- Separación limpia de configuración y código.
- Uso de entorno virtual y
python-dotenv. - Definición adecuada de
Procfiley dependencias. - Gestión de variables de entorno en Heroku.
- Implementación de webhooks para mantener coherencia de estado.
- Pruebas con entornos de desarrollo y test de Stripe.
Para llevarlo al siguiente nivel, considera:
- Implementar Autenticación JWT para proteger rutas.
- Documentar la API con OpenAPI/Swagger.
- Usar contenedores Docker para entornos reproducibles.
- Configurar CI/CD con GitHub Actions o GitLab CI.
Con estos elementos, tendrás una API robusta, escalable y lista para gestionar planes de pago de forma segura y profesional.
Leave a Reply