PagaloSeguro es un laboratorio de integración de pagos desarrollado para practicar y validar el flujo completo de una pasarela de pago en una arquitectura web moderna. El proyecto permite crear órdenes de pago, redirigir al usuario a Mercado Pago Checkout Pro en modo sandbox, recibir eventos mediante webhooks, actualizar el estado de las órdenes y monitorear la operación desde un panel administrativo.
El objetivo principal del proyecto no es construir un ecommerce completo, sino implementar un prototipo técnico enfocado en integración de pagos, separación entre frontend y backend, protección de credenciales, manejo de webhooks, control de roles, Row Level Security, auditoría y despliegue en producción.
Aplicación desplegada en Vercel:
https://pagalo-seguro.vercel.app
- React
- Vite
- Supabase Auth
- Supabase PostgreSQL
- Supabase Row Level Security
- Supabase Edge Functions
- Mercado Pago Checkout Pro Sandbox
- Vercel
- GitHub
El proyecto fue desarrollado con fines de aprendizaje y práctica técnica, buscando simular un flujo real de pagos sin exponer información sensible en el frontend.
Los objetivos principales fueron:
- Implementar autenticación de usuarios.
- Crear órdenes de pago asociadas a usuarios autenticados.
- Generar preferencias de pago desde backend mediante Supabase Edge Functions.
- Redirigir al usuario a Mercado Pago Checkout Pro.
- Recibir eventos de pago mediante webhooks.
- Consultar el estado real del pago antes de actualizar una orden.
- Proteger datos sensibles mediante RLS y funciones backend.
- Registrar eventos y acciones relevantes para auditoría.
- Desplegar frontend y backend serverless en producción.
PagaloSeguro utiliza una arquitectura basada en frontend React, Supabase como backend serverless y Mercado Pago como proveedor de pagos en ambiente sandbox.
Usuario autenticado
↓
Frontend React + Vite
↓
Supabase Auth
↓
Supabase Edge Functions
↓
Mercado Pago Checkout Pro Sandbox
↓
Webhook de Mercado Pago
↓
Supabase PostgreSQL + RLS + Audit LogsEl frontend no crea pagos directamente ni maneja tokens privados. Las operaciones sensibles se ejecutan desde Supabase Edge Functions.
- Registro de usuarios.
- Inicio de sesión.
- Cierre de sesión.
- Rutas protegidas para usuarios autenticados.
- Separación entre usuario normal y administrador mediante roles.
- Listado de productos o servicios de prueba.
- Visualización de productos activos.
- Uso de productos demo para generar órdenes de pago.
- Obtención del monto desde la base de datos, no desde el frontend.
- Creación de órdenes con estado inicial
pending. - Asociación de cada orden a un usuario autenticado.
- Asociación de cada orden a un producto.
- Registro de monto, moneda, proveedor y estado.
- Almacenamiento del
provider_preference_idgenerado por Mercado Pago. - Almacenamiento del
provider_payment_idcuando el pago es confirmado. - Visualización de órdenes propias por usuario.
- Visualización del detalle de una orden.
- Separación entre vista de cliente y vista administrativa.
-
Creación de preferencias de pago mediante Edge Function.
-
Redirección al checkout externo de Mercado Pago.
-
Configuración de URLs de retorno:
- Pago exitoso.
- Pago fallido.
- Pago pendiente.
-
Uso de Mercado Pago Checkout Pro en modo sandbox.
-
Configuración de webhook público para recibir eventos de pago.
-
Consulta del pago real en Mercado Pago antes de actualizar una orden.
- Recepción de eventos enviados por Mercado Pago.
- Registro de eventos en la tabla
payment_events. - Procesamiento de eventos tipo
payment. - Registro informativo de eventos
merchant_order. - Manejo de eventos duplicados o repetidos.
- Manejo de errores sin perder el payload recibido.
- Actualización automática de órdenes cuando el pago es confirmado.
- Soporte para ambiente sandbox mediante
SKIP_MP_SIGNATURE_VALIDATION.
Disponible solo para usuarios con rol admin.
Incluye:
- Visualización global de órdenes.
- Visualización del detalle administrativo de cualquier orden.
- Visualización de eventos de pago recibidos.
- Visualización de logs de auditoría.
- Sincronización manual de pagos cuando una orden ya tiene
provider_payment_id. - Monitoreo de pagos aprobados, pendientes, rechazados o con error.
El sistema registra acciones importantes en la tabla audit_logs, como:
- Creación de checkout.
- Confirmación de pago aprobado.
- Sincronización manual de pago.
- Cambios relevantes asociados al flujo de pago.
El sistema maneja dos roles principales.
Usuario normal del sistema.
Puede:
- Ver productos activos.
- Crear órdenes de pago.
- Ver sus propias órdenes.
- Ver el detalle de sus propias órdenes.
- Continuar el checkout si una orden sigue pendiente.
No puede:
- Ver órdenes de otros usuarios.
- Ver eventos de pago.
- Ver logs de auditoría.
- Acceder al panel administrativo.
- Modificar manualmente estados de pago.
Administrador del sistema.
Puede:
- Ver todas las órdenes.
- Ver eventos de pago.
- Ver logs de auditoría.
- Ver detalle administrativo de órdenes.
- Ejecutar sincronización manual de pagos.
- Acceder a rutas administrativas protegidas.
Las órdenes pueden tener los siguientes estados:
pending: la orden fue creada y el pago aún no está confirmado.approved: Mercado Pago confirmó el pago.rejected: el pago fue rechazado.cancelled: el pago fue cancelado.expired: el intento de pago expiró.refunded: el pago fue reembolsado.error: ocurrió un error técnico durante el flujo.
pagalo-seguro-app/
src/
components/
auth/
AdminRoute.jsx
ProtectedRoute.jsx
layout/
AppLayout.jsx
Navbar.jsx
Sidebar.jsx
context/
AuthContext.jsx
lib/
supabaseClient.js
pages/
admin/
AdminEvents.jsx
AdminLogs.jsx
AdminOrderDetail.jsx
AdminOrders.jsx
Dashboard.jsx
Login.jsx
NotFound.jsx
OrderDetail.jsx
Orders.jsx
PaymentFailure.jsx
PaymentPending.jsx
PaymentSuccess.jsx
Products.jsx
Register.jsx
router/
AppRouter.jsx
services/
adminService.js
ordersService.js
productsService.js
styles/
global.css
main.jsx
supabase/
config.toml
functions/
create-checkout/
index.ts
payment-webhook/
index.ts
sync-payment-status/
index.ts
vercel.json
vite.config.js
package.json
.env.exampleEl sistema utiliza las siguientes tablas en Supabase.
Guarda información extendida de los usuarios registrados.
Campos principales:
idfull_namerolecreated_atupdated_at
Guarda productos o servicios demo que pueden ser pagados mediante Mercado Pago.
Campos principales:
idnamedescriptionpricecurrencyis_activecreated_atupdated_at
Guarda las órdenes de pago generadas por los usuarios.
Campos principales:
iduser_idproduct_idamountcurrencystatusproviderprovider_preference_idprovider_payment_idcheckout_urlcreated_atupdated_at
Guarda los eventos recibidos desde Mercado Pago.
Campos principales:
idorder_idproviderevent_typeprovider_event_idraw_payloadprocessederror_messagecreated_at
Guarda acciones importantes del sistema.
Campos principales:
iduser_idactionentity_typeentity_idmetadatacreated_at
Función encargada de crear una orden y generar una preferencia de pago en Mercado Pago.
Responsabilidades:
- Validar usuario autenticado.
- Recibir
product_id. - Consultar el producto activo desde la base de datos.
- Crear una orden con estado
pending. - Crear una preferencia de pago en Mercado Pago.
- Guardar
provider_preference_id. - Guardar
checkout_url. - Registrar auditoría con
checkout_created.
Función encargada de recibir eventos de Mercado Pago.
Responsabilidades:
- Recibir notificaciones de pago.
- Registrar eventos en
payment_events. - Clasificar eventos
payment,merchant_order, IPN o desconocidos. - Consultar el pago real en Mercado Pago.
- Usar
external_referencepara asociar el pago a una orden. - Actualizar el estado de la orden.
- Guardar
provider_payment_id. - Registrar auditoría con acciones como
payment_approved.
Función administrativa para sincronizar manualmente una orden con Mercado Pago.
Responsabilidades:
- Validar usuario autenticado.
- Validar que el usuario tenga rol
admin. - Recibir
order_id. - Consultar el pago en Mercado Pago usando
provider_payment_id. - Actualizar el estado de la orden.
- Registrar auditoría con
manual_sync_executed.
PagaloSeguro aplica una separación clara entre frontend, backend y base de datos.
- El frontend no define el monto final del pago.
- El frontend no puede marcar una orden como aprobada.
- El frontend no maneja tokens privados de Mercado Pago.
- El
MERCADOPAGO_ACCESS_TOKENsolo se usa en Supabase Edge Functions. - El estado de una orden se actualiza únicamente desde backend.
- El webhook consulta Mercado Pago antes de actualizar una orden.
- El panel admin está protegido por frontend y backend.
- Las tablas sensibles están protegidas con Row Level Security.
El proyecto utiliza RLS en Supabase para controlar el acceso a la información.
Reglas generales:
- Los usuarios solo pueden ver sus propios perfiles.
- Los usuarios pueden ver productos activos.
- Los usuarios solo pueden ver sus propias órdenes.
- Los usuarios normales no pueden ver eventos de pago.
- Los usuarios normales no pueden ver logs de auditoría.
- Los administradores pueden ver todas las órdenes.
- Los administradores pueden ver eventos de pago.
- Los administradores pueden ver logs de auditoría.
- Las actualizaciones sensibles se realizan desde Edge Functions con
service_role.
Esta separación evita que el usuario pueda modificar estados de pago desde el frontend o manipular montos enviados desde el navegador.
Crear un archivo .env.local tomando como base .env.example:
VITE_SUPABASE_URL=
VITE_SUPABASE_ANON_KEY=
VITE_APP_NAME=PagaloSeguroEstas variables también deben configurarse en Vercel.
Configurar los secrets mediante Supabase CLI:
supabase secrets set APP_URL="https://tu-dominio.vercel.app"
supabase secrets set MERCADOPAGO_ACCESS_TOKEN="tu_access_token"
supabase secrets set MERCADOPAGO_WEBHOOK_URL="https://tu-proyecto.supabase.co/functions/v1/payment-webhook"
supabase secrets set MERCADOPAGO_WEBHOOK_SECRET="tu_webhook_secret"
supabase secrets set SKIP_MP_SIGNATURE_VALIDATION="true"Para ambiente sandbox se usa:
SKIP_MP_SIGNATURE_VALIDATION=truePara producción real debe usarse:
SKIP_MP_SIGNATURE_VALIDATION=falseLa validación estricta de firma de Mercado Pago fue implementada y probada. Sin embargo, durante las pruebas en ambiente sandbox, la firma calculada no coincidía con v1, aun recibiendo data.id, ts y x-request-id.
Por este motivo, para el entorno de práctica se mantiene:
SKIP_MP_SIGNATURE_VALIDATION=trueAun con esta configuración, el sistema no actualiza órdenes confiando únicamente en el payload recibido. Antes de modificar una orden, la Edge Function consulta directamente el pago real en Mercado Pago usando el payment_id.
Antes de adaptar este proyecto a pagos reales, se debe resolver la validación estricta de firma y configurar:
SKIP_MP_SIGNATURE_VALIDATION=falseClonar el repositorio:
git clone <url-del-repositorio>
cd pagalo-seguro-appInstalar dependencias:
npm installCrear archivo de entorno local:
cp .env.example .env.localConfigurar las variables:
VITE_SUPABASE_URL=
VITE_SUPABASE_ANON_KEY=
VITE_APP_NAME=PagaloSeguroEjecutar en desarrollo:
npm run devEjecutar entorno de desarrollo:
npm run devGenerar build de producción:
npm run buildPrevisualizar build de producción:
npm run previewEjecutar revisión de código con ESLint:
npm run lintPara que el proyecto funcione correctamente, se debe configurar:
- Supabase Auth.
- Tablas principales.
- Triggers para creación automática de perfiles.
- Row Level Security.
- Policies por rol.
- Edge Functions.
- Secrets de Supabase.
- URL pública del webhook.
- Roles de usuario en la tabla
profiles.
Para ambiente sandbox:
- Crear una aplicación en Mercado Pago Developers.
- Obtener credenciales de prueba.
- Configurar el Access Token de prueba en Supabase secrets.
- Configurar el webhook de prueba.
- Seleccionar el evento
Pagos. - Usar cuentas de prueba para comprador y vendedor.
- Usar tarjetas de prueba para validar pagos.
Webhook recomendado:
https://tu-proyecto.supabase.co/functions/v1/payment-webhookPasos generales:
-
Subir el proyecto a GitHub.
-
Importar el repositorio en Vercel.
-
Configurar el framework como Vite.
-
Configurar variables de entorno:
VITE_SUPABASE_URLVITE_SUPABASE_ANON_KEYVITE_APP_NAME
-
Ejecutar despliegue.
Vincular el proyecto:
supabase link --project-ref <project-ref>Desplegar funciones:
supabase functions deploy create-checkout
supabase functions deploy payment-webhook
supabase functions deploy sync-payment-statusEl proyecto se encuentra en versión MVP funcional.
Incluye:
- Autenticación.
- Productos demo.
- Creación de órdenes.
- Checkout con Mercado Pago Sandbox.
- Webhook de pagos.
- Actualización automática de órdenes.
- Panel administrativo.
- Eventos de pago.
- Logs de auditoría.
- Sincronización manual.
- Row Level Security.
- Separación de variables públicas y privadas.
- Despliegue en Vercel y Supabase.
- La integración está configurada para Mercado Pago Sandbox.
- La validación estricta de firma del webhook queda pendiente para producción real.
- No genera boleta o comprobante.
- No implementa reembolsos desde el panel.
- No implementa gestión CRUD de productos desde el panel admin.
- No implementa Checkout Bricks ni Checkout API personalizado.
- No implementa Stripe como proveedor alternativo.
- Resolver validación estricta de firma de Mercado Pago.
- Implementar comprobante o boleta de pago.
- Implementar gestión administrativa de productos.
- Implementar reembolsos.
- Implementar Checkout Bricks para una experiencia más personalizada.
- Implementar Checkout API para mayor control del flujo.
- Agregar Stripe como proveedor alternativo.
- Implementar arquitectura multi-provider.
- Agregar métricas de conversión de pagos.
- Mejorar visualización del panel administrativo.
- Agregar filtros avanzados en órdenes, eventos y logs.
- Agregar exportación CSV de órdenes y eventos.
Desarrollado por Axel Pariona como proyecto de integración de pagos, seguridad, webhooks y Mercado Pago.