Firma ECDSA-SHA256
Cada request a la API requiere 4 headers firmados con ECDSA-SHA256 (secp256k1). No hay tokens Bearer ni sesiones.
Headers requeridos
Sección titulada «Headers requeridos»| Header | Descripción | Ejemplo |
|---|---|---|
x-client-id | ID de tu API Key | rivo_abc123xyz |
x-timestamp | Fecha/hora actual ISO 8601 (±5 min) | 2026-03-18T14:00:00.000Z |
x-nonce | String único aleatorio por request | a3f9b2c1d8e7... |
x-signature | Firma ECDSA-SHA256 en Base64 | MEYCIQDx... |
Cómo calcular la firma
Sección titulada «Cómo calcular la firma»Construye el siguiente objeto JSON y fírmalo con tu clave privada EC secp256k1:
{ "method": "POST", "path": "/v1/br/payin/pix/instant", "query": "", "body": "{\"amount\":10000,\"amountFormat\":\"cents\",...}", "timestamp": "2026-03-18T14:00:00.000Z", "nonce": "a3f9b2c1d8e7f4a1b2c3d4e5f6a7b8c9"}Pasos:
- Serializa el objeto como JSON (sin espacios extra)
- Firma el string con ECDSA-SHA256 usando tu clave privada secp256k1
- Encode la firma en Base64 → ese es
x-signature
Notas importantes:
- Si el request no tiene body (GET),
"body"va como"" - Si el request tiene query params,
"query"es el stringkey=value&key2=value2sin el?
Ejemplo en Node.js
Sección titulada «Ejemplo en Node.js»const crypto = require('crypto');
function buildHeaders(method, path, query = '', body = '', privateKeyPem, keyId) { const timestamp = new Date().toISOString(); const nonce = crypto.randomBytes(16).toString('hex');
const signedData = JSON.stringify({ method, path, query, body, timestamp, nonce }); const signature = crypto.sign('SHA256', Buffer.from(signedData), privateKeyPem).toString('base64');
return { 'Content-Type': 'application/json', 'x-client-id': keyId, 'x-timestamp': timestamp, 'x-nonce': nonce, 'x-signature': signature, };}Ejemplo en Python
Sección titulada «Ejemplo en Python»import hashlibimport hmacimport jsonimport osimport secretsfrom datetime import datetime, timezonefrom cryptography.hazmat.primitives import hashes, serializationfrom cryptography.hazmat.primitives.asymmetric import ec
def build_headers(method, path, query='', body='', private_key_pem=None, key_id=None): timestamp = datetime.now(timezone.utc).isoformat().replace('+00:00', 'Z') nonce = secrets.token_hex(16)
signed_data = json.dumps({ 'method': method, 'path': path, 'query': query, 'body': body, 'timestamp': timestamp, 'nonce': nonce }, separators=(',', ':'))
private_key = serialization.load_pem_private_key(private_key_pem, password=None) signature = private_key.sign(signed_data.encode(), ec.ECDSA(hashes.SHA256())) signature_b64 = __import__('base64').b64encode(signature).decode()
return { 'Content-Type': 'application/json', 'x-client-id': key_id, 'x-timestamp': timestamp, 'x-nonce': nonce, 'x-signature': signature_b64, }Ejemplo con cURL
Sección titulada «Ejemplo con cURL»# VariablesTIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")NONCE=$(openssl rand -hex 16)KEY_ID="rivo_abc123xyz"BODY='{"amount":10000,"amountFormat":"cents","amountType":"fixed","expirationInSeconds":3600}'
# Construir el string a firmarSIGNED_DATA=$(printf '{"method":"POST","path":"/v1/br/payin/pix/instant","query":"","body":"%s","timestamp":"%s","nonce":"%s"}' \ "$(echo $BODY | sed 's/"/\\"/g')" "$TIMESTAMP" "$NONCE")
# Firmar con clave privadaSIGNATURE=$(echo -n "$SIGNED_DATA" | openssl dgst -sha256 -sign private.pem | base64 | tr -d '\n')
# Hacer el requestcurl -X POST https://api.rivoplay.com/v1/br/payin/pix/instant \ -H "Content-Type: application/json" \ -H "x-client-id: $KEY_ID" \ -H "x-timestamp: $TIMESTAMP" \ -H "x-nonce: $NONCE" \ -H "x-signature: $SIGNATURE" \ -d "$BODY"