Ir al contenido

Seguridad y Antifraude

Seguridad y Antifraude

SanPay está construido con la seguridad en el centro. Desde webhooks firmados con HMAC hasta validación de origen, protegemos cada transacción y punto de integración.

Seguridad de Claves API

Tus claves API son la puerta de entrada a tu cuenta. Sigue estas mejores prácticas:

Separa las Claves por Entorno

Usa `pk_test_*` y `sk_test_*` para desarrollo, `pk_live_*` y `sk_live_*` para producción.

Nunca Expongas Claves Secretas

Las claves secretas (sk_*) deben permanecer en tu servidor. Nunca las incluyas en código cliente o apps móviles.

Rota las Claves Regularmente

Genera nuevas claves API periódicamente y revoca las antiguas desde el panel.

Usa Variables de Entorno

Almacena las claves en variables de entorno, no en repositorios de código.

Tipos de Clave

Tipo de ClavePrefijoUso
Clave Pública pk_live_* / pk_test_* Inicialización SDK del lado del cliente
Clave Secreta sk_live_* / sk_test_* Llamadas API servidor a servidor
Secreto Webhook whsec_* Verificar firmas webhook entrantes

Verificación de Firma Webhook

Cada webhook incluye una firma HMAC-SHA256 para verificar autenticidad y prevenir manipulación.

Formato de Firma

El header `X-Webhook-Signature` contiene:

t=1704556800000,v1=a1b2c3d4e5f6...

Algoritmo de Verificación

  1. Extrae timestamp (t) y firma (v1) del header
  2. Verifica que el timestamp esté dentro de la ventana aceptable (5 minutos)
  3. Calcula esperado: HMAC-SHA256(secret, "{timestamp}.{body}")
  4. Usa comparación timing-safe para verificar la firma
Signature Verification
// PHP Signature Verification
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
// Parse signature
preg_match('/^t=(\d+),v1=([a-f0-9]+)$/', $signature, $matches);
$timestamp = (int) $matches[1];
$receivedHash = $matches[2];
// Check timestamp (5 minute tolerance)
$now = (int) (microtime(true) * 1000);
if (abs($now - $timestamp) > 300000) {
throw new Exception('Signature expired');
}
// Verify signature
$signedPayload = "{$timestamp}.{$payload}";
$expectedHash = hash_hmac('sha256', $signedPayload, $webhookSecret);
if (!hash_equals($expectedHash, $receivedHash)) {
throw new Exception('Invalid signature');
}

¿Por Qué Comparación Timing-Safe?

La comparación estándar de strings puede filtrar información a través de tiempos de respuesta. Los atacantes podrían deducir la firma carácter por carácter. La comparación timing-safe toma tiempo constante independientemente de dónde coincida.

Validación de Origen

El SDK valida que las solicitudes provengan de dominios autorizados:

  • Configura los orígenes permitidos en tu panel SanPay
  • Incluye protocolo, dominio y puerto: https://example.com:443
  • Usa wildcards con precaución: https://*.example.com

Protección Contra Ataques de Replay

Los webhooks incluyen timestamps para prevenir ataques de replay:

  • Rechaza firmas más antiguas de 5 minutos
  • Almacena eventIds procesados para detectar duplicados
  • Toda comunicación vía HTTPS previene espionaje

Límites de Tasa

Los endpoints API tienen límites de tasa para prevenir abuso:

EndpointLímiteVentana
Creación de pago 100 req por minuto
Verificación de estado 300 req por minuto
Lista de activos 60 req por minuto

Mejores Prácticas de Seguridad

Siempre Verifica Webhooks

Nunca proceses un webhook sin verificar su firma. Los atacantes podrían enviar falsas confirmaciones de pago.

Usa Idempotencia

Rastrea eventIds para evitar procesar el mismo evento dos veces, especialmente para cumplimiento de pedidos.

Valida Montos

Siempre compara el monto recibido con el monto esperado. Maneja subpagos y sobrepagos explícitamente.

Solo HTTPS

Entregamos webhooks solo a endpoints HTTPS. Asegúrate de que tu servidor tenga un certificado SSL válido.