The Razorpay webhook endpoint receives payment lifecycle events from Razorpay and keeps your organization’s billing state in sync with actual payment outcomes. When a payment is captured, fails, or a subscription is cancelled, Razorpay delivers a signedDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/paramveer-cyber/Deployaar/llms.txt
Use this file to discover all available pages before exploring further.
POST to POST /api/razorpay/webhook. Deployaar verifies the payload signature using RAZORPAY_WEBHOOK_SECRET, extracts the organizationId from the payment notes, and updates the organization’s billing plan and status in the database accordingly.
Endpoint
Required Headers
| Header | Description |
|---|---|
x-razorpay-signature | HMAC-SHA256 signature of the raw request body. Computed by Razorpay using your RAZORPAY_WEBHOOK_SECRET. |
Content-Type | Must be application/json. |
x-razorpay-signature header is absent, the request is rejected immediately with a 401.
Signature Verification
Deployaar computes the expected signature as:x-razorpay-signature header using a strict string equality check. If the signatures do not match, handleWebhook throws "Invalid Razorpay webhook signature" and the server returns 401 {"error": "Invalid signature"}. No billing state is changed when verification fails.
Handled Events
Deployaar reads theevent field from the parsed webhook payload and routes it to the appropriate billing update. The organizationId is resolved from payload.payment.entity.notes.organizationId or payload.subscription.entity.notes.organizationId — these notes are embedded in the Razorpay order at creation time by Deployaar’s own createOrder function.
| Event | Billing Effect |
|---|---|
payment.captured | Updates the organization’s billing plan to the targetPlan stored in the payment notes (e.g. pro or pro_max). Sets billing status to active. |
payment.failed | Sets the organization’s billing status to past_due. The plan tier is not downgraded immediately. |
subscription.cancelled | Sets the organization’s billing status to inactive. |
| Any other event | Logged at debug level. No database changes are made. |
If the webhook payload is missing an
organizationId in the payment or subscription notes, the event is logged as a warning and dropped — no billing changes occur. This prevents orphaned webhook deliveries from corrupting billing state.| Plan value | Display name | Price (INR) |
|---|---|---|
free | Deployaar Free | — |
pro | Deployaar Pro | ₹1,499 |
pro_max | Deployaar Pro Max | ₹2,999 |
Response Codes
| Status | Body | Meaning |
|---|---|---|
200 | {"received": true} | Event processed successfully (or event type not handled — acknowledged with no action). |
401 | {"error": "Missing x-razorpay-signature header"} | The x-razorpay-signature header was not present in the request. |
401 | {"error": "Invalid signature"} | HMAC-SHA256 verification failed. The payload may have been tampered with, or RAZORPAY_WEBHOOK_SECRET is misconfigured. |
Errors that occur after a successful signature check (e.g. a transient database failure) are swallowed and still return
200 {"received": true}. This prevents Razorpay from continuously retrying deliveries for non-recoverable server-side errors.Setting Up
Open the Razorpay Dashboard
Log in to the Razorpay Dashboard. Navigate to Settings → Webhooks and click Add New Webhook.
Set the Webhook URL
Enter your deployed API URL as the webhook destination:Make sure the URL is publicly reachable and uses HTTPS. Razorpay does not deliver to plain HTTP endpoints in production.
Select webhook events
Enable at minimum the following events:
payment.captured— fires when a one-time payment is successfully captured. This is the primary event that upgrades a plan.payment.failed— fires when a payment attempt fails. Deployaar sets the org topast_due.subscription.cancelled— fires when a Razorpay subscription is cancelled. Deployaar sets the org toinactive.
Copy the webhook secret
After saving, Razorpay generates a webhook secret. Copy it and set it as the
RAZORPAY_WEBHOOK_SECRET environment variable in your API deployment.Set your Razorpay API keys
In the Razorpay Dashboard under Settings → API Keys, generate a key pair. Set both values in your API environment:
RAZORPAY_KEY_ID is also returned to the frontend during checkout so Razorpay.js can open the payment modal. RAZORPAY_KEY_SECRET is used server-side to create orders and verify inline payment signatures.Testing with a Mock Delivery
You can simulate apayment.captured event locally using curl. Replace <secret> with your RAZORPAY_WEBHOOK_SECRET:
200 {"received":true} and the organization’s billing plan is updated in the database.
For a full explanation of plan tiers, usage limits, and the checkout flow, see the Billing Plans reference.