Event Handler Example
Example of handling payment events using a simple routing pattern.
type SubscriptionData = any; // Replace with your type
type TransactionData = any; // Replace with your type
type WebhookEvent<T = any> = {
meta: { occured_at: string; event_type: string; event_id: string };
data: T;
};
export class WebhookHandler {
static async processEvent(event: WebhookEvent) {
switch (event.meta.event_type) {
case 'subscription.created':
await this.handleSubscriptionCreated(event.data as SubscriptionData);
break;
case 'subscription.updated':
await this.handleSubscriptionUpdated(event.data as SubscriptionData);
break;
case 'transaction.created':
await this.handleTransactionCreated(event.data as TransactionData);
break;
case 'transaction.updated':
await this.handleTransactionUpdated(event.data as TransactionData);
break;
default:
console.log(`Unhandled event type: ${event.meta.event_type}`);
}
}
static async handleSubscriptionCreated(data: SubscriptionData) {
// Example: create or enable access for the user
await db.subscriptions.create({
userId: data.customer?.id,
planName: data.items?.[0]?.planName,
status: data.status,
currentPeriodEnd: data.nextBilledAt
});
}
static async handleSubscriptionUpdated(data: SubscriptionData) {
await db.subscriptions.update({
id: data.id,
status: data.status,
pausedAt: data.pausedAt,
canceledAt: data.canceledAt
});
}
static async handleTransactionCreated(data: TransactionData) {
await db.transactions.create({
id: data.id,
amount: data.totalAmountPaid,
currency: data.paidCurrency,
status: data.status
});
}
static async handleTransactionUpdated(data: TransactionData) {
await db.transactions.update({
id: data.id,
status: data.status,
revisedAt: data.revisedAt
});
}
}
Notes:
Use idempotency (by
meta.event_id
or a delivery header) to avoid double-processing.Validate payloads and handle unknown fields defensively.
Last updated