Webhooks
Los webhooks avisan a su sistema en el momento en que algo sucede (un firmante firmó, el sobre se concluyó), sin que usted necesite consultar la API repetidamente. Usted registra una dirección HTTPS y Ravisign envía un POST JSON en cada evento, firmado con HMAC-SHA256.
Los webhooks pueden registrarse por la API (acciones siguientes) o en el panel, en Configuración > Webhooks.
En los ejemplos, la clave está en la variable de entorno RAVISIGN_CHAVE y las respuestas se acortaron donde se indica:
export RAVISIGN_CHAVE="rsg_..."
API="https://ravisign.com.br/api/v1"webhooks/criar#
POST, alcance envelopes.escrever. Parámetros url (https, dirección pública, hasta 500 caracteres) y eventos
(lista o texto separado por comas; vacío = todos los eventos). Hasta 10 webhooks por cuenta (409 webhook_limite).
curl -sS "$API/webhooks/criar" -H "Authorization: Bearer $RAVISIGN_CHAVE" \
-H "Content-Type: application/json" \
-d '{"url":"https://integrador.exemplo.com.br/ravisign","eventos":["envelope.concluido","signatario.otp_solicitado"]}'{
"ok": true,
"segredo": "rsgw_48e39ee70a218e351b7020ec4016abc4f917c72ca44356c8",
"webhook": {
"id": 1,
"url": "https://integrador.exemplo.com.br/ravisign",
"eventos": ["envelope.concluido", "signatario.otp_solicitado"],
"ativo": true,
"criado_em": "2026-10-09T20:28:25-03:00",
"ultima_entrega": null
}
}El segredo aparece solo en esta respuesta: guárdelo para verificar la firma de las entregas (consulte Webhooks). Errores: 400
webhook_url_invalida (sin https, dirección interna o inválida), 400 webhook_eventos_invalidos.
webhooks/listar#
GET, alcance envelopes.ler. Webhooks de la cuenta, sin el secreto, con la última entrega.
curl -sS "$API/webhooks/listar" -H "Authorization: Bearer $RAVISIGN_CHAVE"{
"ok": true,
"webhooks": [
{
"id": 1,
"url": "https://integrador.exemplo.com.br/ravisign",
"eventos": ["envelope.concluido", "signatario.otp_solicitado"],
"ativo": true,
"criado_em": "2026-10-09T20:28:25-03:00",
"ultima_entrega": {
"situacao": "entregue",
"http_status": 200,
"tentativas": 1,
"criada_em": "2026-10-09T20:31:02-03:00",
"entregue_em": "2026-10-09T20:31:03-03:00"
}
}
]
}ultima_entrega es null mientras no haya ninguna entrega.
webhooks/testar#
POST, alcance envelopes.escrever. Parámetro id. Envía de inmediato un evento webhook.teste a la dirección y devuelve el
resultado.
curl -sS "$API/webhooks/testar" -H "Authorization: Bearer $RAVISIGN_CHAVE" \
-H "Content-Type: application/json" -d '{"id":1}'{ "ok": true, "id": 1, "entregue": true, "situacao": "entregue", "http_status": 200 }Si el destino no responde 2xx, entregue viene false, situacao viene pendente (la entrega sigue los nuevos
intentos descritos en Webhooks) y http_status trae el estado recibido (o null sin respuesta). Estados de una entrega:
pendente, entregue y falhou (intentos agotados).
webhooks/remover#
POST, alcance envelopes.escrever. Parámetro id.
curl -sS "$API/webhooks/remover" -H "Authorization: Bearer $RAVISIGN_CHAVE" \
-H "Content-Type: application/json" -d '{"id":1}'{ "ok": true, "id": 1, "removido": true }Eventos y entregas#
Ravisign avisa a su sistema con un POST JSON en cada evento al que el webhook está suscrito.
| Evento | Cuándo | dados |
|---|---|---|
envelope.enviado |
el sobre fue enviado a los firmantes | {} |
signatario.visualizou |
el firmante abrió el documento | signatario |
signatario.assinou |
el firmante firmó | signatario |
signatario.recusou |
el firmante rechazó (el sobre queda recusado) |
signatario |
envelope.concluido |
todos firmaron y la copia final está lista | hash_final |
envelope.expirado |
el plazo venció sin todas las firmas | {} |
envelope.cancelado |
el sobre fue cancelado | {} |
signatario.otp_solicitado |
en el canal de conversación, el firmante pidió un código nuevo en la página | signatario, codigo, validade_minutos, expira_em |
webhook.teste |
webhooks/testar (el envelope del cuerpo viene null) |
mensagem |
signatario en los datos es { "uuid", "papel", "ordem" }. El cuerpo nunca incluye nombre, correo electrónico, teléfono ni CPF: use los
uuids para cruzarlos con lo que su sistema ya tiene.
Ejemplo de cuerpo (envelope.concluido):
{
"evento": "envelope.concluido",
"ocorrido_em": "2026-10-09T23:31:02Z",
"envelope": {
"uuid": "157b650a-75e0-4eaa-a32c-b92b5a432ee4",
"referencia_externa": "PEDIDO-1042",
"situacao": "concluido",
"origem": "chatisp"
},
"dados": { "hash_final": "7ced225baf8e20d34cb09a713c4454a632f749ecf31645aa3a640e1660e2a880" }
}Ejemplo de cuerpo (signatario.otp_solicitado):
{
"evento": "signatario.otp_solicitado",
"ocorrido_em": "2026-10-09T23:40:00Z",
"envelope": {
"uuid": "157b650a-75e0-4eaa-a32c-b92b5a432ee4",
"referencia_externa": "PEDIDO-1042",
"situacao": "enviado",
"origem": "chatisp"
},
"dados": {
"signatario": { "uuid": "7eb90fca-1488-4a17-84c4-0b01f4acb9f1" },
"codigo": "815204",
"validade_minutos": 30,
"expira_em": "2026-10-10T00:10:00Z"
}
}Encabezados de cada entrega:
| Encabezado | Contenido |
|---|---|
Content-Type |
application/json |
User-Agent |
Ravisign-Webhook/1 |
X-Ravisign-Evento |
el evento (igual al evento del cuerpo) |
X-Ravisign-Entrega |
identificador de la entrega; el mismo en todos los intentos (úselo para ignorar repeticiones) |
X-Ravisign-Tentativa |
número del intento (1 a 8) |
X-Ravisign-Assinatura |
sha256= seguido del HMAC-SHA256 del cuerpo, en hexadecimal, con el secreto del webhook |
Entrega y nuevos intentos:
- Responda con cualquier estado 2xx en hasta 10 segundos. Procese el evento después de responder, si toma tiempo.
- Sin 2xx (o sin respuesta), Ravisign vuelve a intentarlo después de 1, 5, 15, 60 y 240 minutos y, a partir de ahí, cada 240 minutos, hasta 8 intentos en total. Las redirecciones no se siguen.
- El destino debe ser https con dirección pública.
- El orden de llegada no está garantizado: use
ocorrido_emy, ante la duda, confirme conenvelopes/detalhe.
Verificación de la firma (PHP)#
Calcule el HMAC sobre el cuerpo SIN PROCESAR recibido (antes de decodificar el JSON) y compare en tiempo constante:
<?php
$segredo = getenv('RAVISIGN_WEBHOOK_SEGREDO'); // o "segredo" devolvido por webhooks/criar
$corpo = file_get_contents('php://input');
$recebida = $_SERVER['HTTP_X_RAVISIGN_ASSINATURA'] ?? '';
$esperada = 'sha256=' . hash_hmac('sha256', $corpo, $segredo);
if (!hash_equals($esperada, $recebida)) {
http_response_code(401);
exit;
}
$entrega = $_SERVER['HTTP_X_RAVISIGN_ENTREGA'] ?? '';
// se esta entrega já foi processada (mesmo X-Ravisign-Entrega), apenas responda 200
$evento = json_decode($corpo, true);
http_response_code(200); // responda logo; o trabalho pesado vai para depois
switch ($evento['evento']) {
case 'envelope.concluido':
// baixar a via final com documentos/baixar e guardar $evento['dados']['hash_final']
break;
case 'signatario.otp_solicitado':
// entregar $evento['dados']['codigo'] na conversa do signatário $evento['dados']['signatario']['uuid']
break;
}Escriba al soporte de Ravi Systems al correo de abajo.