Avisos a tu sistema
Cuando cambia un cobro, te pegamos un POST https en la URL del panel. Respondé 2xx. Si no, lo reintentamos.
Qué te llega
POST https://tudominio.com/webhooks/tiki
Content-Type: application/json
X-Tiki-Event: payment.approved
X-Tiki-Timestamp: 1710000000
X-Tiki-Signature: sha256=3f1c…
{
"event": "payment.approved",
"cobro_id": 12,
"codigo": "TKI1-AB12CD34",
"estado": "PAGADA",
"monto": "15000.00",
"monto_cobrado": "15000.00",
"transaccion_id": 88
}$raw = file_get_contents('php://input');
$ts = isset($_SERVER['HTTP_X_TIKI_TIMESTAMP']) ? $_SERVER['HTTP_X_TIKI_TIMESTAMP'] : '';
$hdr = isset($_SERVER['HTTP_X_TIKI_SIGNATURE']) ? $_SERVER['HTTP_X_TIKI_SIGNATURE'] : '';
$sig = (strpos($hdr, 'sha256=') === 0) ? substr($hdr, 7) : $hdr;
$calc = hash_hmac('sha256', $ts . '.' . $raw, $secret);
if (!hash_equals($calc, $sig)) {
header('HTTP/1.1 401');
exit;
}
$data = json_decode($raw, true);
header('HTTP/1.1 200');
// $data['event'], $data['cobro_id'], $data['estado']const crypto = require('crypto');
function ok(raw, ts, header, secret) {
const sig = String(header || '').replace(/^sha256=/, '');
const calc = crypto.createHmac('sha256', secret)
.update(ts + '.' + raw)
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(calc), Buffer.from(sig));
}
// Express
app.post('/webhooks/tiki', express.raw({ type: 'application/json' }), (req, res) => {
const raw = req.body.toString('utf8');
if (!ok(raw, req.get('X-Tiki-Timestamp'), req.get('X-Tiki-Signature'), secret)) {
return res.status(401).end();
}
const data = JSON.parse(raw);
res.status(200).end();
});HTTP/1.1 200 OK (vacío alcanza)
Eventos
| Evento | Cuándo | estado en el cuerpo |
|---|---|---|
| payment.created | Creaste el cobro | PENDIENTE |
| payment.pending | Está en proceso | PENDIENTE / EN_PROCESO |
| payment.approved | Se acreditó | PAGADA |
| payment.partially_paid | Pago parcial | PAGADA_PARCIALMENTE |
| payment.rejected | No se acreditó o venció | CANCELADO |
| payment.refunded | Devolviste todo | DEVUELTA |
| payment.partially_refunded | Devolviste una parte | DEVUELTA_PARCIALMENTE |
La firma es HMAC-SHA256 de timestamp + '.' + body con la clave del panel. La URL tiene que ser https.