aboutsummaryrefslogtreecommitdiffstats
path: root/packages/api/routes
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2025-07-13 09:28:24 +0000
committerMohamed Bassem <me@mbassem.com>2025-07-13 20:44:00 +0000
commitd1d5263486f96db578aad918a59007045c3c077f (patch)
treedf65f062b6eda93364f7d509fc2c52663561097a /packages/api/routes
parent845ccf1ad46c8635782f8e10280b07c48c08eaf5 (diff)
downloadkarakeep-d1d5263486f96db578aad918a59007045c3c077f.tar.zst
feat: Add stripe based subscriptions
Diffstat (limited to 'packages/api/routes')
-rw-r--r--packages/api/routes/webhooks.ts44
1 files changed, 44 insertions, 0 deletions
diff --git a/packages/api/routes/webhooks.ts b/packages/api/routes/webhooks.ts
new file mode 100644
index 00000000..66ce96d3
--- /dev/null
+++ b/packages/api/routes/webhooks.ts
@@ -0,0 +1,44 @@
+import { Hono } from "hono";
+
+import { Context, createCallerFactory } from "@karakeep/trpc";
+import { appRouter } from "@karakeep/trpc/routers/_app";
+
+const createCaller = createCallerFactory(appRouter);
+
+const app = new Hono<{
+ Variables: {
+ ctx: Context;
+ };
+}>().post("/stripe", async (c) => {
+ const body = await c.req.text();
+ const signature = c.req.header("stripe-signature");
+
+ if (!signature) {
+ return c.json({ error: "Missing stripe-signature header" }, 400);
+ }
+
+ try {
+ const api = createCaller(c.get("ctx"));
+ const result = await api.subscriptions.handleWebhook({
+ body,
+ signature,
+ });
+
+ return c.json(result);
+ } catch (error) {
+ console.error("Webhook processing failed:", error);
+
+ if (error instanceof Error) {
+ if (error.message.includes("Invalid signature")) {
+ return c.json({ error: "Invalid signature" }, 400);
+ }
+ if (error.message.includes("not configured")) {
+ return c.json({ error: "Stripe is not configured" }, 400);
+ }
+ }
+
+ return c.json({ error: "Internal server error" }, 500);
+ }
+});
+
+export default app;