feat(billing): add subscription and Stripe billing router
- Add stripeCustomerId column to users table - Create Stripe client initialization (web/src/server/stripe.ts) - Add billing service with getOrCreateCustomer, checkout/portal sessions, subscription management, invoice listing, and webhook event handling - Create billing tRPC router with getSubscription, createCheckoutSession, createPortalSession, cancelSubscription, reactivateSubscription, listInvoices - Add raw webhook endpoint at /api/stripe/webhook with signature verification - Define Valibot schemas for all billing procedure inputs - Wire billing router into root tRPC router - Update schema tests for new column/index counts - Write unit tests for billing service and router
This commit is contained in:
27
web/src/routes/api/stripe/webhook.ts
Normal file
27
web/src/routes/api/stripe/webhook.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import type { APIEvent } from "@solidjs/start/server";
|
||||
import { stripe } from "~/server/stripe";
|
||||
import { handleWebhookEvent } from "~/server/services/billing.service";
|
||||
|
||||
export async function POST(event: APIEvent) {
|
||||
const body = await event.request.text();
|
||||
const signature = event.request.headers.get("stripe-signature");
|
||||
|
||||
if (!signature) {
|
||||
return new Response("Missing stripe-signature header", { status: 400 });
|
||||
}
|
||||
|
||||
try {
|
||||
const webhookEvent = stripe.webhooks.constructEvent(
|
||||
body,
|
||||
signature,
|
||||
process.env.STRIPE_WEBHOOK_SECRET ?? "",
|
||||
);
|
||||
|
||||
await handleWebhookEvent(webhookEvent);
|
||||
|
||||
return new Response("OK", { status: 200 });
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : "Webhook error";
|
||||
return new Response(message, { status: 400 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user