Configuración
Webhooks
Notify your other systems the moment something happens in Recaudo: a payment, a new customer, an assigned conversation.
Before you start
You need an https URL in your system that accepts POST requests with JSON. Webhooks live in Settings › Advanced › Webhooks (the Alerts to your systems page).
Add an endpoint
Each endpoint receives only the events you choose.
-
Open Webhooks
Go to Settings, open Advanced, choose Webhooks and click New address. -
Enter where to send
Under Where to send alerts paste the Web address (it must start with https) and, optionally, a name or note. Keep Send alerts to this address checked. -
Choose what to send
Under What to send check the events you care about or use Select all. -
Save and copy the signing key
Click Save address. Save your signing key appears (it starts withwhsec_): copy it into your system. -
Send a test
Use Send test to receive atest.webhooknotification and confirm your system responds.
Careful
The signing key is shown only once. If you lose it, open the endpoint details and use Change signing key under Technical details; the old one stops working.
Available events
Events are grouped by module. Some examples:
- Payments and payment links:
payment.succeeded,payment.failed,payment_link.paid. - Invoices and subscriptions:
invoice.paid,subscription.canceled. - Customers and leads:
customer.created,lead.converted. - Conversations:
conversation.assigned,conversation.message.received. - CRM, follow-ups and flows:
deal.won,follow_up.completed,flow_run.completed.
Verify the signature
Every notification includes the X-Recaudo-Signature header with the timestamp (t) and an HMAC-SHA256 signature (v1) of t.body made with your signing key. Compute it yourself and compare before trusting the notification:
X-Recaudo-Signature: t=1760000000,v1=5f2b9c...
X-Recaudo-Event-Id: 9b1d2c3e-...
X-Recaudo-Event-Type: payment.succeeded
<?php
$secret = getenv('RECAUDO_WEBHOOK_SECRET'); // whsec_...
$payload = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_RECAUDO_SIGNATURE'] ?? '';
parse_str(str_replace(',', '&', $header), $parts); // t=...&v1=...
$expected = hash_hmac('sha256', $parts['t'] . '.' . $payload, $secret);
if (! hash_equals($expected, $parts['v1'] ?? '') || abs(time() - (int) $parts['t']) > 300) {
http_response_code(400);
exit;
}
$event = json_decode($payload, true);
http_response_code(200);
const crypto = require('crypto');
// Usa el cuerpo crudo (raw body), no el JSON ya interpretado
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const expected = crypto
.createHmac('sha256', secret)
.update(`${parts.t}.${rawBody}`)
.digest('hex');
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1 || ''));
}
The structure of each event is in the API webhooks reference.
Review deliveries and resend
Your system must reply with a 2xx code. If it does not respond or fails, Recaudo retries up to 5 times with increasingly longer waits.
-
Open the details
In the endpoint list click View details. -
Check Recent deliveries
Each delivery shows as Received, Failed or Pending, with the attempt number, the data sent and your system’s response. -
Resend if needed
Once you fix the problem in your system, use Resend on the failed delivery.
Important
Do not confuse it with Settings › Advanced › Webhook log: that shows the notifications your payment gateways send to Recaudo, not the ones Recaudo sends to you.
Tip
Use
X-Recaudo-Event-Id to ignore duplicates: because of retries, the same event may reach you more than once.Next steps
Was this page helpful?
Thanks for letting us know.