---
title: "Razorpay"
space: "BWH Payments (Next)"
url: "https://docs.bwh.tech/bwh-payments-next/gateways/razorpay"
updated: "2026-10-12"
---

Take cards, UPI, netbanking and wallets in India through [Razorpay Payment Links](https://razorpay.com/docs/payments/payment-links/). Each checkout is a short hosted link, and a signed webhook reports when it's paid.

## Before you start

- A Razorpay account. Test mode is fine.
- A **Key ID** and **Key Secret** from **Account & Settings → API Keys**

## Set up Razorpay

**1. Fill in Razorpay Gateway Settings**

| Field | Value |
|---|---|
| Key ID | `rzp_test_…` or `rzp_live_…`. The key decides whether payments are test or live. |
| Key Secret | The secret shown with the key |
| Currency | Used when a payment has no currency. Usually `INR`. |
| Success URL | Your [confirmation page](/bwh-payments-next/get-started/return-pages). `?reference_id=…` is added to it. |
| Failure URL, Cancelled URL | Your [payment-failed page](/bwh-payments-next/get-started/return-pages). Razorpay never redirects here. BWH Payments passes these URLs back to your app, so you can send the shopper there yourself. |
| Test Mode | For your own reference only |
| Webhook Secret | Filled in at step 3 |

**2. Create a Payment Gateway Profile** named `Razorpay`, set **Gateway Settings** to `Razorpay Gateway Settings`, and tick **Enabled**.

**3. Add the webhook.** In Razorpay, go to **Account & Settings → Webhooks → Add New Webhook**:

- **URL:** `https://your.site/api/v2/method/bwh_payments.bwh_payments.webhook.handle?gateway=Razorpay`
- **Secret:** choose one, and paste the same value into **Webhook Secret**
- **Events:** `payment_link.paid`, and for refunds `refund.created`, `refund.processed` and `refund.failed`

:::caution
The webhook secret is **not** your Key Secret. If you use the Key Secret, every delivery fails verification.
:::

## Options

| Option | Default | Turn it on when |
|---|---|---|
| **Treat Authorised As Paid** | Off | Your Razorpay account captures payments automatically. On a manual-capture account, leave it off: an authorised payment hasn't been collected yet. |
| **Send Razorpay Notifications To Shopper** | Off | You want Razorpay to SMS and email the link to the shopper and send reminders. Each message is billed to your account. |

## How it behaves

| Razorpay link status | Payment status |
|---|---|
| `paid` | Paid |
| `expired` | Expired |
| `cancelled` | Cancelled |
| `created` with an authorised payment | Paid, only with **Treat Authorised As Paid** |
| `created`, `partially_paid`, anything else | Pending |

- **Amounts** are sent in paise, or the smallest unit of the currency.
- **Webhooks** are HMAC-SHA256 signed. Deliveries without Razorpay's event id header are rejected, because that id is what stops duplicates.
- **Refunds** go against the link's captured payment. Partial refunds are supported. A `pending` refund settles from a refund webhook, or from `sync_refunds`. A refund made in the Razorpay Dashboard is recorded too.
- **Old payments** imported from frappe/payments have a `pay_…` payment id as their `order_ref`, and are refunded against it.
- **Cancelling** an open checkout cancels the payment link.

## Good to know

- Empty shopper details are left out, because Razorpay rejects a blank email or phone number. Guest checkout works without them.
- A payment that is authorised but never captured can't be refunded from here. Capture it or refund it in the Razorpay Dashboard.

## Next steps

- [Webhooks and security](/bwh-payments-next/build/webhooks-and-security): debug a delivery that isn't arriving
- [Build a payment gateway](/bwh-payments-next/build/build-a-payment-gateway): add a gateway that isn't listed
