InicioPago con YapePago con QRPreciosSeguridadDevelopersBlog Ingresar Crear cuenta
Blog / Developers
Developers · 17 oct 2026 · 11 min de lectura · por TAYPI

Cómo integrar pagos QR en Django (Python)

Integra pagos QR en Django paso a paso: endpoint de cobro, render del QR y validación de webhooks.

Integrar pagos QR Django Python es una vía directa para aceptar Yape, Plin y cualquier billetera interoperable en tu e-commerce sin depender de tarjetas ni de validaciones manuales. En esta guía te muestro cómo conectar tu backend Django a una API REST de pagos QR, renderizar el código dinámico y validar automáticamente los cobros con webhooks.

¿Por qué integrar pagos QR en tu e-commerce Django?

En el Perú, los pagos con QR interoperable se han vuelto una alternativa sólida para comercios digitales: eliminan las capturas falsas, reducen el riesgo de contracargos y funcionan directamente sobre la infraestructura del BCRP. Si desarrollas con Django y Python, integrar una pasarela de pagos QR te permite aceptar cobros desde Yape, Plin y cualquier billetera interoperable sin salir del flujo de tu tienda.

La clave está en que no necesitas un SDK oficial de Python. Pasarelas como TAYPI ofrecen SDKs para PHP, JavaScript/TypeScript y .NET, pero en Django se integra consumiendo su API REST directamente. Eso te da control total sobre el flujo y evita depender de librerías externas no oficiales. Además, los QR dinámicos que genera la pasarela expiran en 15 minutos, lo que reduce el riesgo de reutilización y mejora la seguridad de cada transacción.

Antes de entrar al código, conviene revisar qué son los pagos QR interoperables en Perú y cómo la interoperabilidad del BCRP simplifica la conciliación para tu negocio.

Arquitectura de una integración de pagos QR con Django

El flujo típico de pagos QR en Django tiene tres piezas:

  1. Tu servidor Django: expone un endpoint para crear la intención de cobro.
  2. La pasarela de pagos: genera un QR dinámico único con monto fijo y referencia, y devuelve también un checkout_url.
  3. El webhook: la pasarela notifica a tu backend cuando el pago es confirmado, y tu código valida la firma HMAC-SHA256 antes de actualizar la orden.

La comunicación entre Django y la pasarela se hace mediante peticiones POST a un endpoint como /api/v1/payments. Tu backend envía los datos de la orden y recibe como respuesta la imagen del QR (o los datos para renderizarla) y una URL de pago. A partir de ahí, el cliente escanea desde su app de billetera y el comercio espera la confirmación en tiempo real.

Una ventaja importante de este modelo es que no hay saldos atrapados en una app: la liquidación se realiza a tu CCI al día hábil siguiente (T+1). Eso hace que la integración sea especialmente atractiva para e-commerce de ticket bajo y medio que necesitan flujo de caja predecible.

Si prefieres no construir todo desde cero, algunas pasarelas ofrecen módulos listos para WooCommerce, pero en Django el control manual te permite personalizar el flujo al máximo. La documentación para developers de TAYPI describe los endpoints disponibles y los parámetros exactos para este tipo de integración.

Paso 1: Crear el endpoint de cobro con la API REST

Lo primero es crear una vista en Django que reciba los datos de la orden y haga una petición a la API de la pasarela. En este ejemplo usaré requests para hacer la llamada HTTP, pero puedes usar httpx o cualquier biblioteca que prefieras.

Configura las credenciales

En tu archivo settings.py (o mejor, en variables de entorno), guarda las credenciales de la pasarela:

# settings.py
TAYPI_API_URL = "https://api.taypi.pe/v1"
TAYPI_API_KEY = "tu_api_key"
TAYPI_API_SECRET = "tu_api_secret"
TAYPI_WEBHOOK_SECRET = "tu_webhook_secret"

Nunca subas estas claves al repositorio. Usa variables de entorno con python-dotenv o un gestor de secretos.

Crea la vista de cobro

Aquí tienes un ejemplo simplificado de un endpoint crear_pago:

# views.py
import requests
from django.conf import settings
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def crear_pago(request):
    if request.method != "POST":
        return JsonResponse({"error": "Método no permitido"}, status=405)

    data = request.POST  # o json.loads(request.body)
    monto = data.get("monto")
    referencia = data.get("referencia")  # ej: número de pedido

    payload = {
        "amount": monto,
        "currency": "PEN",
        "reference": referencia,
        # otros campos según documentación oficial
    }

    headers = {
        "Authorization": f"Bearer {settings.TAYPI_API_KEY}",
        "Content-Type": "application/json",
    }

    try:
        response = requests.post(
            f"{settings.TAYPI_API_URL}/payments",
            json=payload,
            headers=headers,
            timeout=15,
        )
        response.raise_for_status()
        respuesta = response.json()
    except requests.RequestException as e:
        return JsonResponse({"error": "No se pudo crear el cobro"}, status=502)

    # La respuesta incluye el QR y el checkout_url
    return JsonResponse({
        "qr_data": respuesta.get("qr_data"),      # o la representación que devuelva la API
        "checkout_url": respuesta.get("checkout_url"),
        "payment_id": respuesta.get("id"),
        "expira_en": respuesta.get("expires_at"),
    })

Este endpoint devuelve al frontend los datos necesarios para mostrar el QR. La pasarela asigna un monto fijo y una referencia única a cada cobro, por lo que el QR no se puede reutilizar. El cliente tiene 15 minutos para completar el pago antes de que expire.

Para una integración más robusta, consulta la guía completa de webhooks de pagos en tiempo real y evita duplicar cobros con estrategias de idempotencia.

Paso 2: Renderizar el código QR en tu frontend

Una vez que el backend devuelve los datos del QR, tienes dos opciones para mostrarlo al cliente:

  • Insertar la imagen del QR: si la API devuelve el QR como imagen en base64, puedes incrustarla directamente en un <img>.
  • Redirigir al checkout_url: si prefieres no renderizar el QR en tu propia página, puedes llevar al cliente a la URL de pago de la pasarela.

En una vista Django con plantilla, lo más sencillo es pasar los datos a tu template:

<!-- template/pago.html -->
{% if qr_data %}
  <img src="data:image/png;base64,{{ qr_data }}" alt="Código QR de pago">
  <p>Escanea con Yape, Plin o cualquier billetera interoperable.</p>
  <p>El QR expira en 15 minutos.</p>
{% elif checkout_url %}
  <a href="{{ checkout_url }}" class="btn">Ir a pagar</a>
{% endif %}

Si usas Django REST Framework + un frontend separado (React, Vue, etc.), simplemente consumes el endpoint /crear_pago y muestras el QR con la librería que prefieras. Lo importante es que el QR sea dinámico y de un solo uso. No uses un QR estático: el QR estático no está asociado a un monto fijo y dificulta la conciliación automática.

Una ventaja de integrar pagos QR en Django es que puedes personalizar la experiencia: mostrar el monto exacto, la referencia del pedido y el tiempo restante. Para entender mejor por qué el QR dinámico es más seguro que el estático, revisa las diferencias entre QR estático y QR dinámico EMVCo.

Paso 3: Validar webhooks y firmas HMAC-SHA256

La confirmación del pago no debe depender del frontend. Tu backend debe recibir un webhook de la pasarela cuando el pago es verificado con la entidad financiera. Este webhook es una petición POST a un endpoint tuyo, y es crítico validar su autenticidad.

Cómo verificar la firma HMAC-SHA256 en Python

Cada webhook incluye una firma en el encabezado HTTP (por ejemplo, X-Signature). Para validarla, calculas la firma con tu clave secreta del webhook y la comparas con la enviada:

import hashlib
import hmac

def verificar_firma(payload: bytes, firma_recibida: str, secreto: str) -> bool:
    firma_calculada = hmac.new(
        secreto.encode("utf-8"),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(firma_calculada, firma_recibida)

# En tu vista de webhook
@csrf_exempt
def webhook_pago(request):
    if request.method != "POST":
        return JsonResponse({"error": "Método no permitido"}, status=405)

    payload = request.body
    firma_recibida = request.headers.get("X-Signature", "")

    if not verificar_firma(payload, firma_recibida, settings.TAYPI_WEBHOOK_SECRET):
        return JsonResponse({"error": "Firma inválida"}, status=400)

    data = json.loads(payload)
    # Procesa el evento: pago confirmado, expirado, etc.
    payment_id = data.get("id")
    estado = data.get("status")

    if estado == "confirmed":
        # Marca la orden como pagada en tu base de datos
        # Usa transacciones atómicas y evita duplicados
        actualizar_orden(payment_id, estado)

    return JsonResponse({"ok": True})

Este paso es fundamental para la seguridad: sin verificación de firma, un atacante podría falsificar un webhook y marcar órdenes como pagadas. Si quieres profundizar en la verificación de firmas, te recomiendo cómo verificar firmas HMAC-SHA256 en tu backend.

Además, implementa idempotencia: si la pasarela reintenta el webhook, tu endpoint debe reconocer que ya procesó ese payment_id y no duplicar la actualización. Esto es especialmente relevante en APIs de pago, como se explica en por qué la idempotencia es crítica en APIs de pago.

Consideraciones de seguridad e idempotencia para pagos QR en Django

La seguridad no es opcional cuando manejas dinero en línea. Al integrar pagos QR en Django, asegúrate de cumplir con estos puntos:

  • Usa TLS 1.3 en todas las comunicaciones. Tu servidor y la API de la pasarela deben comunicarse cifrados.
  • Activa la idempotencia. Cada solicitud de cobro debe tener un identificador único (por ejemplo, el número de orden). Si el cliente hace doble clic, no se crean dos cobros.
  • Valida siempre los webhooks con HMAC-SHA256. Nunca confíes en el cuerpo del mensaje sin verificar la firma.
  • Maneja los estados correctamente. Un pago puede estar pendiente, confirmado, expirado o fallido. Actualiza tu base de datos solo con eventos confirmados.
  • Prueba en sandbox. Antes de ir a producción, usa las claves de sandbox de la pasarela para simular transacciones y webhooks.

En el contexto peruano, es importante que la pasarela cumpla con la normativa PLAFT y opere sobre la infraestructura supervisada por la SBS. TAYPI opera sobre la interoperabilidad del BCRP vía CCE y cuenta con certificaciones ISO 27001:2022 e ISO 9001:2015, lo que refuerza la seguridad de la integración. Puedes revisar más detalles en seguridad de TAYPI.

También considera que los QR dinámicos de la pasarela expiran en 15 minutos; esto reduce el riesgo de que un código sea usado más de una vez. Si el cliente no paga dentro de ese plazo, puedes generar un nuevo cobro con la misma referencia, pero nunca reutilices el mismo QR.

¿Cuánto cuesta integrar pagos QR en Django?

El costo de integración depende de tu propia inversión en desarrollo, pero el costo por transacción lo define la pasarela. Al momento de elegir, compara comisiones y características reales.

CriterioIntegración API REST (Django)Módulos o plugins listos
Requiere desarrolloSí, en Python/DjangoNo, se instala y configura
PersonalizaciónAltaLimitada
SDK oficial para PythonNo siempre disponible, se usa API RESTNo aplica
Tiempo típico de integraciónAlrededor de un díaHoras
MantenimientoDepende de tu equipoDelegado al proveedor

En el caso de TAYPI, la comisión es 2.50% + S/ 0.20 + IGV por cobro confirmado. Para un cobro de S/ 100, la comisión total es S/ 3.19 y recibes S/ 96.81. No hay costo de instalación, mensualidad ni permanencia. Si quieres ver el detalle completo, consulta los precios de TAYPI.

La elección entre una integración pura de API y un plugin dependerá de tu stack. Si ya usas Django, la API REST te da más flexibilidad y control. Si usas WooCommerce, quizá prefieras un módulo oficial. Lo importante es que la pasarela valide el pago directamente con la entidad financiera, no con capturas, y que la liquidación sea a tu CCI al día siguiente.

Preguntas frecuentes

¿Necesito un SDK de Python para integrar pagos QR en Django?

No. Puedes integrar pagos QR en Django consumiendo la API REST de la pasarela directamente con bibliotecas como requests o httpx. TAYPI no tiene SDK oficial de Python, pero su API REST está documentada y permite crear cobros, obtener el QR y recibir webhooks.

¿Cómo verifico que un pago con QR fue realmente recibido?

La verificación se hace mediante webhooks en tiempo real. La pasarela envía una notificación a tu backend cuando confirma el pago con la entidad financiera. Debes validar la firma HMAC-SHA256 para garantizar que el webhook es auténtico y actualizar tu orden solo en ese momento.

¿Cuánto tiempo expira un QR dinámico de pago?

En el caso de TAYPI, cada QR dinámico único expira en 15 minutos. Si el cliente no completa el pago dentro de ese plazo, debes generar un nuevo cobro con una nueva referencia y QR.

¿Puedo probar la integración antes de ir a producción?

Sí. Las pasarelas suelen ofrecer claves de sandbox para simular transacciones y webhooks sin mover dinero real. Úsalas para probar el flujo completo: creación de cobro, render del QR y validación de webhooks.

¿Qué pasa si mi servidor no está disponible cuando llega un webhook?

Las pasarelas suelen reintentar el envío del webhook varias veces. Por eso es clave implementar idempotencia en tu endpoint: si recibes el mismo evento más de una vez, tu sistema debe reconocerlo y no duplicar la actualización de la orden.

Conclusión

Integrar pagos QR Django Python es una tarea directa si aprovechas la API REST de una pasarela confiable. El flujo se resume en tres pasos: crear un endpoint de cobro, renderizar el QR dinámico y validar webhooks con HMAC-SHA256. Con esto, tu e-commerce puede aceptar Yape, Plin y cualquier billetera interoperable de forma automática, sin capturas manuales ni contracargos.

Si buscas una opción que se adapte a este flujo, TAYPI ofrece una API REST pensada para desarrolladores, liquidación T+1 a tu CCI y seguridad basada en idempotencia y firmas. Para empezar, revisa la documentación para developers de TAYPI y crea tu cuenta de prueba hoy.


Si estás listo para integrar pagos QR en tu proyecto Django, crea tu cuenta gratis en TAYPI y accede a la API REST, claves de sandbox y documentación técnica para comenzar.

¿Listo para cobrar con QR?

Crea tu cuenta gratis y genera tu primer QR en minutos.

Abrir cuenta gratis