Fix: implement server-side Razorpay webhook verification for robust payment sync#11
Fix: implement server-side Razorpay webhook verification for robust payment sync#11anveshpol1522 wants to merge 7 commits into
Conversation
Implement Razorpay order creation with user authentication.
|
@anveshpol1522 is attempting to deploy a commit to the notsoocool's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Hey @anveshpol1522 — thanks for picking up #8, this is exactly the kind of gap we needed to close. I went through the PR and I'm not quite ready to merge yet. The webhook direction is right, but a couple things would break production if we shipped as-is. The big one: replacing create-order removes stuff the app already relies on (keyId, prefill, rate limits, saving the order in Supabase). Checkout would stop working because the frontend needs keyId to open Razorpay. Could you keep the existing postCreateOrder flow and only add userId to the order notes in paymentService? Also Razorpay won't be able to hit the webhook unless we mark /api/webhooks/razorpay as a public route in proxy.ts — right now Clerk would block it. Smaller stuff: the upsert uses onConflict razorpay_order_id but our PK is user_id, so we should match what verifyPayment already does. Would be good to skip upgrading if that payment was already processed (client verify might've beaten the webhook). And plan_expiry should stay YYYY-MM-DD like the rest of the code. Ideally most of the upgrade logic lives in paymentService so we're not maintaining two versions. A README note for RAZORPAY_WEBHOOK_SECRET would help too. Ping me when you push an update — happy to take another look. |
|
Hey @notsoocool, thanks for the guidance! I've updated the PR based on your feedback. Here is what I changed: Let me know if this looks good to merge! |
Changes made:
ACTION REQUIRED BY MAINTAINERS BEFORE MERGE/DEPLOY:
Because this feature relies on secure server-to-server communication, it requires the addition of two new environment variables and a dashboard configuration.
Add New Environment Variables
Please add the following keys to your .env.local (for testing) and your Vercel/hosting environment variables (for production):
RAZORPAY_WEBHOOK_SECRET: A secret string used to verify the webhook signature. (You will create this in step 2).
SUPABASE_SERVICE_ROLE_KEY: Your Supabase Service Role key (found in Supabase Dashboard -> Project Settings -> API). This is required because the webhook operates outside of the Clerk authenticated session.
Configure the Webhook in Razorpay
In your Razorpay Dashboard:
Navigate to Settings ---> Webhooks.
Click Add New Webhook.
Webhook URL: Set this to your production domain (e.g., https://worktowords.vercel.app/api/webhooks/razorpay). For local testing, you will need a tool like Ngrok or Stripe CLI to forward the local port.
Secret: Create a strong, random secret string. This must match the RAZORPAY_WEBHOOK_SECRET environment variable.
Active Events: Select ONLY payment.captured.
Save the webhook.
Testing Notes for Maintainers:
To test this locally, you will need to expose your localhost:3000 to the internet using a tool like Ngrok or Localtunnel so Razorpay can reach the webhook endpoint during a test transaction.
A huge thanks for assigning this issue to me. Absolutely loved working on this issue and would be glad to work on future issues like this