Agent skill

Tebex Webhooks Skill

Receive and verify Tebex webhooks. Use when setting up Tebex webhook handlers, debugging X-Signature verification, completing the validation.webhook handshake, or handling events like payment.completed, payment.refunded, and recurring-payment.renewed.

Install this skill

npx skills add hookdeck/webhook-skills --skill tebex-webhooks


When to Use This Skill

  • Setting up Tebex webhook handlers
  • Debugging Tebex X-Signature verification failures
  • Completing the validation.webhook handshake so an endpoint activates
  • Handling payment, dispute, and recurring-payment events

Verification (core)

Tebex has no SDK. Verify the hex X-Signature header manually. The signature is two-step: SHA-256 hash the raw request body, then HMAC-SHA256 that hex hash using your webhook secret as the key. Do not JSON.parse before verifying — a re-serialized body produces a different hash.

Node:

const crypto = require('crypto');

function verifyTebexSignature(rawBody, signatureHeader, secret) {
  const bodyHash = crypto.createHash('sha256').update(rawBody).digest('hex');
  const expected = crypto.createHmac('sha256', secret).update(bodyHash).digest('hex');
  const received = Buffer.from(signatureHeader || '');
  const expectedBuf = Buffer.from(expected);
  return received.length === expectedBuf.length &&
    crypto.timingSafeEqual(received, expectedBuf);
}

Python:

import hashlib, hmac

def verify_tebex_signature(raw_body: bytes, signature: str, secret: str) -> bool:
    body_hash = hashlib.sha256(raw_body).hexdigest()
    expected = hmac.new(secret.encode(), body_hash.encode(), hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature or "")

Validation handshake: On setup Tebex sends a validation.webhook ping. After verifying the signature, respond 200 with {"id": "<payload.id>"} echoing the received id, or the endpoint never activates.

For complete handlers with route wiring, event dispatch, and tests, see:

Common Event Types

EventDescription
validation.webhookSetup ping — echo the id back with a 200 to activate the endpoint
payment.completedA payment completed successfully
payment.declinedA payment was declined
payment.refundedA payment was refunded
payment.dispute.openedA chargeback/dispute was opened
payment.dispute.wonA dispute was resolved in your favor
payment.dispute.lostA dispute was resolved against you
payment.dispute.closedA dispute was closed
recurring-payment.startedA subscription began
recurring-payment.renewedA subscription renewed
recurring-payment.endedA subscription ended
recurring-payment.cancellation.requestedA subscription cancellation was requested
recurring-payment.cancellation.abortedA pending cancellation was aborted

For the full event reference, see Tebex Webhooks.

Payload Structure

Every webhook has the same envelope: id (unique webhook ID), type (event name), date (ISO timestamp), and subject (event-specific data).

Environment Variables

TEBEX_WEBHOOK_SECRET=your_webhook_secret_here   # Creator Panel > Developers > Webhooks > Endpoints

Source IP Allowlist

Tebex sends webhooks only from 18.209.80.3 and 54.87.231.232. The docs suggest returning 404 to requests from any other IP. See references/verification.md for an example.

Local Development

# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 tebex --path /webhooks/tebex

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Aug 5, 2026

View on GitHub →