Skip to content

Commit

Permalink
Merge pull request #36 from kevinreber/temp-stripe-fix
Browse files Browse the repository at this point in the history
debugging stripe
  • Loading branch information
kevinreber authored Nov 24, 2024
2 parents dbff6fe + 9305d68 commit 83c8c44
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 51 deletions.
72 changes: 72 additions & 0 deletions app/routes/api.webhook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import type { ActionFunction } from "@remix-run/node";
import { json } from "@remix-run/node";
import { stripe } from "~/services/stripe.server";
import { handleStripeEvent } from "~/services/webhook.server";
import { Logger } from "~/utils/logger.server";

// [credit @kiliman to get this webhook working](https://github.com/remix-run/remix/discussions/1978)
// To have this webhook working locally, in another server we must run `stripe listen --forward-to localhost:3000/webhook` (yarn run stripe:listen)
export const action: ActionFunction = async ({ request }) => {
console.log("Webhook endpoint hit!", new Date().toISOString());

if (request.method !== "POST") {
return json({ error: "Method not allowed" }, { status: 405 });
}

const payload = await request.text();
const sig = request.headers.get("stripe-signature");

if (!sig) {
return json({ error: "No signature" }, { status: 400 });
}

try {
Logger.info({
message: "[api.webhook.ts]: Processing webhook request",
metadata: {
method: request.method,
headers: Object.fromEntries(request.headers.entries()),
signature: sig,
},
});

const event = stripe.webhooks.constructEvent(
payload,
sig,
process.env.STRIPE_WEB_HOOK_SECRET!
);

const result = await handleStripeEvent(event.type, event.data, event.id);

return json(
{ success: true, data: result },
{
status: 200,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "POST",
"Access-Control-Allow-Headers": "Content-Type, stripe-signature",
},
}
);
} catch (error: unknown) {
Logger.error({
message: "[api.webhook.ts]: Webhook error",
error: error instanceof Error ? error : new Error(String(error)),
});

return json(
{
error: error instanceof Error ? error.message : "Unknown error",
},
{
status: 400,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "POST",
"Access-Control-Allow-Headers": "Content-Type, stripe-signature",
},
}
);
}
};
78 changes: 27 additions & 51 deletions app/routes/webhook.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,32 @@
import type { ActionFunction, MetaFunction } from "@remix-run/node";
import type { ActionFunction } from "@remix-run/node";
import { json } from "@remix-run/node";
import { stripe } from "~/services/stripe.server";
import { handleStripeEvent } from "~/services/webhook.server";
import { Logger } from "~/utils/logger.server";

export const meta: MetaFunction = () => {
return [{ title: "Stripe Webhook" }];
};

// [credit @kiliman to get this webhook working](https://github.com/remix-run/remix/discussions/1978)
// To have this webhook working locally, in another server we must run `stripe listen --forward-to localhost:3000/webhook` (yarn run stripe:listen)
export const action: ActionFunction = async ({ request }) => {
console.log("Webhook endpoint hit!", new Date().toISOString());

Logger.info({
message: "[webhook.ts]: Received webhook request",
metadata: {
method: request.method,
url: request.url,
headers: Object.fromEntries(request.headers.entries()),
timestamp: new Date().toISOString(),
},
});

// Only allow POST requests
if (request.method !== "POST") {
Logger.warn({
message: "[webhook.ts]: Invalid method for webhook",
metadata: { method: request.method },
});
return json({ error: "Method not allowed" }, 405);
return json({ error: "Method not allowed" }, { status: 405 });
}

const payload = await request.text();

Logger.info({
message: "[webhook.ts]: Payload",
metadata: { payload },
});

const sig = request.headers.get("stripe-signature");

if (!sig) {
Logger.warn({
message: "[webhook.ts]: Missing Stripe signature",
});
return json({ error: "No signature" }, 400);
return json({ error: "No signature" }, { status: 400 });
}

try {
Logger.info({
message: "[webhook.ts]: Constructing Stripe event",
message: "[webhook.ts]: Processing webhook request",
metadata: {
signaturePresent: !!sig,
payloadLength: payload.length,
webhookSecretPresent: !!process.env.STRIPE_WEB_HOOK_SECRET,
method: request.method,
headers: Object.fromEntries(request.headers.entries()),
signature: sig,
},
});

Expand All @@ -64,33 +36,37 @@ export const action: ActionFunction = async ({ request }) => {
process.env.STRIPE_WEB_HOOK_SECRET!
);

Logger.info({
message: "[webhook.ts]: Successfully constructed Stripe event ",
metadata: {
eventType: event.type,
eventId: event.id,
},
});

const result = await handleStripeEvent(event.type, event.data, event.id);

return json({ success: true, data: result });
return json(
{ success: true, data: result },
{
status: 200,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "POST",
"Access-Control-Allow-Headers": "Content-Type, stripe-signature",
},
}
);
} catch (error: unknown) {
Logger.error({
message: "[webhook.ts]: Webhook error",
error: error instanceof Error ? error : new Error(String(error)),
metadata: {
payload: payload.substring(0, 100) + "...", // Log first 100 chars of payload
},
});

return json(
{
errors: [
{ message: error instanceof Error ? error.message : "Unknown error" },
],
error: error instanceof Error ? error.message : "Unknown error",
},
400
{
status: 400,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "POST",
"Access-Control-Allow-Headers": "Content-Type, stripe-signature",
},
}
);
}
};

0 comments on commit 83c8c44

Please sign in to comment.