tefpay-integration
v1.0.1
Published
Integración universal, robusta y minimalista de pagos y suscripciones TEFPAY para React, Express, Next.js, Fastify, Koa y NestJS. Centraliza la gestión, validación y notificaciones automáticas en un solo punto, con lógica profesional, cobertura de tests y
Maintainers
Readme
Tefpay Integration
Integración universal, robusta y minimalista de pagos y suscripciones TEFPAY para React, Express, Fastify, Koa y NestJS.
Índice
Tefpay Integration
Características Destacadas
- Universal: Compatibilidad con React, Express, Fastify, Koa y NestJS.
- Minimalista: Fácil integración con mínima configuración.
- Robusta y Segura: Validación automática de firmas, campos y tipos de transacción.
- Completa: Manejo de pagos, suscripciones y sus notificaciones asociadas (altas, bajas, cobros, devoluciones, etc.).
- Herramientas para Frontend: Hooks React para una experiencia de usuario fluida.
- Tests End-to-End: Cobertura exhaustiva para una integración confiable.
Quick Start
1. Instalación del paquete
pnpm add tefpay-integration
# o
npm install tefpay-integration
# o
yarn add tefpay-integration2. Instalación de Peer Dependencies
El paquete requiere que tengas instaladas las peerDependencies de tu framework. Instala las recomendadas según tu stack:
- React:
pnpm add react(para hooks frontend) - Express:
pnpm add express - Fastify:
pnpm add fastify - Koa:
pnpm add koa koa-bodyparser - NestJS:
pnpm add @nestjs/common @nestjs/core
Compatibilidad:
- React
>= 18.x- Express
>= 4.x- Fastify
>= 4.x- Koa
>= 3.x- NestJS
>= 9.x
3. Crear tu endpoint de notificaciones (Backend Obligatorio)
Tefpay envía notificaciones automáticas a tu backend tras cada acción. El uso de handleTefpayNotification o sus adaptadores específicos es obligatorio para procesar correctamente el flujo de suscripciones y pagos. Consulta la sección detallada a continuación para ejemplos específicos.
4. (Opcional) Integrar Hooks visuales en React
import { useTefpaySubscriptionAction, TefpayClient } from "tefpay-integration";
// ...ver ejemplo completo en la sección "Hooks y Utilidades Frontend"5. Ejecuta los tests para validar tu integración
pnpm test -- --coverageManejo de Notificaciones (Backend Obligatorio)
El paquete ofrece adaptadores específicos para cada framework que simplifican la integración. Todos ellos utilizan internamente handleTefpayNotification para procesar el cuerpo de la solicitud, validar la firma y ejecutar tu callback personalizado.
ROBUSTEZ Y SEGURIDAD:
- Validación automática: El paquete valida el tamaño del body, la presencia de campos obligatorios, la firma y el tipo de transacción soportado en cada notificación.
- Endpoint HTTPS: Expón el endpoint de notificaciones solo por HTTPS.
- No procesar: Nunca proceses notificaciones si la firma es inválida o faltan datos críticos.
- Restricción IP: Limita el acceso al endpoint solo a IPs de Tefpay si es posible, o monitoriza intentos sospechosos.
- Logging: Registra todos los eventos y errores en logs persistentes para auditoría y trazabilidad.
- Información sensible: No devuelvas información sensible en la respuesta del endpoint.
- Clave Secreta: Revisa y actualiza la clave secreta periódicamente y almacénala solo en variables de entorno seguras (
process.env.TEFPAY_SECRET_KEY).- Validar Eventos: Valida siempre el
eventy losdatarecibidos antes de ejecutar cualquier acción en tu backend.- Middlewares de Seguridad: Considera usar middlewares adicionales de validación (rate limiting, body size, CORS estricto) en el endpoint de notificaciones.
Next.js (App Router)
Utiliza tefpayNextHandler en un Route Handler.
// app/api/tefpay-notify/route.ts
import { tefpayNextHandler } from "tefpay-integration/dist/adapters/next-adapter";
import { NextRequest, NextResponse } from "next/server";
export async function POST(req: NextRequest) {
try {
const result = await tefpayNextHandler(
req,
NextResponse, // Pasa NextResponse para la gestión de respuesta
process.env.TEFPAY_SECRET_KEY!,
async (data) => {
// --- Lógica de procesamiento de notificación ---
// 'data' contendrá los campos procesados (event, status, email, account, etc.)
if (
data.event === "subscription_activated" &&
data.status === "active"
) {
// Actualiza la suscripción en BD, envía email, etc.
return { success: true, action: "activate_subscription", ...data };
}
if (data.event === "charge_attempt_failed") {
// Registrar el fallo, enviar alerta, etc.
return { success: false, action: "charge_failed", ...data };
}
if (
data.event === "subscription_suspended" &&
data.status === "suspended"
) {
// Suspender la suscripción en BD
return { success: true, action: "suspend_subscription", ...data };
}
// Otros casos...
return { success: false, action: "unknown", ...data };
}
);
return NextResponse.json(result, { status: 200 });
} catch (err: any) {
return NextResponse.json({ error: err.message }, { status: 400 });
}
}Express
Utiliza tefpayExpressMiddleware como middleware de ruta. Asegúrate de tener express.json() o body-parser configurado.
// app.ts (o archivo de ruta)
import express from "express";
import { tefpayExpressMiddleware } from "tefpay-integration/dist/adapters/express-adapter";
const app = express();
app.use(express.json()); // Necesario para parsear el body JSON
app.post(
"/api/tefpay-notify",
tefpayExpressMiddleware(process.env.TEFPAY_SECRET_KEY!, async (data) => {
// Procesa la notificación en tu backend
return { status: "ok", ...data };
})
);
app.listen(3000, () => console.log("Express running on port 3000"));Fastify
Utiliza tefpayFastifyHandler como handler de ruta. Fastify parsea el body JSON por defecto.
// app.ts (o archivo de ruta)
import Fastify from "fastify";
import { tefpayFastifyHandler } from "tefpay-integration/dist/adapters/fastify-adapter";
const fastify = Fastify();
fastify.post(
"/api/tefpay-notify",
tefpayFastifyHandler(process.env.TEFPAY_SECRET_KEY!, async (data) => {
// Procesa la notificación en tu backend
return { status: "ok", ...data };
})
);
fastify.listen({ port: 3000 }, (err, address) => {
if (err) throw err;
console.log(`Fastify running on ${address}`);
});Koa
Utiliza tefpayKoaMiddleware como middleware de aplicación. Requiere koa-bodyparser.
// app.ts (o archivo de ruta)
import Koa from "koa";
import bodyParser from "koa-bodyparser";
import { tefpayKoaMiddleware } from "tefpay-integration/dist/adapters/koa-adapter";
const app = new Koa();
app.use(bodyParser()); // Necesario para parsear el body JSON
app.use(
tefpayKoaMiddleware(process.env.TEFPAY_SECRET_KEY!, async (data) => {
// Procesa la notificación en tu backend
return { status: "ok", ...data };
})
);
app.listen(3000, () => console.log("Koa running on port 3000"));NestJS
Utiliza tefpayNestHandler dentro de un controlador. Asegúrate de que NestJS esté configurado para usar Fastify o Express como motor subyacente (ambos son compatibles).
// src/tefpay/tefpay.controller.ts
import { Controller, Post, Req, Res } from "@nestjs/common";
import { Request, Response } from "express"; // O FastifyRequest, FastifyReply si usas Fastify
import { tefpayNestHandler } from "tefpay-integration/dist/adapters/nest-adapter";
@Controller("tefpay")
export class TefpayController {
@Post("notify") // Endpoint final: /tefpay/notify
async handleNotification(@Req() req: Request, @Res() res: Response) {
await tefpayNestHandler(
req,
res,
process.env.TEFPAY_SECRET_KEY!,
async (data) => {
// Procesa la notificación en tu backend
return { status: "ok", ...data };
}
);
}
}Adaptadores Multiplataforma
Los adaptadores son el puente entre tu framework y la lógica central de tefpay-integration.
Se encuentran en
dist/adapterstras la compilación. Importa desde:tefpay-integration/dist/adapters/<nombre-adapter>
tefpay-integration/dist/adapters/next-adaptertefpay-integration/dist/adapters/express-adaptertefpay-integration/dist/adapters/fastify-adaptertefpay-integration/dist/adapters/koa-adaptertefpay-integration/dist/adapters/nest-adapter
Hooks y Utilidades Frontend (React)
Este paquete también incluye herramientas para simplificar la integración frontend en React.
useTefpaySubscriptionAction: Hook React para gestionar acciones relacionadas con suscripciones (ej. mostrar un formulario de pago, gestionar redirecciones).TefpayPayment: Clase utilitaria para generar formularios de pago y manejar la interacción con la pasarela de Tefpay.
Ejemplo básico de useTefpaySubscriptionAction:
// components/SubscriptionButton.tsx
import React from "react";
import { useTefpaySubscriptionAction, TefpayClient } from "tefpay-integration";
interface SubscriptionButtonProps {
userId: string;
planId: string;
}
const TefpayClientInstance = new TefpayClient({
merchantCode: process.env.NEXT_PUBLIC_TEFPAY_MERCHANT_CODE!,
terminal: process.env.NEXT_PUBLIC_TEFPAY_TERMINAL!,
apiUrl: process.env.NEXT_PUBLIC_TEFPAY_API_URL!,
});
const SubscriptionButton: React.FC<SubscriptionButtonProps> = ({
userId,
planId,
}) => {
const { initiateAction, isLoading, error } =
useTefpaySubscriptionAction(TefpayClientInstance);
const handleSubscribe = async () => {
try {
// Aquí se simula la obtención de la URL de pago desde tu backend
// En una aplicación real, tu backend generaría esta URL de Tefpay
// basándose en userId, planId, y otros datos de la suscripción.
const response = await fetch("/api/create-tefpay-payment", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ userId, planId }),
});
const { paymentUrl } = await response.json();
if (paymentUrl) {
// Redirige al usuario al formulario de pago de Tefpay
initiateAction(paymentUrl);
} else {
throw new Error("No se pudo obtener la URL de pago de Tefpay.");
}
} catch (err) {
console.error("Error al iniciar suscripción:", err);
}
};
return (
<div>
<button onClick={handleSubscribe} disabled={isLoading}>
{isLoading ? "Cargando..." : "Suscribirse Ahora"}
</button>
{error && <p style={{ color: "red" }}>Error: {error.message}</p>}
</div>
);
};
export default SubscriptionButton;Cobertura y Robustez de Tests
El paquete incluye tests unitarios y de integración end-to-end (e2e) para todos los adaptadores principales, asegurando la robustez y el correcto funcionamiento en diferentes entornos.
- Express:
test/e2e/tefpay-e2e-express.test.ts - Fastify:
test/e2e/tefpay-e2e-fastify.test.ts - Koa:
test/e2e/tefpay-e2e-koa.test.ts - NestJS:
test/e2e/tefpay-e2e-nest.test.ts - Next.js: (
test/e2e/tefpay-e2e-next.test.ts) - Requiere Next.js comodevDependencyy un entorno Next real para su ejecución.
Para cada framework, existe un test equivalente que valida el flujo completo, la robustez de la integración y el manejo de errores.
Preguntas Frecuentes (FAQ)
¿Por qué es obligatorio el uso de un backend para handleTefpayNotification?
Tefpay opera enviando notificaciones asíncronas a un endpoint de tu servidor. Procesar estas notificaciones es esencial para actualizar el estado de las suscripciones y pagos en tu base de datos y gestionar el ciclo de vida del usuario. Sin este procesamiento backend, tu integración no puede funcionar correctamente ni de forma segura.
¿Puedo usar el paquete solo en frontend?
No. Aunque se proporcionan hooks y utilidades para React, la parte crítica de la integración con Tefpay (validación de notificaciones y actualización de estados) debe residir en tu backend para garantizar seguridad y fiabilidad.
¿Qué hago si la firma de la notificación es inválida?
Si el paquete reporta una firma inválida, los pasos a seguir son:
- Verificar
TEFPAY_SECRET_KEY: Asegúrate de que la clave secreta configurada en tuprocess.env.TEFPAY_SECRET_KEYsea idéntica a la que tienes en tu panel de Tefpay. Un solo carácter diferente causará un fallo. - Confirmar Body Parser: Asegúrate de que tu framework (Express, Fastify, Koa, NestJS) esté parseando correctamente el cuerpo de la solicitud JSON antes de pasarla al adaptador de Tefpay.
- Depuración: Activa los logs detallados para ver los datos exactos que está recibiendo tu endpoint y cómo se está calculando la firma.
¿Cómo depuro errores de integración?
- Logs en tu Backend: Implementa logging exhaustivo en tu
callbacky alrededor del manejador de notificaciones. - Documentación Técnica: Consulta la documentación técnica detallada de Tefpay sobre el formato de las notificaciones.
- Tests Incluidos: Utiliza los tests
e2eprovistos en el paquete para simular notificaciones y verificar el comportamiento. - Entorno de Desarrollo: Realiza pruebas en un entorno de desarrollo donde puedas examinar las solicitudes entrantes y salientes.
¿Por qué no hay un test de Next.js "estándar"?
Los tests de Next.js requieren la ejecución dentro de un contexto de Next.js real o con next instalado como devDependency. Debido a la naturaleza del entorno de pruebas, no se incluye un test e2e de Next.js en la ejecución principal, pero se recomienda crearlos y ejecutarlos dentro de un proyecto Next.js.
Solución de Problemas Comunes
- Error de firma inválida: Clave secreta incorrecta o cuerpo de la solicitud modificado.
- Solución: Verifica tu
TEFPAY_SECRET_KEYy asegúrate de que tubody-parser(o equivalente) esté configurado correctamente.
- Solución: Verifica tu
- No llegan notificaciones: El endpoint no está expuesto correctamente o Tefpay no tiene la URL configurada.
- Solución: Confirma que tu servidor esté escuchando en la URL correcta y que esa URL esté registrada en tu panel de control de Tefpay. Verifica que no haya firewalls bloqueando las solicitudes de Tefpay.
- Error en adaptadores al importar: Problemas con la ruta de importación o el proceso de transpilación.
- Solución: Asegúrate de importar desde
tefpay-integration/dist/adapters/<nombre-adapter>después de que el paquete ha sido compilado.
- Solución: Asegúrate de importar desde
- Problemas con
peerDependencies: El paquete no encuentra las dependencias necesarias de tu framework.- Solución: Instala las versiones recomendadas de React, Express, Fastify, Koa y NestJS.
- Tests de Next.js no ejecutan: No hay un entorno Next.js disponible.
- Solución: Ejecuta los tests de Next.js solo en proyectos Next.js reales donde
nextesté instalado.
- Solución: Ejecuta los tests de Next.js solo en proyectos Next.js reales donde
Diagrama de Flujo de Integración
flowchart TD
A[Frontend: React/Next.js (App)] -->|1. Iniciar Pago/Suscripción| B(Tu Backend: Express/Fastify/Koa/NestJS)
B -->|2. Generar Solicitud de Pago| C(Servidor TEFPAY)
C -->|3. Redirección al Formulario de Pago| A
A -->|4. Usuario Completa Pago| C
C -->|5. Notificación Automática (Webhook)| B
B -->|6. Adaptador TEFPAY (handleTefpayNotification)| D{Validación de Firma y Datos}
D -- "Firma OK" --> E[7. Callback Personalizado: Procesa Evento, Actualiza BD]
D -- "Firma Inválida" --> F[7. Error: Registra y Responde 400]
E -->|8. Respuesta HTTP 200| C
F -->|8. Respuesta HTTP 400| C
E -->|9. Notificar Frontend (Opcional: Websockets, Refetch)| ADocumentación Avanzada
Para casos de uso complejos, configuraciones detalladas, variantes específicas y preguntas adicionales, consulta la documentación extendida:
Soporte
Si tienes dudas sobre la configuración de tu cuenta Tefpay, el proceso de activación de notificaciones o el flujo transaccional específico de Tefpay, por favor, revisa su documentación oficial y contacta directamente al equipo de soporte de Tefpay.
Para consultas relacionadas con la implementación de tefpay-integration en tu código, problemas con los adaptadores, o sugerencias de mejora del paquete, abre un issue en nuestro repositorio de GitHub.
