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:
2026-05-25 16:07:00 -04:00
parent 28c33a930d
commit 40a9ef146c
14 changed files with 1006 additions and 4 deletions

View File

@@ -0,0 +1,24 @@
import { object, string, url, minLength, optional, picklist } from "valibot";
export const CreateCheckoutSessionSchema = object({
priceId: string([minLength(1)]),
successUrl: string([url()]),
cancelUrl: string([url()]),
});
export const CreatePortalSessionSchema = object({
returnUrl: string([url()]),
});
export const CancelSubscriptionSchema = object({
subscriptionId: string([minLength(1)]),
});
export const ReactivateSubscriptionSchema = object({
subscriptionId: string([minLength(1)]),
});
export const ListInvoicesSchema = object({
limit: optional(string(), "10"),
startingAfter: optional(string()),
});