Webhooks
Receive real-time notifications when events occur in tPay365. Webhooks are HMAC-signed and delivered with automatic retries.
Event Types
| Parameter | Type | Required | Description |
|---|---|---|---|
| paycheck.calculated | event | Optional | A clean paycheck calculation has completed |
| vault.stored | event | Optional | New PII has been stored in the vault |
| vault.deleted | event | Optional | PII has been permanently deleted (GDPR erasure) |
| payment.executed | event | Optional | A payment has been successfully executed |
| payment.failed | event | Optional | A payment execution has failed |
| employee.activated | event | Optional | An employee has completed activation |
| employee.deactivated | event | Optional | An employee has been deactivated |
Payload Schema
Every webhook payload follows the same envelope format with event metadata and typed data.
Webhook payload
json
{
"id": "evt_abc123",
"type": "paycheck.calculated",
"created_at": "2026-02-10T14:30:00Z",
"data": {
"employee_id": "emp_8821-9920",
"gross_income": 285000,
"safe_to_spend": 170450
}
}HMAC Verification
Every webhook includes an X-tPay365-Signature header. Verify it using HMAC-SHA256 before processing.
Verify webhook signature (Node.js)
typescript
import crypto from "node:crypto"
function verifyWebhook(payload: string, signature: string, secret: string): boolean {
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex")
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected),
)
}Always verify signatures
Never process a webhook payload without verifying the HMAC signature first. Use timing-safe comparison to prevent timing attacks.
Retry Policy
Failed webhook deliveries are retried with exponential backoff. Your endpoint must return a 2xx status within 5 seconds.
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 24 hours |