Proceso de seguridad
La API implementa diferentes niveles de seguridad:
Servicios planos (sin firma ni cifrado) Usados principalmente en ambientes de desarrollo/pruebas.
Servicios con firma digital (JWS)
Garantizan integridad, autenticidad y no repudio.
Requieren intercambio de certificados y uso de llaves privadas/públicas.
(Opcional) Tramas cifradas Según requerimientos del proyecto.
Adicionalmente:
La comunicación se realiza sobre HTTPS.
Se recomienda uso de VPN entre la Entidad Financiera Recaudadora y el comercio.
Servicios planos (sin seguridad)
Para agilizar el desarrollo de la integración se dispone de endpoints de prueba sin firma ni cifrado:
Generar QR (imagen Base64)
https://<URL-TEST>/ws-qr-service/qr/simple/encript64Bloquear QR
https://<URL-TEST>/ws-qr-service/qr/simple/bloquedConsultar QR
https://<URL-TEST>/ws-qr-service/qr/simple/details
En producción se recomienda utilizar la capa de seguridad con firma digital JWS.
Firma digital JWS
La capa de seguridad utiliza el estándar JWS (JSON Web Signature) para firmar digitalmente las tramas JSON.
Flujo general
Generar par de llaves
Llave privada y certificado digital (X.509 en formato PEM).
Intercambio de certificados públicos
El comercio envía su certificado público a Tesabiz.
Tesabiz envía su certificado público al comercio.
Construcción de la trama JSON normal
Según los esquemas descritos en los endpoints (por ejemplo,
infoTx+qrCobro).
Firma JWS
El comercio firma la trama con su llave privada usando una librería JWS (ej. algoritmo
RS256).
Construcción del payload para seguridad
{
"code": "CODIGOCOMERCIO",
"payload": "<TRAMA_FIRMADA_JWS>"
}code: código de empresa en el sistema QR-Comercio (provisto por Tesabiz).payload: cadena JWS resultante de firmar el JSON.
Consumo de servicios seguros
Generar QR (texto hash)
https://<URL-TEST>/tesabiz-ws-security/sc/jws/encriptGenerar QR (imagen Base64)
https://<URL-TEST>/tesabiz-ws-security/sc/jws/encript64
Respuesta de servicios seguros
La respuesta tiene la forma:
{
"codReturn": "0",
"txtReturn": "SUCCESS",
"payload": "<TRAMA_FIRMADA_JWS_RESPUESTA>"
}El comercio debe validar la firma del campo
payloadusando el certificado público de Tesabiz y luego decodificar la trama para obtener el JSON real (equivalente a las respuestas descritas en la sección de endpoints).
Confirmación de pago con JWS
Para el servicio Recibir Pago QR, el comercio debe:
Exponer un endpoint que reciba:
{ "payload": "<TRAMA_FIRMADA_JWS>" }Validar la firma con el certificado público de Tesabiz.
Parsear el contenido (que tendrá el mismo formato que
qrPagadodescrito en la documentación de endpoints).Responder:
{ "codReturn": "0", "txtReturn": "SUCCESS", "payload": "<TRAMA_FIRMADA_JWS_RESPUESTA>" }
Generación de firma
Con el equipo de QRPay se tiene que compartir su certificado, para esto generamos de esta manera usando openssl
openssl genrsa -out private.key 2048
openssl rsa -in private.key -pubout -out public.key
openssl req -new -key private.key -out request.csr
openssl x509 -req -days 365 -in request.csr -signkey private.key -out certificate.pemEl certificate.pem será el que se tiene compartir con el equipo de QRPay
Ejemplo para enviar el payload firmado
NodeJS
const jwtPrivate = this.configService.get<string>('JWT_PRIVATE');
const bodyEncrypted = jwt.sign({{PAYLOAD_BODY}}, {{PIVATE.KEY}}, {
algorithm: 'RS256',
noTimestamp: true, // IMPORTANTE
});
try {
const response = await axios.post(
`${URL_QRPAY}/tesabiz-ws-security/sc/jws/encript64`,
{
code: 'B89',
payload: bodyEncrypted,
},
);
Tabla importante
noTimestamp
enviarle como verdadero
code
Código de su empresa registrada en Plataforma QRPay - pedir al encargado
body
El cuerpo encriptado
Validación de firma para el cliente
const qrpayPublicKey =
this.configService.get<string>('QRPAY_PUBLIC_KEY');
const decoded = jwt.verify({{PAYLOAD_RESPONSE_ENCRYPTED}}, {{PUBLIC_KEY_QRPAY}}, {
algorithms: ['RS256'],
});Tabla importante
QRPAY_PUBLIC_KEY
La llave publica compartida por el equipo de QRPAY
Last updated