PAGREAL · API DE INTEGRACIÓN v1
Guía pública de integración para cuentas Site y Mixto.
Versión documentada: PagReal v8.3.0
Base pública: https://api.pagreal.com/v1
Esta documentación explica cómo autenticar una integración, consultar el estado de la cuenta, validar credenciales, leer la configuración de cobro y verificar pagos. También explica cómo funciona la cuota diaria de verificaciones del plan.
1. Antes de comenzar #
Necesitas un token activo generado desde la sección API de PagReal.
Todas las peticiones deben enviarse por HTTPS. No necesitas enviar user_id: el token identifica automáticamente a la cuenta propietaria de la consulta.
Los tokens de integración usan exclusivamente el prefijo prt_.
Header recomendado #
Authorization: Bearer prt_TU_TOKEN_SECRETOEn solicitudes POST agrega además:
Content-Type: application/jsonTambién se admite el header alternativo de PagReal:
X-PagReal-Token: prt_TU_TOKEN_SECRETOBuenas prácticas con el token #
- Trátalo como una contraseña privada de servidor.
- No lo publiques en JavaScript del navegador, HTML público, repositorios ni capturas.
- Si sospechas que fue expuesto, genera un nuevo token desde la app. El anterior dejará de funcionar.
- Tu integración nunca debe enviar un
user_idpara decidir a quién pertenece una consulta.
2. Respuestas comunes #
Token no enviado · HTTP 401 #
{
"ok": false,
"code": "TOKEN_REQUIRED",
"message": "Token de integración requerido."
}Token inválido o revocado · HTTP 401 #
{
"ok": false,
"code": "TOKEN_INVALID",
"message": "Token de integración inválido o revocado."
}Cuenta inactiva · HTTP 403 #
{
"ok": false,
"code": "ACCOUNT_INACTIVE",
"message": "La cuenta asociada al token está inactiva."
}Límite técnico de frecuencia · HTTP 429 #
{
"ok": false,
"code": "RATE_LIMITED",
"message": "Demasiadas solicitudes. Intenta nuevamente en unos segundos.",
"retryAfter": 12
}RATE_LIMITED es una protección técnica temporal. Es independiente de la cuota comercial diaria de tu plan.
3. GET /account #
Devuelve los datos básicos de la cuenta asociada al token y el estado de su plan.
Solicitud #
curl \
-H "Authorization: Bearer prt_TU_TOKEN_SECRETO" \
https://api.pagreal.com/v1/accountRespuesta · HTTP 200 #
{
"ok": true,
"accountType": "user",
"user": {
"id": "e7815f58-8457-11f1-ba19-020000cfa43c",
"username": "mi_integrador",
"name": "Mi negocio",
"role": "site"
},
"access": {
"subscriptionRequired": true,
"active": true,
"status": "active",
"daysRemaining": 18,
"expiresAt": "2026-09-21T23:59:59.000Z",
"nextPaymentDate": "21/09/2026",
"planName": "Básico"
},
"passwordSecurity": {
"algorithm": "scrypt",
"hashExposed": false,
"verifyEndpoint": "/v1/auth/verify"
}
}Qué debes usar #
user.rolepuede sersiteomixedpara integraciones de clientes.access.activeindica si el plan permite operar.access.daysRemainingindica los días restantes.- La API nunca entrega la contraseña ni su hash.
4. POST /auth/verify #
Permite validar el usuario y contraseña de la misma cuenta identificada por el token.
No se puede utilizar el token de una cuenta para validar la contraseña de otra.
Solicitud #
curl -X POST \
https://api.pagreal.com/v1/auth/verify \
-H "Authorization: Bearer prt_TU_TOKEN_SECRETO" \
-H "Content-Type: application/json" \
-d '{
"username": "mi_integrador",
"password": "CLAVE_ESCRITA_POR_EL_USUARIO"
}'Credenciales correctas y plan activo · HTTP 200 #
{
"ok": true,
"valid": true,
"accountType": "user",
"subscriptionRequired": true,
"accessActive": true,
"daysRemaining": 18
}Credenciales correctas pero plan vencido · HTTP 200 #
{
"ok": true,
"valid": true,
"accountType": "user",
"subscriptionRequired": true,
"accessActive": false,
"daysRemaining": 0
}Usuario o contraseña incorrectos · HTTP 200 #
{
"ok": true,
"valid": false,
"accountType": "user",
"subscriptionRequired": true,
"accessActive": false,
"daysRemaining": 0
}5. GET /config #
Devuelve el estado del acceso, el estado del monitoreo bancario y los métodos de pago activos configurados por la cuenta.
Solicitud #
curl \
-H "Authorization: Bearer prt_TU_TOKEN_SECRETO" \
https://api.pagreal.com/v1/configRespuesta con banco activo · HTTP 200 #
{
"ok": true,
"accountType": "user",
"access": {
"subscriptionRequired": true,
"active": true,
"daysRemaining": 18,
"expiresAt": "2026-09-21T23:59:59.000Z"
},
"automaticPayment": {
"active": true,
"state": "active",
"bankCode": "0102",
"accountLast4": "1028",
"lastSuccessAt": "2026-09-03T14:00:00.000Z",
"errorCode": "",
"error": ""
},
"paymentMethods": [
{
"type": "mobile_payment",
"bankCode": "0102",
"phone": "04141234567",
"documentType": "Cédula",
"documentNumber": "12345678"
},
{
"type": "bank_transfer",
"bankCode": "0102",
"accountHolderName": "Nombre Titular",
"documentType": "Cédula",
"documentNumber": "12345678",
"accountNumber": "01020000000000000000"
}
]
}Respuesta con monitoreo pausado · HTTP 200 #
{
"ok": true,
"accountType": "user",
"access": {
"subscriptionRequired": true,
"active": true,
"daysRemaining": 18,
"expiresAt": "2026-09-21T23:59:59.000Z"
},
"automaticPayment": {
"active": false,
"state": "paused",
"bankCode": "0102",
"accountLast4": "1028",
"lastSuccessAt": "2026-09-03T14:00:00.000Z",
"errorCode": "",
"error": ""
},
"paymentMethods": []
}automaticPayment.active solo debe considerarse disponible cuando vale true. Entre los estados visibles pueden aparecer active, paused, error, disconnected o connecting.
6. POST /payments/verify #
Consulta un pago recibido usando referencia, monto, fecha y banco.
Body #
{
"reference": "6439",
"amount": "12,00",
"date": "2026-09-03",
"bankCode": "0102"
}Campos #
reference: obligatorio. Se toman los dígitos y se usan los últimos 4. El resultado debe tener exactamente 4 dígitos.amount: obligatorio y mayor que cero. Acepta formatos como12,00y1.250,50.date: opcional. Si no se envía, se utiliza la fecha actual de Venezuela. AceptaYYYY-MM-DDoDD-MM-YYYY.bankCode: opcional. El valor actual soportado es0102.
Solicitud cURL #
curl -X POST \
https://api.pagreal.com/v1/payments/verify \
-H "Authorization: Bearer prt_TU_TOKEN_SECRETO" \
-H "Content-Type: application/json" \
-d '{
"reference": "6439",
"amount": "12,00",
"date": "2026-09-03",
"bankCode": "0102"
}'Pago encontrado por primera vez · HTTP 200 #
{
"ok": true,
"accountType": "user",
"found": true,
"alreadyConsulted": false,
"status": "FOUND",
"payment": {
"id": "uuid-del-historial",
"reference": "6439",
"amount": 12,
"bankCode": "0102",
"date": "2026-09-03"
},
"usage": {
"charged": true,
"used": 7,
"limit": 150,
"remaining": 143
}
}Pago encontrado que ya se había consultado · HTTP 200 #
{
"ok": true,
"accountType": "user",
"found": true,
"alreadyConsulted": true,
"status": "ALREADY_CONSULTED",
"payment": {
"id": "uuid-del-historial",
"reference": "6439",
"amount": 12,
"bankCode": "0102",
"date": "2026-09-03"
},
"usage": {
"charged": false,
"used": 7,
"limit": 150,
"remaining": 143
}
}Pago no encontrado · HTTP 200 #
{
"ok": true,
"accountType": "user",
"found": false,
"alreadyConsulted": false,
"status": "NOT_FOUND",
"payment": {
"id": "uuid-del-historial",
"reference": "7352",
"amount": 864,
"bankCode": "0102",
"date": "2026-09-03"
},
"usage": {
"charged": true,
"used": 8,
"limit": 150,
"remaining": 142
}
}7. Cómo funciona la cuota diaria del plan #
La cuota comercial se aplica únicamente a POST /payments/verify para cuentas con plan API.
Una solicitud lógica se identifica por esta combinación:
- cuenta propietaria del token;
- banco;
- fecha del pago;
- últimos 4 dígitos de la referencia;
- monto.
Cuándo consume #
Cuando una combinación lógica nueva puede procesarse, consume una unidad de la cuota. Tanto un resultado FOUND como un resultado NOT_FOUND cuentan cuando la consulta fue procesada.
Cuándo NO vuelve a consumir #
Si repites exactamente la misma combinación lógica, la consulta puede volver a ejecutarse pero no consume otra unidad, incluso si se repite más tarde. En la respuesta verás:
{
"usage": {
"charged": false,
"used": 7,
"limit": 150,
"remaining": 143
}
}Esto permite reconsultar el mismo pago sin castigar la cuota del plan.
Límite diario alcanzado · HTTP 429 #
Una combinación lógica nueva que exceda el límite diario responde:
{
"ok": false,
"code": "DAILY_VERIFICATION_LIMIT_REACHED",
"status": "LIMIT_REACHED",
"message": "Has alcanzado el límite diario de verificaciones de tu plan.",
"limit": 150,
"used": 150,
"remaining": 0,
"date": "2026-09-03"
}Una consulta ya conocida puede seguir siendo reconocida como repetida porque no representa una nueva unidad lógica.
Diferencia entre cuota y rate limit #
DAILY_VERIFICATION_LIMIT_REACHED: agotaste la cuota comercial diaria para solicitudes lógicas nuevas.RATE_LIMITED: enviaste demasiadas solicitudes en un periodo corto. Es una protección técnica y temporal.
8. Errores de /payments/verify #
Plan inactivo · HTTP 403 #
{
"ok": false,
"code": "SERVICE_INACTIVE",
"status": "INACTIVE",
"message": "Acceso expirado. Renueva tu plan para continuar.",
"daysRemaining": 0
}Banco automático no disponible · HTTP 409 #
{
"ok": false,
"code": "BANK_MONITOR_INACTIVE",
"status": "UNAVAILABLE",
"message": "El pago automático no está activo en este momento.",
"bankState": "paused",
"bankErrorCode": ""
}Esta respuesta no consume una nueva solicitud lógica porque la verificación no pudo procesarse correctamente.
Referencia inválida · HTTP 400 #
{
"ok": false,
"code": "INVALID_REFERENCE",
"message": "La referencia debe contener los últimos 4 dígitos."
}Monto inválido · HTTP 400 #
{
"ok": false,
"code": "INVALID_AMOUNT",
"message": "Monto inválido."
}Fecha inválida · HTTP 400 #
{
"ok": false,
"code": "INVALID_DATE",
"message": "Fecha inválida. Usa YYYY-MM-DD o DD-MM-YYYY."
}Banco no soportado · HTTP 400 #
{
"ok": false,
"code": "BANK_NOT_SUPPORTED",
"message": "Banco no disponible."
}9. Ejemplo PHP completo #
<?php
$token = 'prt_TU_TOKEN_SECRETO';
$url = 'https://api.pagreal.com/v1/payments/verify';
$payload = [
'reference' => '6439',
'amount' => '12,00',
'date' => '2026-09-03',
'bankCode' => '0102',
];
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_TIMEOUT => 15,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
die('Error de conexión: ' . $error);
}
$data = json_decode($response, true);
if ($httpCode === 429 && ($data['code'] ?? '') === 'DAILY_VERIFICATION_LIMIT_REACHED') {
echo 'Cuota diaria agotada';
exit;
}
switch ($data['status'] ?? $data['code'] ?? '') {
case 'FOUND':
echo 'Pago encontrado';
break;
case 'ALREADY_CONSULTED':
echo 'Pago encontrado y ya consultado anteriormente';
break;
case 'NOT_FOUND':
echo 'Pago no encontrado';
break;
case 'INACTIVE':
case 'SERVICE_INACTIVE':
echo 'Plan inactivo';
break;
case 'UNAVAILABLE':
case 'BANK_MONITOR_INACTIVE':
echo 'Banco automático no disponible';
break;
default:
echo $data['message'] ?? $data['error'] ?? 'Respuesta inesperada';
}10. Flujo recomendado para un sitio web #
- Guarda el token únicamente en el backend de tu sitio.
- Usa
GET /accountal iniciar para conocer la cuenta y el estado del plan. - Usa
GET /configpara saber si el cobro automático está disponible y mostrar los métodos de pago activos. - Si necesitas validar las credenciales del mismo titular, usa
POST /auth/verify. - Cuando el cliente informe un pago, envía referencia, monto, fecha y banco a
POST /payments/verify. - Maneja
FOUND,ALREADY_CONSULTEDyNOT_FOUNDcomo resultados normales de negocio. - Maneja
DAILY_VERIFICATION_LIMIT_REACHED,RATE_LIMITED,SERVICE_INACTIVEyBANK_MONITOR_INACTIVEcomo estados que requieren una acción diferente. - Lee el objeto
usagede cada verificación para conocer si esa consulta consumió cuota y cuántas quedan.
11. Resumen de endpoints #
GET /account #
- Datos básicos de la cuenta del token.
- Rol.
- Plan y vigencia.
- Días restantes.
POST /auth/verify #
- Valida usuario y contraseña de la misma cuenta del token.
- Nunca devuelve hash de contraseña.
GET /config #
- Estado del plan.
- Estado del banco automático.
- Últimos 4 dígitos de la cuenta configurada.
- Métodos de pago activos.
POST /payments/verify #
- Verifica referencia + monto + fecha + banco.
- Devuelve
FOUND,ALREADY_CONSULTEDoNOT_FOUND. - Devuelve información de cuota en
usage. - Las solicitudes lógicas repetidas no vuelven a consumir cuota.
12. Checklist de integración #
- Usa siempre HTTPS.
- Mantén el token fuera del frontend público.
- No envíes
user_idpara elegir la cuenta de una consulta. - Respeta el estado
access.active. - Comprueba
automaticPayment.activeantes de intentar verificar un pago. - Maneja errores HTTP además del campo
ok. - Guarda registros propios de las respuestas importantes para poder auditar tu integración.
- Si recibes
RATE_LIMITED, espera el tiempo indicado antes de reintentar. - Si recibes
DAILY_VERIFICATION_LIMIT_REACHED, no envíes nuevas combinaciones lógicas hasta que la cuota esté disponible nuevamente.
PagReal · API de Integración v1