Skip to main content

Webhooks & Events

Time: ~10 minutes | Difficulty: Beginner Use the TagadaPay Node SDK to register HTTPS endpoints for real-time notifications, verify deliveries cryptographically, and query the event log for debugging and analytics.

What webhooks are (and why use them)

Webhooks are HTTP callbacks TagadaPay sends to your server when something happens on the platform — for example, a successful payment or a subscription change. Your endpoint receives a JSON payload so you can update your database, trigger fulfillment, notify internal tools, or sync with Zapier/n8n without polling the API.
Webhooks run asynchronously after the triggering action. Design your handler to respond quickly (e.g. validate the signature, enqueue work, return 2xx). Heavy work should happen in a background job.

Create a webhook

Register a URL and the event types you care about. The API returns the endpoint id, URL, signing secret, subscribed types, and whether the endpoint is enabled.
import Tagada from '@tagadapay/node-sdk';

const tagada = new Tagada('your-api-key');

const webhook = await tagada.webhooks.create({
  storeId: 'store_...',
  url: 'https://api.example.com/webhooks/tagada',
  eventTypes: ['order/paid', 'subscription/created', 'subscription/canceled'],
  description: 'Production notifications',
});

// { id, url, secret, eventTypes, enabled, storeId, createdAt, ... }
console.log(webhook.id, webhook.secret);
Store webhook.secret securely (environment variable or secrets manager). It is returned when you create the endpoint and is required to verify that payloads really came from TagadaPay.

The signing secret

Each webhook endpoint has a unique secret. TagadaPay uses it to compute an HMAC-SHA256 signature over the raw JSON body of each delivery. Your server must verify that signature before trusting the payload.
Event type strings in eventTypes must exactly match the names listed below (slash format like order/paid). The SDK validates event types at build time via TypeScript and at runtime — passing an invalid type will throw an error immediately.

List webhooks

const endpoints = await tagada.webhooks.list('store_...');
// Webhook[]

Delete a webhook

const { success, id } = await tagada.webhooks.del('wh_...');

Available event types

All webhook event types use the slash format (category/event). These are the only valid values accepted by the eventTypes field.

Order events

Event typeDescription
order/paidOrder successfully paid — trigger fulfillment or CRM updates
order/createdOrder record created
order/refundedOrder refunded
order/failedOrder payment failed
order/upsellStartedPost-purchase upsell flow initiated
order/paymentInitiatedPayment process started for an order

Checkout events

Event typeDescription
checkout/initiatedCheckout session started
checkout/emailValidatedCustomer email validated during checkout

Payment events

Event typeDescription
payment/createdPayment record created
payment/succeededPayment completed successfully
payment/failedPayment attempt failed
payment/refundedPayment refunded
payment/authorizedPayment authorized (not yet captured)
payment/rejectedPayment rejected by processor or fraud rules

Subscription events

Event typeDescription
subscription/createdNew subscription started
subscription/canceledSubscription canceled
subscription/pausedSubscription paused
subscription/resumedSubscription resumed
subscription/pastDueSubscription payment past due
subscription/rebillUpcomingUpcoming rebill notification
subscription/rebillSucceededRebill charge succeeded
subscription/rebillDeclinedRebill charge declined
subscription/cancelScheduledCancellation scheduled for end of period
subscription/rebillCaptureFailedRebill capture failed

Funnel events

Event typeDescription
funnel/sessionStartedFunnel session started
funnel/sessionCompletedFunnel session completed
funnel/stepEnteredVisitor entered a funnel step
funnel/stepViewedFunnel step viewed
funnel/stepExitedVisitor exited a funnel step
funnel/convertedFunnel conversion recorded
funnel/customEventCustom funnel event fired
funnel/sessionAbandonedFunnel session abandoned

Club events

Event typeDescription
club/membershipActivatedClub membership activated
club/membershipDeactivatedClub membership deactivated

Security events

Event typeDescription
security/abuseDetectedAbuse or fraud detected
The SDK and API reject any event type not in this list. If you pass an invalid type like order.paid (dot format) or s_order_paid (internal format), you will receive a validation error.

Events API (query & analytics)

Use the Events resource to audit activity, build dashboards, or debug webhook payloads.

Recent events

const recent = await tagada.events.recent(25);
// AppEvent[] — includes eventType, createdAt, payload, storeId, ...

Statistics

const stats = await tagada.events.statistics({ storeId: 'store_...' });
// { totalEvents, eventsByType, processedCount, unprocessedCount }

List with filters and pagination

const { data, total, page, pageSize, hasMore } = await tagada.events.list({
  pagination: { page: 1, pageSize: 50 },
  sortBy: { field: 'appEvents.createdAt', direction: 'desc' },
  filters: {
    'stores.id': ['store_...'],
    // Event types here are often internal analytics ids (e.g. s_order_paid) — see Note below
    'appEvents.eventType': ['s_order_paid'],
  },
});
Optional filters include date ranges on appEvents.createdAt / appEvents.processedAt, customer.email, appEvents.draft, and free-text search.
Webhook subscriptions use slash-format names like order/paid and subscription/created. The Events list API may return internal eventType strings (for example s_order_paid) — these are for internal analytics and should not be used when creating webhooks.

Webhook signature verification (HMAC-SHA256)

TagadaPay signs the exact JSON string sent as the request body.
  1. Read the raw body as a string (do not parse JSON before verifying).
  2. Compute HMAC-SHA256(secret, rawBody) and hex-encode the digest.
  3. Compare to the X-TagadaPay-Signature header value after the sha256= prefix.
import crypto from 'crypto';

function verifyTagadaWebhook(rawBody: string, secret: string, signatureHeader: string | null) {
  if (!signatureHeader?.startsWith('sha256=')) return false;
  const expected = signatureHeader.slice('sha256='.length);
  const hmac = crypto.createHmac('sha256', secret).update(rawBody, 'utf8').digest('hex');
  try {
    return crypto.timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(hmac, 'hex'));
  } catch {
    return false;
  }
}
Other headers on the request include X-TagadaPay-Timestamp and User-Agent: TagadaPay-Webhooks/1.0. You can use the timestamp for optional replay protection.

SDK methods reference

ResourceMethodDescription
webhookscreate(params)Create endpoint; params: storeId, url, eventTypes, optional description
webhookslist(storeId)List all webhooks for a store
webhooksdel(id)Delete webhook; returns { success, id }
eventsrecent(limit?)Most recent events
eventsstatistics(params?)Aggregates; optional storeId, startDate, endDate
eventslist(params?)Filtered list with filters, pagination, sortBy, search
eventsretrieve(eventId)Single event by id

Next steps

Node SDK Quick Start

Install the SDK, authenticate, and explore core resources

Sandbox Testing

Exercise payments and webhook-style flows without live processors

Merchant Quick Start

End-to-end store, funnel, and checkout setup

Subscriptions

Recurring billing and subscription lifecycle