npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

products-payment-refacil-mcp

v1.1.3

Published

MCP Server para la API products-payment-refacil

Readme

products-payment-refacil MCP Server

Servidor MCP (Model Context Protocol) generado automáticamente para la API products-payment-refacil.

🚀 Características

  • 11 herramientas generadas automáticamente desde la colección Postman
  • Autenticación flexible: secretId con renovación automática de tokens
  • Servidor HTTP con Fastify
  • Protocolo MCP estándar para integración con IDEs

📋 Requisitos

  • Node.js 20+
  • npm o yarn

📦 Instalación desde NPM

Si este paquete está publicado en npm, puedes instalarlo globalmente:

# Instalación global (recomendado)
npm install -g products-payment-refacil-mcp

# Verificar instalación
products-payment-refacil-mcp --version

Configuración Rápida en IDEs

Cursor

  1. Abrir SettingsFeaturesModel Context Protocol
  2. Click en "Edit Config"
  3. Agregar:

Windows: %APPDATA%\Cursor\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json

macOS/Linux: ~/.config/Cursor/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json

{
  "mcpServers": {
    "products-payment-refacil": {
      "command": "products-payment-refacil-mcp",
      "env": {
        "BASE_URL": "https://products-payment-api.qa.refacil.co",
        "SECRET_ID": "tu-secret-id",
        "AUTH_ENDPOINT": "/auth/generate-token",
        "TOKEN_CACHE_TTL": "3600"
      }
    }
  }
}
  1. Reiniciar Cursor

Claude Desktop

Editar archivo de configuración:

Windows: %APPDATA%\Claude\claude_desktop_config.json

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

Linux: ~/.config/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "products-payment-refacil": {
      "command": "products-payment-refacil-mcp",
      "env": {
        "BASE_URL": "https://products-payment-api.qa.refacil.co",
        "SECRET_ID": "tu-secret-id",
        "AUTH_ENDPOINT": "/auth/generate-token",
        "TOKEN_CACHE_TTL": "3600"
      }
    }
  }
}

Reiniciar Claude Desktop.

Visual Studio Code

  1. Instalar extensión MCP for VS Code
  2. Editar settings.json:
{
  "mcp.servers": {
    "products-payment-refacil": {
      "command": "products-payment-refacil-mcp",
      "env": {
        "BASE_URL": "https://products-payment-api.qa.refacil.co",
        "SECRET_ID": "tu-secret-id",
        "AUTH_ENDPOINT": "/auth/generate-token",
        "TOKEN_CACHE_TTL": "3600"
      }
    }
  }
}
  1. Recargar VS Code

🛠️ Instalación para Desarrollo

Si quieres contribuir o ejecutar desde el código fuente:

# Clonar el repositorio
git clone https://github.com/refacil/products-payment-refacil-mcp.git
cd products-payment-refacil-mcp

# Instalar dependencias
npm install

# Construir el proyecto
npm run build

# Iniciar en desarrollo
npm run dev

# Iniciar en producción
npm start

🔧 Configuración

El servidor se configura mediante variables de entorno:

# Copiar archivo de ejemplo
cp .env.example .env

# Editar configuración
nano .env

Variables de Entorno

| Variable | Descripción | Valor por defecto | |----------|-------------|-------------------| | PORT | Puerto del servidor | 3008 | | ENVIRONMENT | Entorno de ejecución | development | | BASE_URL | URL base de la API | https://products-payment-api.qa.refacil.co | | SECRET_ID | ID secreto para autenticación | 0d92fc6aa394c13... (your secret id) | | AUTH_ENDPOINT | Endpoint de autenticación | /auth/generate-token | | TOKEN_CACHE_TTL | TTL del caché de tokens (segundos) | 3600 | | MCP_TOKEN | Token de autenticación del MCP | mcp-secret-token-123 |

🐳 Docker

# Construir imagen
docker build -t products-payment-refacil-mcp .

# Ejecutar contenedor
docker run -p 3008:3008 products-payment-refacil-mcp

# O usar docker-compose
docker-compose up

☸️ Kubernetes

# Aplicar manifests
kubectl apply -f k8s/

# Verificar despliegue
kubectl get pods -l app=products-payment-refacil-mcp

🔌 Uso del MCP

Endpoints Disponibles

  • /mcp: Endpoint principal del protocolo MCP
  • /health: Health check del servidor
  • /tools: Lista de herramientas disponibles

Modo Multi-Usuario (HTTP)

El servidor MCP soporta múltiples usuarios simultáneamente en modo HTTP mediante el header X-Secret-ID.

¿Cómo funciona?

  1. Sin X-Secret-ID: Usa el SECRET_ID del archivo .env (modo single-user)
  2. Con X-Secret-ID: Usa el secretId proporcionado en el header (modo multi-user)

Ejemplo de uso:

# Usuario 1
curl -X POST http://localhost:3008/mcp \
  -H "Authorization: Bearer mcp-token" \
  -H "X-Secret-ID: user1-secret-id" \
  -H "Content-Type: application/json" \
  -d '{"method": "tools/call", "params": {...}}'

# Usuario 2
curl -X POST http://localhost:3008/mcp \
  -H "Authorization: Bearer mcp-token" \
  -H "X-Secret-ID: user2-secret-id" \
  -H "Content-Type: application/json" \
  -d '{"method": "tools/call", "params": {...}}'

Ventajas del Modo Multi-Usuario:

  • ✅ Cada usuario usa sus propias credenciales
  • ✅ Tokens cacheados por secretId (mejor performance)
  • ✅ Un solo servidor para múltiples clientes
  • ✅ Compatible con modo single-user (fallback al .env)

🛠️ Herramientas Disponibles

auth_generate_token

Endpoints para autenticación y generación de tokens

Genera un token JWT usando el secretId del cliente. Este token debe ser usado en todas las peticiones posteriores junto con el secretId.

🔑 MANEJO GLOBAL DE ERRORES 401 - AUTENTICACIÓN:

⚠️ IMPORTANTE: Este endpoint es la base para resolver errores de autenticación en TODOS los endpoints protegidos.

🔄 Flujo de Resolución de Errores 401:

1. Cuando recibas un error 401 en cualquier endpoint:

{
  "statusCode": 401,
  "message": "Error de autenticación",
  "date": 1754924521985,
  "payload": {
    "error": "AUTHENTICATION_ERROR",
    "details": "Authentication failed",
    "originalStatus": 401
  }
}

2. Acciones inmediatas a realizar:

  • Verificar que tus datos de autenticación sean correctos

  • Regenerar un nuevo token usando este endpoint (/auth/generate-token)

  • Reintentar la operación original con el nuevo token

💡 Mejor práctica: Implementa retry automático para errores 401 antes de fallar.

📋 Flujo de resolución detallado:

  • Token expirado: Llamar este endpoint con tu secretId

  • Token inválido: Verificar formato y regenerar si es necesario

  • Secret ID incorrecto: Usar el mismo secretId del token original

  • Headers faltantes: Incluir Authorization: Bearer {token} y x-secret-id: {secretId}

🔄 Ejemplo de retry automático:

// Si recibes 401, regenera token y reintenta
if (error.statusCode === 401) {
  const newToken = await generateNewToken(secretId);
  // Reintentar operación original con nuevo token
}

🎯 Aplicable a todos los endpoints protegidos:

  • 📦 Productos y categorías

  • 🛒 Solicitudes de producto

  • 💳 Creación de pagos

  • 🔄 Reembolsos

  • Y cualquier otro endpoint que requiera autenticación

Respuesta exitosa (200):

{
  "statusCode": 200,
  "message": "Token generado exitosamente",
  "date": 1704441600000,
  "payload": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "expiresIn": 360
  }
}

Campos del payload:

  • token (string): Token JWT para autenticación

  • expiresIn (number): Tiempo de expiración en minutos (ej: 360 = 6 horas)

🤖 Automatización en Postman:
Este endpoint incluye un script automático que:

  • ✅ Guarda el token en la variable {{token}} de la colección

  • ✅ Valida que la respuesta sea exitosa

  • ✅ Muestra logs informativos en la consola

  • ✅ Maneja errores automáticamente

Resultado: Los siguientes endpoints usarán automáticamente el token generado.

Respuesta de error (400):

{
  "statusCode": 400,
  "message": "Datos de entrada inválidos",
  "date": 1704441600000,
  "payload": {
    "error": "VALIDATION_ERROR"
  }
}

Parámetros:

| Name | Type | Description | | --- | --- | --- | | secretId | string | Campo del body: secretId |

status

Verificación del estado de la API y conectividad con servicios

Verifica el estado de la API y servicios internos.

Respuesta exitosa (200):

{
  "statusCode": 200,
  "message": "API funcionando correctamente",
  "date": 1704441600000,
  "payload": {
    "status": "ok",
    "timestamp": "2024-01-15T10:30:45.123Z",
    "uptime": 3600,
    "services": "connected",
    "version": "1.0.0",
    "environment": "development"
  }
}

Respuesta con error (503):

{
  "statusCode": 503,
  "message": "API con problemas de conectividad",
  "date": 1704441600000,
  "payload": {
    "status": "error",
    "timestamp": "2024-01-15T10:30:45.123Z",
    "uptime": 3600,
    "services": "disconnected",
    "error": "Connection timeout",
    "version": "1.0.0",
    "environment": "development"
  }
}

products_categories

Endpoints para consultar categorías y productos disponibles

Retorna las categorías de productos que el cliente puede acceder.

Headers requeridos:

  • Authorization: Bearer {token}
  • x-secret-id: {secretId}

Respuesta exitosa (200):

{
  "statusCode": 200,
  "message": "Categorías obtenidas exitosamente",
  "date": 1704441600000,
  "payload": [
    {
      "id": 1,
      "name": "Recargas",
      "description": "Recargas de celular",
      "enabled": true
    },
    {
      "id": 2,
      "name": "Pines",
      "description": "Pines de servicios",
      "enabled": true
    }
  ]
}

Respuesta de error (401):

{
  "statusCode": 401,
  "message": "Error de autenticación",
  "date": 1754924521985,
  "payload": {
    "error": "AUTHENTICATION_ERROR",
    "details": "Authentication failed",
    "originalStatus": 401
  }
}

Parámetros:

| Name | Type | Description | | --- | --- | --- | | secretId | string | Header personalizado: x-secret-id |

products_by_cus_and_category

Endpoints para consultar categorías y productos disponibles

Retorna los productos filtrados por cliente y categoría.

Headers requeridos:

  • Authorization: Bearer {token}

  • x-secret-id: {secretId}

Body (JSON):

  • categoryId (number, requerido): ID de la categoría

  • limit (number, opcional): Número máximo de productos (default: 10)

  • offset (number, opcional): Número de productos a omitir (default: 0)

  • searchText (string, opcional): Texto para buscar en productos

Ejemplo de Request:

{
  "categoryId": 120,
  "limit": 10,
  "offset": 0,
  "searchText": "BANCAMIA"
}

Respuesta exitosa (200):

{
  "statusCode": 200,
  "message": "Productos obtenidos exitosamente",
  "date": 1754924866513,
  "payload": {    
    "products": [
      {
        "id": 1,
        "name": "BANCAMIA",
        "amount": null,
        "meta": {
          "partial": "false",
          "overdue": "true",
          "type": "RECAUDO CODIGO BARRAS",
          "fnArgs": "1,25,44"
        },
        "description": null,
        "image_url": "bills/52368.png",
        "query_type": "BILLData",
        "sell_type": "Bill",
        "agreement": "7700000000001",
        "template_data_request": {
             "cellphone": "3208888888",
             "reference": "123456789"
         }
      },
      {
        "id": 16045,
        "name": "LIBERACION DE CUPO BANCAMIA",
        "amount": null,
        "meta": {
          "fnArgs": 43278,
          "categoryId": 43,
          "form": [
            {
              "active": true,
              "type": "text",
              "label": "Numero De Documento",
              "placeholder": "Ingrese su NUMERO DE DOCUMENTO",
              "legend": "NUMERO DE DOCUMENTO",
              "value": "reference",
              "required": true
            },
            {
              "active": true,
              "type": "text",
              "label": "Codigo De Corresponsal",
              "placeholder": "Ingrese su CODIGO DE CORRESPONSAL",
              "legend": "CODIGO DE CORRESPONSAL",
              "value": "reference2",
              "required": true
            }
          ]
        },
        "description": null,
        "image_url": "bill.png",
        "query_type": "BILLData",
        "sell_type": "Bill",
        "agreement": "2010910",
        "template_data_request": {
             "cellphone": "3208888888",
             "reference": "123456789",
             "reference2": "123548"
         }
      }
    ]
  }
}

📋 Datos para Solicitud de Producto:
Esta respuesta contiene información clave que se debe usar para crear una solicitud de producto:

  • id: ID del producto (se usa en product-requests/create)

  • query_type: Tipo de consulta (se usa en product-requests/create)

  • sell_type: Tipo de venta (se usa en product-requests/create)

  • agreement: Acuerdo del producto (se puede usar en product-requests/create)

  • template_data_request: Template para el campo data en product-requests/create

  • amount: Monto del producto (puede ser null para productos con consulta previa)

Notas importantes:

  • template_data_request: Es un template que muestra la estructura de datos que se debe enviar en el campo data cuando se crea una solicitud de producto para esta categoría específica. Los valores son ejemplos y deben ser reemplazados con datos reales.

  • data dinámico: El campo data en las solicitudes de producto es dinámico y su estructura depende de la categoría. Cada categoría puede requerir diferentes campos y formatos.

  • Objeto meta: Es dinámico y puede contener información diferente para cada producto. No se define una estructura fija debido a su naturaleza variable.

  • Tipos de producto: Los productos pueden tener diferentes tipos de query_type y sell_type según la categoría.

  • Campo amount: Puede ser null para productos que requieren consulta previa (como facturas), o contener un valor específico para productos de pago directo.

🔄 Flujo de Uso:

  1. Consultar productos con este endpoint

  2. Seleccionar producto de la lista

  3. Usar datos del producto para crear solicitud en product-requests/create

  4. Usar template_data_request como referencia para el campo data

  5. Determinar amount según el tipo de producto (null para consulta previa, valor para pago directo)

Respuesta de error (401):

{
  "statusCode": 401,
  "message": "Error de autenticación",
  "date": 1754924521985,
  "payload": {
    "error": "AUTHENTICATION_ERROR",
    "details": "Authentication failed",
    "originalStatus": 401
  }
}

Parámetros:

| Name | Type | Description | | --- | --- | --- | | secretId | string | Header personalizado: x-secret-id | | categoryId | number | Campo del body: categoryId | | limit | number | Campo del body: limit | | offset | number | Campo del body: offset | | searchText | null | Campo del body: searchText |

product_requests_create

Endpoints para crear solicitudes de productos

Crea una nueva solicitud de producto. Esta es la primera etapa del proceso de pago.

📋 Relación con Endpoint de Productos:
Los datos para crear esta solicitud provienen principalmente del endpoint products/by-customer-and-category:

  • category_id: ID de la categoría (del endpoint de productos)

  • id: ID del producto seleccionado (del campo id del producto)

  • query_type: Tipo de consulta (del campo query_type del producto)

  • sell_type: Tipo de venta (del campo sell_type del producto)

  • data: Estructura basada en template_data_request del producto

  • agreement: Acuerdo del producto (del campo agreement del producto)

Headers requeridos:

  • Authorization: Bearer {token}

  • x-secret-id: {secretId}

Body (JSON):

  • category_id (number, requerido): ID de la categoría (obtenido del endpoint de productos)

  • id (number, requerido): ID del producto seleccionado (obtenido del campo id del producto)

  • amount (number|null, opcional): Monto del producto (ver reglas de uso)

  • data (object, requerido): Datos específicos del producto basados en template_data_request del producto

  • query_type (string, requerido): Tipo de consulta del producto (PHONE_QUERY, PLATE_QUERY, etc.)

  • sell_type (string, requerido): Tipo de venta del producto (DIRECT_SALE, QUERY_FIRST)

  • agreement (string, opcional): Aceptación de términos (puede venir del campo agreement del producto)

  • customer_id (string, opcional): Identificador único del usuario o dispositivo

  • cart_id (string, opcional): identificador del carrito de compra al que se quiere agregar la solicictud de producto

📋 Reglas para el campo customer_id:

🔑 Con Usuario Registrado:

  • Enviar: ID único del usuario en tu sistema

  • Ejemplo: "customer_id": "user_12345" o "customer_id": "cliente_abc123"

  • Uso: Para seguimiento, historial de transacciones, y análisis de comportamiento

📱 Sin Usuario Registrado (Frontend Anónimo):

  • Enviar: Identificador único del dispositivo o sesión

  • Ejemplos:

    • Device ID: "customer_id": "device_abc123def456"

    • Session ID: "customer_id": "session_xyz789"

    • Browser Fingerprint: "customer_id": "browser_fp_123"

    • Local Storage ID: "customer_id": "local_456"

  • Uso: Para seguimiento de transacciones anónimas y análisis de patrones

💡 Mejores Prácticas:

  • Consistencia: Usar el mismo formato de ID en toda la aplicación

  • Persistencia: Mantener el ID durante toda la sesión del usuario

  • Privacidad: No incluir información personal identificable en el ID

  • Longitud: Recomendado entre 10-50 caracteres

🔄 Flujo de Implementación:

1. Usuario Registrado:

const customerId = user.id || user.customerId || user.uuid;
// customerId = "user_12345"

2. Usuario Anónimo:

// Generar ID único del dispositivo
const deviceId = generateDeviceId(); // "device_abc123def456"
const sessionId = generateSessionId(); // "session_xyz789"
const customerId = deviceId || sessionId;

3. Envío en Request:

{
  "category_id": 120,
  "id": 1952,
  "amount": null,
  "data": {
    "cellphone": "3208385715",
    "reference": "123456"
  },
  "query_type": "BILLData",
  "sell_type": "Bill",
  "agreement": "2010910",
  "customer_id": "device_abc123def456"
}

📊 Beneficios del Tracking:

  • Análisis: Comportamiento de usuarios anónimos vs registrados

  • Seguimiento: Transacciones por dispositivo/sesión

  • Fraude: Detección de patrones sospechosos

  • UX: Mejora de la experiencia del usuario

💰 Reglas para el campo amount****:

  • amount: null: Para productos que generan consulta previa (ej: facturas, servicios con tarifas variables)

  • amount: valor: Para productos de pago directo con precio fijo (ej: recargas, productos con precio conocido)

  • Validación interna: El sistema valida internamente y solo toma el amount del cliente cuando aplica

🔄 Flujo de Creación de Solicitud:

1. Consultar productos:

POST /products/by-customer-and-category
{
  "categoryId": 120,
  "limit": 10,
  "offset": 0,
  "searchText": "ACACIAS"
}

2. Respuesta del endpoint de productos:

{
  "statusCode": 200,
  "message": "Productos obtenidos exitosamente",
  "date": 1754945365966,
  "payload": {
    "template_data_request": {
      "cellphone": "3208888888",
      "reference": "123456789"
    },
    "products": [
      {
        "id": 1952,
        "name": "ACACIAS DEL CASTILLO CONJUNTO 3 CALI",
        "amount": null,
        "meta": {
          "fnArgs": 20363,
          "categoryId": 44,
          "form": [
            {
              "active": true,
              "type": "text",
              "label": "Numero De Casa",
              "placeholder": "Ingrese su Numero de Casa",
              "legend": "Numero de Casa",
              "value": "reference",
              "required": true
            }
          ]
        },
        "description": null,
        "image_url": "bill.png",
        "query_type": "BILLData",
        "sell_type": "Bill",
        "agreement": "2010910"
      }
    ]
  }
}

3. Crear solicitud usando datos del producto:

{
  "category_id": 120,
  "id": 1952,
  "amount": null,
  "data": {    
    "cellphone": "3208385715",
    "reference": "123456"
  },
  "query_type": "BILLData",
  "sell_type": "Bill",
  "agreement": "2010910"  
}

Respuesta exitosa (201):

{
  "statusCode": 201,
  "message": "Solicitud creada exitosamente",
  "date": 1754945173974,
  "payload": {
    "cartId": "25894df4-a599-4d28-a2f2-bb5b8faa678b",
    "requestId": "15974df4-a599-4d28-a2f2-bb5b8faa678b",
    "amount": 9999,
    "paymentMethods": [
      {
        "id": 304135,
        "name": "Transfiya",
        "internal_name": "AppFormTransfiya",
        "description": "Transfiya",
        "categoryid": 176,
        "image": "transfiya.png",
        "template_data_request": {
          "cellphone": "3208888888"
        },
        "cost": 500
      },
      {
        "id": 56,
        "name": "PSE",
        "internal_name": "AppFormPse",
        "description": "PSE",
        "categoryid": 61,
        "image": "pse.png",
        "template_data_request": {
          "name": "Juan Perez",
          "email": "[email protected]",
          "bankId": "1007",
          "cellphone": "3208888888",
          "typePerson": "0",
          "documentType": "CC",
          "documentNumber": "1032222222"
        },
        "cost": 500
      },
      {
        "id": 88,
        "name": "Nequi",
        "internal_name": "AppFormNequiCargar",
        "description": "Botón de pago nequi",
        "categoryid": 176,
        "image": "nequi-responsive.png",
        "template_data_request": {
          "cellphone": "3208888888"
        },
        "cost": 500
      },
      {
        "id": 53,
        "name": "Bancolombia",
        "internal_name": "AppFormDefault",
        "description": "Botón de pago Bancolombia",
        "categoryid": 177,
        "image": "bancolombia.png",
        "template_data_request": {
          "name": "Juan Perez",
          "email": "[email protected]",
          "bankId": "1007",
          "cellphone": "3208888888",
          "typePerson": "0",
          "documentType": "CC",
          "documentNumber": "1032222222"
        },
        "cost": 500
      },
      {
        "id": 89,
        "name": "Daviplata",
        "internal_name": "AppFormDaviplataPse",
        "description": "Botón de pago daviplata",
        "categoryid": 176,
        "image": "daviplata.png",
        "template_data_request": {
          "cellphone": "3208888888"
        },
        "cost": 500        
      }
    ]
  }
}

📋 Datos de la Respuesta:

  • **cartId:**Identificador unico del carrito al que se asigno la solicitud de producto (se usa en /products-payment/create)

  • requestId: Identificador único de la solicitud de producto

  • amount: Monto que se debe pagar (calculado por el sistema)

  • additionalData: Datos adicionales del producto (solo si aplica)

  • paymentMethods: Array con medios de pago disponibles

💳 Información de Medios de Pago:
Cada medio de pago contiene:

  • id: ID del medio de pago (se usa en /products-payment/create)

  • name: Nombre del medio de pago

  • categoryid: ID de la categoría del medio de pago (se usa en /products-payment/create)

  • template_data_request: Template para el campo data en /products-payment/create

  • cost: Costo del medio de pago para esta transacción (0 = sin costo, >0 = con costo)

🔄 Siguiente Paso - Crear Pago:
Con la respuesta de este endpoint, puedes proceder a crear el pago usando /products-payment/create enviando:

  • cartId: Del campo cartId de la respuesta

  • id: Del campo id del medio de pago seleccionado

  • categoryid: Del campo categoryid del medio de pago seleccionado

  • data: Basado en template_data_request del medio de pago seleccionado

Respuesta de error (403):

{
  "statusCode": 403,
  "message": "Acceso denegado - Categoría no permitida",
  "date": 1704441600000,
  "payload": {
    "error": "CATEGORY_NOT_ALLOWED"
  }
}

Respuesta de error (401):

{
  "statusCode": 401,
  "message": "Error de autenticación",
  "date": 1754924521985,
  "payload": {
    "error": "AUTHENTICATION_ERROR",
    "details": "Authentication failed",
    "originalStatus": 401
  }
}

Parámetros:

| Name | Type | Description | | --- | --- | --- | | secretId | string | Header personalizado: x-secret-id | | category_id | number | Campo del body: category_id | | id | number | Campo del body: id | | amount | null | Campo del body: amount | | data | object | Campo del body: data | | query_type | string | Campo del body: query_type | | sell_type | string | Campo del body: sell_type | | agreement | string | Campo del body: agreement | | customer_id | string | Campo del body: customer_id |

product_requests_status

Endpoints para crear solicitudes de productos

Consulta el estado actual de una solicitud de producto individual por su requestId o de un carrito completo por su cartId.

🔒 Seguridad:
Este endpoint incluye validación de seguridad que garantiza que solo puedas consultar el estado de las solicitudes/carritos que creaste.

📋 Parámetros:

Debes proporcionar uno de los siguientes parámetros (no ambos obligatorios):

  • requestId (string, opcional): ID único de la solicitud de producto individual (UUID)

  • cartId (string, opcional): ID único del carrito de compras (UUID)

Headers requeridos:

  • Authorization: Bearer {token}

  • x-secret-id: {secretId}

📊 Estados Posibles:

🔄 Estados de Proceso:

  • INITIATED: Solicitud creada y en proceso de validación

  • QUERIED: Solicitud consultada exitosamente en API externa

  • PENDING: Solicitud lista para procesar el pago

  • WAITING_PAYMENT: Esperando confirmación de pago del proveedor

❌ Estados de Error:

  • INVALID: Datos inválidos en la validación del producto

  • DISCARDED: Usuario decidió no continuar con el pago del producto

  • EXPIRED: La solicitud de producto ha expirado

✅ Estados Finales:

  • SOLD: Pago exitoso y producto vendido

  • REFUNDED: Pago exitoso pero venta falló

  • CANCELLED: Usuario no realizó el pago del producto, el proveedor no confirmó el pago

🔄 Flujo de Uso - Producto Individual:

1. Consultar estado usando requestId:

POST /product-requests/status
{
  "requestId": "15974df4-a599-4d28-a2f2-bb5b8faa678b"
}

2. Respuesta del estado (producto individual):

{
  "statusCode": 200,
  "message": "Estado consultado exitosamente",
  "date": 1754945173974,
  "payload": {
    "id": "15974df4-a599-4d28-a2f2-bb5b8faa678b",
    "cartId": "22884df4-a599-4d28-a2f2-bb5b8faa352b",
    "status": "SOLD",
    "description": "Pago exitoso y producto vendido",
    "details": {
      "id": 123,
      "categoryId": 1,
      "amount": 15000,
      "data": {...}
    },
    "urlSummary": "https://example.com/summary/ref-xyz"
  }
}

🛒 Flujo de Uso - Carrito Completo:

1. Consultar estado usando cartId:

POST /product-requests/status
{
  "cartId": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}

2. Respuesta del estado (carrito completo):

{
  "statusCode": 200,
  "message": "Estado consultado exitosamente",
  "date": 1754945173974,
  "payload": {
    "cartId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "status": "COMPLETED",
    "totalAmount": 27000,
    "itemsCount": 2,
    "products": [
      {
        "id": "20db2a40-77b7-11f0-85d4-7d462019c921",
        "status": "SOLD",
        "description": "Pago exitoso y producto vendido",
        "details": {
          "id": 123,
          "categoryId": 1,
          "amount": 15000,
          "data": {...}
        },
        "urlSummary": "https://example.com/summary/ref-xyz"
      },
      {
        "id": "30db2a40-77b7-11f0-85d4-7d462019c922",
        "status": "SOLD",
        "description": "Pago exitoso y producto vendido",
        "details": {
          "id": 456,
          "categoryId": 2,
          "amount": 12000,
          "data": {...}
        },
        "urlSummary": "https://example.com/summary/ref-xyz"
      }
    ]
  }
}

🔐 Validación de Seguridad:

  • Usuario autenticado: Solo puedes consultar solicitudes/carritos creados con tu secretId

  • ID válido: Debe ser un UUID válido

  • Acceso restringido: No puedes consultar solicitudes/carritos de otros usuarios

📱 Casos de Uso:

  • Frontend: Mostrar estado actual al usuario

  • Backend: Seguimiento de transacciones

  • Webhooks: Complementar notificaciones asíncronas

  • Auditoría: Verificar estado de solicitudes

  • Carrito: Consultar estado de múltiples productos a la vez

Respuesta de error (400 - Parámetros faltantes):

{
  "statusCode": 400,
  "message": "Debe proporcionar requestId o cartId",
  "date": 1754945173974,
  "payload": {
    "error": "MISSING_REQUIRED_PARAMETER"
  }
}

Respuesta de error (404):

{
  "statusCode": 404,
  "message": "Solicitud de producto no encontrada",
  "date": 1754945173974,
  "payload": {
    "error": "PRODUCT_REQUEST_NOT_FOUND"
  }
}

💡 Tip para Testing:
Usa la variable {{lastCartId}} o {{lastRequestId}} que se llenan automáticamente al crear solicitudes.

Parámetros:

| Name | Type | Description | | --- | --- | --- | | secretId | string | Header personalizado: x-secret-id | | requestId | string | Campo del body: requestId | | cartId | string | Campo del body: cartId |

product_requests_discard

Endpoints para crear solicitudes de productos

Descarta una solicitud de producto individual por su requestId o un carrito completo con todos sus productos por su cartId.

🔒 Seguridad:
Este endpoint incluye validación de seguridad que garantiza que solo puedas descartar solicitudes/carritos que creaste.

📋 Parámetros:

Debes proporcionar uno de los siguientes parámetros (no ambos obligatorios):

  • requestId (string, opcional): ID único de la solicitud de producto individual (UUID)

  • cartId (string, opcional): ID único del carrito de compras (UUID)

Headers requeridos:

  • Authorization: Bearer {token}

  • x-secret-id: {secretId}

⚠️ Condiciones para Descartar:

Para producto individual:

  • El producto debe estar en estado PENDING

  • Debe pertenecer al usuario autenticado

Para carrito completo:

  • El carrito debe estar en estado ACTIVE

  • Debe pertenecer al usuario autenticado

  • Debe tener al menos un producto en estado PENDING

🔄 Flujo de Uso - Producto Individual:

1. Descartar producto usando requestId:

POST /product-requests/discard
{
  "requestId": "15974df4-a599-4d28-a2f2-bb5b8faa678b"
}

2. Respuesta (producto individual):

{
  "statusCode": 200,
  "message": "Solicitud descartada exitosamente",
  "date": 1754945173974,
  "payload": {
    "requestId": "15974df4-a599-4d28-a2f2-bb5b8faa678b",
    "status": "DISCARDED"
  }
}

🛒 Flujo de Uso - Carrito Completo:

1. Descartar carrito usando cartId:

POST /product-requests/discard
{
  "cartId": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}

2. Respuesta (carrito completo):

{
  "statusCode": 200,
  "message": "Carrito descartado exitosamente (2 productos)",
  "date": 1754945173974,
  "payload": {
    "cartId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "status": "CANCELLED",
    "discardedCount": 2,
    "products": [
      {
        "requestId": "20db2a40-77b7-11f0-85d4-7d462019c921",
        "status": "DISCARDED"
      },
      {
        "requestId": "30db2a40-77b7-11f0-85d4-7d462019c922",
        "status": "DISCARDED"
      }
    ]
  }
}

🔐 Validación de Seguridad:

  • Usuario autenticado: Solo puedes descartar solicitudes/carritos creados con tu secretId

  • ID válido: Debe ser un UUID válido

  • Acceso restringido: No puedes descartar solicitudes/carritos de otros usuarios

📱 Casos de Uso:

  • Usuario cambia de opinión: Descarta producto antes de pagar

  • Datos incorrectos: Usuario ingresó datos equivocados

  • Monto muy alto: Usuario no esperaba ese monto

  • Limpiar carrito: Descartar todos los productos de una vez

  • Empezar de nuevo: Usuario quiere crear un nuevo carrito desde cero

Respuesta de error (400 - Parámetros faltantes):

{
  "statusCode": 400,
  "message": "Debe proporcionar requestId o cartId",
  "date": 1754945173974,
  "payload": {
    "error": "MISSING_REQUIRED_PARAMETER"
  }
}

Respuesta de error (400 - Producto no está en PENDING):

{
  "statusCode": 500,
  "message": "Product request is not pending",
  "date": 1754945173974,
  "payload": {
    "error": "Product request is not pending"
  }
}

Respuesta de error (400 - Carrito no está ACTIVE):

{
  "statusCode": 500,
  "message": "Cart is not active",
  "date": 1754945173974,
  "payload": {
    "error": "Cart is not active"
  }
}

Respuesta de error (404):

{
  "statusCode": 500,
  "message": "Product request not found",
  "date": 1754945173974,
  "payload": {
    "error": "Product request not found"
  }
}

💡 Tip para Testing:
Usa la variable {{lastCartId}} o {{lastRequestId}} que se llenan automáticamente al crear solicitudes.

Parámetros:

| Name | Type | Description | | --- | --- | --- | | secretId | string | Header personalizado: x-secret-id | | requestId | string | Campo del body: requestId | | cartId | string | Campo del body: cartId |

products_banks_pse

Endpoints para crear pagos de productos

Obtiene la lista de bancos disponibles para pagos PSE.

📋 Uso:
Este endpoint es esencial para pagos PSE, ya que el usuario debe seleccionar su banco antes de crear el pago.

Headers requeridos:

  • Authorization: Bearer {token}

  • x-secret-id: {secretId}

Respuesta exitosa (200):

  • Array de bancos con id, name e image

  • Cada banco incluye el ID requerido para el campo bankId en pagos PSE

Relación con otros endpoints:

  • El id del banco se usa en data.bankId del endpoint POST /products-payment/create cuando el medio de pago es PSE

  • documentType se debe asignar unas de estas opciones:

    • CC = Cedula de ciudadania

    • CE = Cedula de extranjeria

    • NIT = Nit

  • typePerson se debe asignar una de estas opciones:

    • 0 = Natural

    • 1 = Juridico

Ejemplo de uso en pago PSE:

{
  "requestId": "uuid-request",
  "id": 56, // ID del medio de pago PSE
  "categoryid": 61,
  "data": {
    "bankId": "1007", // ID obtenido de este endpoint
    "name": "Juan Perez",
    "email": "[email protected]",
    "cellphone": "3001234567",
    "typePerson": "0", 
    "documentType": "CC", 
    "documentNumber": "1234567890"
  }
}

Parámetros:

| Name | Type | Description | | --- | --- | --- | | secretId | string | Header personalizado: x-secret-id |

products_payment_create

Endpoints para crear pagos de productos

  • Campo cartId (OBLIGATORIO): ID del carrito obtenido de /product-requests/create

  • Filosofía "Always Cart": Todos los productos (individuales o múltiples) usan carrito

Ejemplo correcto:

{
  "cartId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "id": 304135,
  "categoryid": 176,
  "data": { "cellphone": "3051000002" },
  "returnUrl": "https://mi-app.com/return",
  "webhookUrl": "https://mi-app.com/webhook"
}

Crea el pago de un producto usando el medio de pago seleccionado. Esta es la etapa final del proceso de pago.

📋 Relación con Endpoint de Solicitud:
Los datos para crear este pago provienen de la respuesta del endpoint product-requests/create:

  • cartId: Del campo cartId de la respuesta de solicitud

  • id: Del campo id del medio de pago seleccionado

  • categoryid: Del campo categoryid del medio de pago seleccionado

  • data: Basado en template_data_request del medio de pago seleccionado

Headers requeridos:

  • Authorization: Bearer {token}

  • x-secret-id: {secretId}

Body (JSON):

  • cartId (string, requerido): ID de la solicitud obtenido de product-requests/create

  • id (number, requerido): ID del medio de pago seleccionado

  • categoryid (number, requerido): ID de la categoría del medio de pago

  • data (object, requerido): Datos del pagador basados en template_data_request del medio de pago

  • returnUrl (string, opcional): URL de retorno después del pago

  • webhookUrl (string, opcional): URL para notificaciones de estado del pago

🔄 Flujo de Creación de Pago:

1. Respuesta de creación de solicitud:

{
  "statusCode": 201,
  "message": "Solicitud creada exitosamente",
  "date": 1754945173974,
  "payload": {
    "cartId": "15974df4-a599-4d28-a2f2-bb5b8faa678b",
    "requestId": "25884df4-a599-4d28-a2f2-bb5b8faa788a",
    "amount": 9999,
    "paymentMethods": [
      {
        "id": 304135,
        "name": "Transfiya",
        "internal_name": "AppFormTransfiya",
        "description": "Transfiya",
        "categoryid": 176,
        "image": "transfiya.png",
        "template_data_request": {
          "cellphone": "3208888888"
        }
      },
      {
        "id": 56,
        "name": "PSE",
        "internal_name": "AppFormPse",
        "description": "PSE",
        "categoryid": 61,
        "image": "pse.png",
        "template_data_request": {
          "name": "Juan Perez",
          "email": "[email protected]",
          "bankId": "1007",
          "cellphone": "3208888888",
          "typePerson": "0",
          "documentType": "CC",
          "documentNumber": "1032222222"
        }
      }
    ]
  }
}

2. Crear pago con Transfiya (ejemplo):

{
  "cartId": "15974df4-a599-4d28-a2f2-bb5b8faa678b",
  "id": 304135,
  "categoryid": 176,
  "data": {
    "cellphone": "3051000002"
  },
  "returnUrl": "https://plataforma.refacil.co/#/",
  "webhookUrl": "https://webhook.site/4083efe6-7809-40ac-bbaa-9271d4a0c853"
}

3. Crear pago con PSE (ejemplo):

{
  "cartId": "15974df4-a599-4d28-a2f2-bb5b8faa678b",
  "id": 56,
  "categoryid": 61,
  "data": {
    "name": "Juan Perez",
    "email": "[email protected]",
    "bankId": "1007",
    "cellphone": "3051000002",
    "typePerson": "0",
    "documentType": "CC",
    "documentNumber": "1032222222"
  },
  "returnUrl": "https://plataforma.refacil.co/#/",
  "webhookUrl": "https://webhook.site/4083efe6-7809-40ac-bbaa-9271d4a0c853"
}

💳 Estructura de Datos por Medio de Pago:

Medios Simples (Solo celular):

  • Transfiya, Nequi, Daviplata

  • Campo data: {"cellphone": "3051000002"}

Medios Bancarios (Datos completos):

  • PSE, Bancolombia

  • Campo data: {"name", "email", "bankId", "cellphone", "typePerson", "documentType", "documentNumber"}

🔗 URLs de Configuración:

  • returnUrl: URL donde la pasarela de pago redirige al usuario después del pago

  • webhookUrl: URL donde se envían notificaciones de cambios de estado del pago

Respuesta exitosa (201):

{
    "statusCode": 201,
    "message": "Recurso de pago creado exitosamente",
    "date": 1755026415574,
    "payload": {
        "cartId": "88d0b575-80f4-4f9b-af8f-5d09ec2cb877",
        "url": "https://mf-core.refacil.co/refacilpay/resumen/62/5ff47b60-77b1-11f0-b5e9-6f43bd8928c1",
        "reference": "5ff47b60-77b1-11f0-b5e9-6f43bd8928c1",
        "amount": 19000
        "expiresIn": "2025-08-13T07:20:15.038Z"
    }
}

📋 Datos de la Respuesta:

  • reference: Identificador único del pago

  • url: URL para redirigir al usuario al gateway de pagos

  • amount: Monto a pagar

  • cartId: ID del carrito que tiene las solicitudes de productos creadas

  • expiresIn: Fecha y hora de expiracion del recurso de pago

🔄 Siguiente Paso - Procesamiento:

  1. Redirigir usuario: Usar url para enviar al usuario al gateway de pagos

  2. Procesar pago: El usuario completa el pago en el gateway

  3. Recibir notificaciones: El webhookUrl recibe actualizaciones de estado

  4. Redirigir retorno: El usuario regresa a returnUrl después del pago

Respuesta de error (400):

{
  "statusCode": 400,
  "message": "Datos de entrada inválidos",
  "date": 1754945173974,
  "payload": {
    "error": "INVALID_INPUT_DATA",
    "details": "El campo data no coincide con el template del medio de pago"
  }
}

Respuesta de error (404):

{
  "statusCode": 404,
  "message": "Solicitud no encontrada",
  "date": 1754945173974,
  "payload": {
    "error": "REQUEST_NOT_FOUND",
    "details": "La solicitud especificada no existe o ha expirado"
  }
}

Respuesta de error (401):

{
  "statusCode": 401,
  "message": "Error de autenticación",
  "date": 1754924521985,
  "payload": {
    "error": "AUTHENTICATION_ERROR",
    "details": "Authentication failed",
    "originalStatus": 401
  }
}

Parámetros:

| Name | Type | Description | | --- | --- | --- | | secretId | string | Header personalizado: x-secret-id | | cartId | string | Campo del body: cartId | | id | number | Campo del body: id | | categoryid | number | Campo del body: categoryid | | data | object | Campo del body: data | | returnUrl | string | Campo del body: returnUrl | | webhookUrl | string | Campo del body: webhookUrl |

products_refund_create

Endpoints para crear reembolsos

Crea un reembolso para un request específico. Usado cuando un pago fue exitoso pero la venta falló.

Headers requeridos:

  • Authorization: Bearer {token}

  • x-secret-id: {secretId}

Body (JSON):

  • requestId (string, requerido): ID del request a reembolsar

  • keyBreB (string, requerido): Clave BreB del cliente (número de celular u otro identificador)

  • email (string, requerido): Email del cliente

  • webhookUrl (string, requerido): URL para notificaciones del reembolso

Respuesta exitosa (201):

{
  "statusCode": 201,
  "message": "Refund creado exitosamente",
  "date": 1704441600000,
  "payload": {
    "requestId": "0aaef286-867c-486d-bf98-3a16eeabad5c",
    "reference": "00af1036-2473-4014-9c50-4d350ccc2560",
    "keyBreB": "3051000002",
    "amount": "9999.00"
  }
}

Respuesta de error (400):

{
  "statusCode": 400,
  "message": "Datos de entrada inválidos",
  "date": 1704441600000,
  "payload": {
    "error": "INVALID_REQUEST_ID",
    "requestId": "req-uuid-1234-5678-9abc"
  }
}

Respuesta de error (401):

{
  "statusCode": 401,
  "message": "Error de autenticación",
  "date": 1754924521985,
  "payload": {
    "error": "AUTHENTICATION_ERROR",
    "details": "Authentication failed",
    "originalStatus": 401
  }
}

Parámetros:

| Name | Type | Description | | --- | --- | --- | | secretId | string | Header personalizado: x-secret-id | | requestId | string | Campo del body: requestId | | keyBreB | string | Campo del body: keyBreB | | email | string | Campo del body: email | | webhookUrl | string | Campo del body: webhookUrl |

docs_cli_web_documentation

Guía para implementar webhooks del lado del cliente para recibir notificaciones de pagos y reembolsos

📋 IMPORTANTE: Implementación de Webhooks del Cliente Requerida

Este NO es un endpoint de la API, sino una guía para implementar webhooks en TU sistema.

🔄 Lo que Necesitas Implementar:

Para recibir notificaciones de estado de pagos y reembolsos, DEBES implementar endpoints webhook en tu sistema:

1. Webhook de Estado de Pago

  • URL: Tu endpoint (ej., https://tu-dominio.com/webhooks/estado-pago)

  • Método: POST

  • Propósito: Recibir actualizaciones de estado de pago (SOLD, REFUNDED, CANCELLED)

2. Webhook de Estado de Reembolso

  • URL: Tu endpoint (ej., https://tu-dominio.com/webhooks/estado-reembolso)

  • Método: POST

  • Propósito: Recibir actualizaciones de estado de reembolso (CONFIRMED, FAILED)

🔑 Cómo Configurar:

  1. Implementa endpoints webhook en tu sistema

  2. Proporciona las URLs en el campo webhookUrl al crear pagos/reembolsos

  3. Valida las firmas usando HMAC-SHA1 y tu hashKey

📚 Documentación Disponible:

  • Guía de Webhooks del Cliente: client-webhook-documentation.md Solicitar a soporte si es necesario

  • Ejemplos de Código: webhook-examples.md Solicitar a soporte si es necesario

  • Validación de Firmas: Algoritmo HMAC-SHA1

⚠️ Requisitos de Seguridad:

  • Tu webhook debe responder con HTTP 200-299 en menos de 10 segundos

  • Valida el campo signature usando HMAC-SHA1

  • Solicita tu hashKey al equipo de soporte

    • 📞 Proceso de obtención:

      • 1. Contacta al equipo de soporte para solicitar integración

      • 2. Recibirás tu `hashKey` único para validación de firmas

      • 3. Configura este `hashKey` de forma segura en tu aplicación

Ejemplo de payload webhook que recibirás:

Notificacion de Rembolso

Datos a firmar: `refundId-amount-timestamp`

Estados Posibles:

CONFIRMED: Reembolso confirmado y procesado

FAILED: Reembolso falló

{
  "refundId": "ref-uuid-1234-5678-9abc",
  "reference": "refund_ref_987654321",
  "status": "CONFIRMED",
  "amount": 9999,
  "method": "BRE-B",
  "destination": "3208385715",
  "requestId": "15974df4-a599-4d28-a2f2-bb5b8faa678b",
  "timestamp": "2024-01-15T10:35:45.123Z",
  "signature": "b9c8d7e6f5g4h3i2j1k0l9m8n7o6p5q4r3s2t1u0v9w8x7y6z5"
}

Notificacion de Pago

Datos a firmar: `cartId-amount-timestamp`

Estados del Carrito (campo `status` de nivel superior):

  • COMPLETED: Todos los productos del carrito fueron vendidos exitosamente
  • PARTIALLY_REFUNDED: Algunos productos vendidos, otros reembolsados
  • FULLY_REFUNDED: Todos los productos del carrito fueron reembolsados
  • CANCELLED: Pago no confirmado por el proveedor

Estados de Producto Individual (campo `products[].status`):

  • SOLD: Producto vendido exitosamente
  • REFUNDED: Pago exitoso pero venta del producto falló, se inició reembolso
  • CANCELLED: Pago no confirmado para este producto
{
  "cartId": "15974df4-a599-4d28-a2f2-bb5b8faa678b",
  "reference": "topup_ref_123456789",
  "status": "COMPLETED",
  "amount": 20000, 
  "products":[
    {
      "requestId": "85774df4-a599-4d28-a2f2-bb5b8faa678b",
      "status": "SOLD",
      "amount": 10000,
      "billData": {
        "customerName": "Juan Perez",
        "dueDate": "2024-02-15",
        "totalAmount": 10000
      }
    },
    {
      "requestId": "95774df4-b599-5d28-c2f2-cc5b8faa678c",
      "status": "SOLD",
      "amount": 10000,
      "billData": {
        "customerName": "Maria Garcia",
        "dueDate": "2024-02-20",
        "totalAmount": 10000
      }
    }
  ],
  "timestamp": "2024-01-15T10:30:45.123Z",
  "signature": "a8b7c9d2e3f4g5h6i7j8k9l0m1n2o3p4q5r6s7t8u9v0w1x2y3z4"
}

Ejemplo con estado PARTIALLY_REFUNDED:

{
  "cartId": "25974df4-b599-5d28-c2f2-cc5b8faa678d",
  "reference": "topup_ref_987654321",
  "status": "PARTIALLY_REFUNDED",
  "amount": 20000,
  "products": [
    {
      "requestId": "a5774df4-c599-6d28-d2f2-dd5b8faa678e",
      "status": "SOLD",
      "amount": 10000,
      "billData": {
        "customerName": "Carlos Lopez",
        "dueDate": "2024-02-18",
        "totalAmount": 10000
      }
    },
    {
      "requestId": "b5774df4-d599-7d28-e2f2-ee5b8faa678f",
      "status": "REFUNDED",
      "amount": 10000,
      "errorMessage": "Venta falló en proveedor externo"
    }
  ],
  "timestamp": "2024-01-15T10:35:45.123Z",
  "signature": "c9d8e7f6g5h4i3j2k1l0m9n8o7p6q5r4s3t2u1v0w9x8y7z6a5"
}

Ejemplo de codigo para validacion de firma

import crypto from 'crypto';
function validateSignature(payload: any, receivedSignature: string): boolean {
  // Extraer datos para la firma
  const id = payload.cartId || payload.refundId;
  const amount = payload.amount;
  const timestamp = payload.timestamp;
  // Crear string a hashear (MISMO ORDEN)
  const dataToHash = `${id}-${amount}-${timestamp}`;
  // Generar firma esperada usando tu hashKey (proporcionado por soporte)
  const expectedSignature = crypto
    .createHmac('sha1', YOUR_HASH_KEY)  // ← Tu hashKey de soporte
    .update(dataToHash)
    .digest('hex');
  // Comparación segura de firmas
  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature, 'hex'),
    Buffer.from(receivedSignature, 'hex')
  );
}

📝 Logs

El servidor genera logs detallados de todas las operaciones:

[2024-01-01T12:00:00.000Z] get_users iniciada
[2024-01-01T12:00:01.000Z] get_users completada exitosamente

🔍 Troubleshooting

Error de autenticación

Verificar que las credenciales estén configuradas correctamente en las variables de entorno.

Error de conexión a la API

Verificar que BASE_URL sea accesible y la API esté funcionando.

Error de puerto

Verificar que el puerto 3008 no esté siendo usado por otro servicio.

📞 Soporte

Para soporte técnico, contactar al equipo de desarrollo.


Generado automáticamente por Refacil MCP Framework