Requiere Node.js 22 o superior. Instalar con npm install y configurar .env usando .env.example como referencia, conservando el token existente.
npm.cmd start
# Desarrollo con recarga automática:
npm.cmd run devGET http://localhost:3000/dni/01234567: DNI de exactamente 8 dígitos.GET http://localhost:3000/ruc/20131312955: RUC de exactamente 11 dígitos.GET http://localhost:3000/health: disponibilidad del proceso, sin consultar al proveedor.
La validación local comprueba formato y longitud; la existencia e identidad se verifican con APIsPERU.
Respuesta exitosa: { "success": true, "data": { ...datosDelProveedor } }.
Respuesta de error: { "success": false, "error": { "code": "...", "message": "...", "requestId": "..." } }.
Estados: 400 documento inválido, 403 origen bloqueado, 404 ruta/documento no encontrado, 429 límite local, 502 fallo/respuesta inválida del proveedor, 503 límite del proveedor, 504 timeout y 500 error interno. Los errores internos no exponen mensajes del proveedor ni el token.
APIS_PERU_TOKEN: token usado exclusivamente en el servidor comoAuthorization: Bearer.LICENSING_API_TOKEN: secreto administrativo de al menos 32 caracteres para emitir licencias; si falta, la ruta de emisión queda deshabilitada.LICENSING_UI_ENABLED: usartruepara habilitar el formulario de emisión. Mantener enfalsesalvo que se limite el acceso con protección del deployment (Vercel Deployment Protection) o localhost.LICENSING_PRIVATE_KEY_PATH: ruta local al PEM Ed25519 privado. Por defectoprivate/licensing/arcna1.pem. En un despliegue configuraLICENSING_PRIVATE_KEYcomo variable secreta en lugar de subir el archivo.PORT: 3000 por defecto.HOST:127.0.0.1por defecto;0.0.0.0para escuchar fuera del equipo/contenedor.CORS_ORIGINS: orígenes separados por comas, sin rutas. Por defectohttp://localhost:5173,http://localhost:3000.RATE_LIMIT_WINDOW_MS: ventana de 60000 ms por defecto.RATE_LIMIT_MAX: 30 solicitudes por IP, compartidas entre DNI y RUC, por ventana.TRUST_PROXY: vacío por defecto; configurar únicamente IP/subred del proxy confiable (por ejemplo127.0.0.1). No habilitar confianza global en cabeceras enviadas por clientes.
El límite usa memoria del proceso: se reinicia al arrancar y cada instancia tiene su contador. Para varias instancias se necesita un almacén compartido, por ejemplo Redis. CORS controla acceso desde navegadores, no autentica clientes; las consultas DNI/RUC no agregan autenticación de consumidores. La ruta administrativa de emisión requiere su propio token. Para publicación usar HTTPS y el control de acceso correspondiente a la aplicación.
Se incluyen Helmet, identificadores de solicitud, Cache-Control: no-store, tiempo de espera de 15 segundos al proveedor y cierre ordenado. No se registran números de documento, datos personales ni tokens.
Abre GET /licenses/issue para usar el formulario privado. Solo necesitas ingresar el ID del cliente: el servidor usa LICENSING_API_TOKEN internamente y nunca lo envía al navegador. El formulario muestra el código junto con su QR descargable.
La interfaz y su ruta POST /api/licenses/issue/ui están desactivadas por defecto. Para habilitarlas, establece LICENSING_UI_ENABLED=true y protege todo el deployment con Vercel Deployment Protection o limita el servidor a localhost/red administrativa. No publiques esta ruta sin una barrera de acceso: cualquiera que pueda invocarla podría emitir licencias. En producción usa HTTPS. El endpoint JSON original POST /api/licenses/issue permanece protegido por el encabezado Authorization con el token interno.
El endpoint autenticado también se puede usar directamente después de confirmar manualmente el pago:
POST /api/licenses/issue
Authorization: Bearer <LICENSING_API_TOKEN>
Content-Type: application/json
{"installationId":"ID-DE-32-DIGITOS-HEX"}También está disponible como POST /licenses/issue. El ID acepta guiones y espacios. Una respuesta 201 contiene el código en data.license y el QR PNG como data.qrDataUrl. La API no confirma pagos ni crea pedidos; quien la opera debe verificar el pago y el ID antes de solicitar la emisión. La ruta limita a 5 solicitudes por ventana configurada y no está habilitada si falta el secreto administrativo.
En local, guarda la clave en private/licensing/arcna1.pem, excluida de Git. En Vercel u otro host, configura LICENSING_API_TOKEN y LICENSING_PRIVATE_KEY como secretos de entorno, además del token de APIsPERU para las consultas. Activa LICENSING_UI_ENABLED=true solo después de habilitar Deployment Protection. Nunca envíes esos secretos desde el cliente.
npm.cmd test
# Mantiene el modo de consulta por consola:
npm.cmd run consultar -- ruc 20131312955Las pruebas usan respuestas simuladas y no consumen la cuota de APIsPERU.
La entrada app.js exporta la aplicación Express sin abrir un puerto. vercel.json selecciona el framework Express. El servidor de src/server.js se conserva para ejecución local.
- Subir estos cambios y configurar la raíz del proyecto en la carpeta que contiene
package.jsonyapp.js. - En Settings → Environment Variables agregar
APIS_PERU_TOKENpara Production (y Preview si se necesita). Para habilitar emisión, configurar tambiénLICENSING_API_TOKENyLICENSING_PRIVATE_KEYcomo secretos. - Si se desea usar el formulario, configurar Deployment Protection para impedir el acceso público al deployment y agregar
LICENSING_UI_ENABLED=true. Mantenerlo enfalsesi no se ha protegido el acceso. El.envlocal no se sube al repositorio. - Si se consulta desde una web, configurar
CORS_ORIGINScon el origen de esa web, por ejemplohttps://mi-frontend.vercel.app, sin barra final. Se pueden incluir varios separados por comas. - Quitar overrides anteriores de Build Command y Output Directory; usar el framework Express y sus valores predeterminados.
- Hacer un nuevo deployment después de configurar las variables.
Endpoints públicos, reemplazando TU-PROYECTO por el dominio del deployment:
GET https://TU-PROYECTO.vercel.app/api/dni/01234567
GET https://TU-PROYECTO.vercel.app/api/ruc/20131312955
GET https://TU-PROYECTO.vercel.app/api/health
También funcionan las rutas originales /dni/:numero, /ruc/:numero y /health. / devuelve un listado de endpoints. No se envía el token de APIsPERU desde el cliente.
/api/health verifica el proceso incluso si falta el token; las consultas requieren APIS_PERU_TOKEN. Si devuelve 500, revisar las variables del deployment; si devuelve 403 con ORIGIN_NOT_ALLOWED, revisar CORS_ORIGINS. El límite en memoria se aplica por instancia de Vercel, no es una cuota global del deployment.