WHMCS does not ship a Razorpay module, so a WHMCS Razorpay integration uses Razorpay's own open-source plugin from GitHub. You upload it to the modules folder, activate Razorpay as a payment gateway, enter the Key Id and Key Secret, and add an order.paid webhook with a shared secret. It takes one-off invoice payments only: no Razorpay Subscriptions, no automatic renewals and no refunds from WHMCS.
Does WHMCS have a built-in Razorpay module?
No. The WHMCS 9.0 payment gateway list has no Razorpay entry. Razorpay maintains the integration itself, as an MIT-licensed plugin in the razorpay/razorpay-whmcs repository, and support comes from Razorpay, not WHMCS. Because it is a custom module, it needs a self-hosted install; WHMCS Cloud does not give access to the files.
Razorpay's WHMCS plugin page lists the plugin for merchants in India, Malaysia and Singapore, on Web Standard Checkout, for the Payment Gateway product only. Route and Subscriptions are not supported. Razorpay's own sources disagree on versions, so check all three before you download:
| Razorpay source | WHMCS versions named | What it says to install |
|---|---|---|
| Documentation, Integration Steps | 6, 7 and 8 (5 has its own release) | Release 2.0.1, whose notes say tested up to WHMCS 8.1.0 |
| GitHub README, revised September 2026 | 6, 7, 8 and 9 | The master branch |
| GitHub releases | Not stated | Newest tag 2.2.2, August 2024. The 2.2.1 notes say not to use that release. |
Release 2.0.1 predates two fixes that matter: 2.1.1 removed a double slash from the callback URL, and 2.2.2 fixed checkout ignoring an updated amount on an unpaid invoice. On WHMCS 8.13 or 9, I would test 2.2.2 or master on a staging copy and keep whichever passes.
How do you install and configure the Razorpay plugin?
Upload the plugin's modules folder over your WHMCS modules folder, activate the gateway and enter your keys. The Integration Steps page still uses the old Setup > Payments > Payment Gateways menu; in WHMCS 8 and 9 it is Configuration > System Settings > Payment Gateways.
- Download the version you chose and upload its
modulescontents. On the currentmasterbranch that ismodules/gateways/razorpay.phpplus amodules/gateways/razorpay/folder holding the return handler andrazorpay-webhook.php. - Activate Razorpay on the Payment Gateways page.
- Enter the Key Id and Key Secret from the Razorpay Dashboard. Use the Test Mode pair first.
- Leave Payment Action on Authorize and Capture, the default. With Authorize alone, payments wait for a manual capture, and Razorpay refunds uncaptured payments automatically.
- If your WHMCS default currency is not INR, set Convert To For Processing to INR and keep the exchange rate current at Configuration > System Settings > Currencies.
- Save the changes.
For live keys, switch the Razorpay Dashboard to Live Mode, go to Account & Settings, then API Keys, click Generate Key, download the pair and store it safely. Replace the test pair in WHMCS only after testing passes. The Key Secret belongs in WHMCS and nowhere else.
How do you set up the Razorpay webhook in WHMCS?
Turn on Enable Webhook in the gateway settings, then create a webhook in the Razorpay Dashboard for the order.paid event with the same secret. The client's browser return records most payments; the webhook is the backup when that return never reaches WHMCS.
- In WHMCS, tick Enable Webhook. The setting shows the URL, which on
masterends in/modules/gateways/razorpay/razorpay-webhook.php. Enter a Webhook Secret. - In the Razorpay Dashboard, open Accounts & Settings, then Webhooks, and click Add New Webhook.
- Paste the URL, enter the same secret, add an alert email for delivery failures, select
order.paidand click Create Webhook.
Razorpay's Validate and Test Webhooks page adds three practical points. Webhooks go only to public URLs, so localhost and tunnelling domains such as ngrok.io are rejected. In Test Mode, the OTP prompt when you save a webhook accepts 754081. And the same event can arrive more than once.
I read the webhook handler in the current source. It checks the X-Razorpay-Signature header, an HMAC-SHA256 of the raw body keyed with your secret, and answers 401 with a Gateway Log entry on a mismatch. It acts on order.paid only. It then looks up the WHMCS order behind the invoice and compares the payment with that order's total. A renewal invoice has no order behind it, so in my reading the webhook does not record renewals, and a first invoice reduced by credit or a part payment may log an amount mismatch. Those payments depend on the browser return, so test them before you rely on the webhook.
Which currencies and payment methods does the plugin support?
Only currencies with two decimal places, such as INR, USD and EUR. Zero-decimal currencies like JPY and three-decimal ones like BHD fail, according to the plugin's FAQ. Foreign cards also need International Cards activated in the Razorpay Dashboard, under Account & Settings, then International payments.
Checkout offers debit and credit cards, netbanking, UPI, card EMI and wallets by default. Cardless EMI and Pay Later need Razorpay's approval; bank transfer and emandate need approval and a separate integration. If you bill in several currencies, my WHMCS multi-currency guide covers how Convert To For Processing interacts with client currencies.
What can the Razorpay plugin not do?
It cannot charge anyone without the client clicking Pay. The only payment function the plugin defines is the payment link, so WHMCS treats it as a third-party gateway: it sends the Invoice Created email and disables Attempt Capture.
- No automatic renewals. Every renewal is an invoice the client pays by hand, so keep payment reminders on and the cron healthy; see my WHMCS cron guide. Clients who want auto-pay can use a token gateway such as Stripe in WHMCS.
- No Razorpay Subscriptions. Razorpay documents its recurring products separately. Connecting WHMCS renewals to them is custom gateway work, and it has to follow the mandate rules Razorpay documents for Indian recurring payments.
- No refunds from WHMCS. The plugin defines no refund function, which is what WHMCS calls to refund through a gateway. Refund in the Razorpay Dashboard, then record it on the invoice's Refund tab as Manual Refund Processed Externally. A refund made in Razorpay never reaches WHMCS by itself.
Because the plugin is open source, adding a refund function is a small, contained change to a copy of it; that sits under WHMCS custom module development.
How do you test the WHMCS Razorpay integration?
Use Test Mode keys and Razorpay's test data, then confirm both sides. No money moves in Test Mode.
| Method | Test input from Razorpay's Integration Steps |
|---|---|
| Domestic card | Visa 4100 2800 0000 1007 or Mastercard 5500 6700 0000 1002, any CVV, any future expiry |
| International card | Mastercard 5555 5555 5555 4444 or Visa 4012 8888 8888 1881 |
| UPI | success@razorpay succeeds, failure@razorpay fails |
| Netbanking and wallets | Pick any listed option; a mock page offers Success and Failure |
- Pay a test invoice. In the Dashboard, Transactions then Payments should show it as Captured, and the invoice should be Paid.
- Pay with
failure@razorpayand confirm the invoice stays Unpaid. - Pay a new order's invoice and close the tab before the redirect, then repeat with a renewal invoice. Note which ones the webhook records.
- Switch to live keys and take one small real payment before announcing it.
Why is a Razorpay payment not showing in WHMCS?
Usually the callback URL, the webhook secret or the amount. Read Billing > Gateway Log first; the plugin logs each failure there.
| Symptom | Cause and fix |
|---|---|
| Payment stays Authorized, invoice unchanged | Razorpay's FAQ links this to ModulesGarden add-ons that add a trailing slash to the System URL, which doubles the slash in the callback path. Fix the URL, and check that Payment Action is Authorize and Capture. |
| Paid at Razorpay, invoice unpaid, signature failure in the log | The secret in WHMCS and in the Dashboard differ. Re-enter both. |
WHMCS_ERROR: Payment to Razorpay Failed. Amount mismatch. | The payment differs from the WHMCS order total the webhook compares it with, for example after credit, a part payment or an invoice edit. Confirm it in the Dashboard and add the payment by hand. |
| Webhook URL will not save | It points to localhost or a blocked tunnelling domain. Use a public staging URL. |
| Checkout fails in one currency | A zero- or three-decimal currency. Bill or convert to a two-decimal one. |
| Foreign cards declined | International Cards is not activated on the account. |
Before opening a Razorpay ticket, their FAQ asks for the plugin version, steps to reproduce, error logs and a staging login. Give them a staging admin account, never your live one.
Last reviewed 12 October 2026. Disclosure: I sell WHMCS and web development work, so I am not neutral. I am CTO at ElySpace, a freelance developer for Marmaids LLC, and founder of WHMCSPilot and MagizAI. Plugin details come from Razorpay's documentation, its GitHub repository and the WHMCS 9.0 documentation as I read them on that date; I did not take a live payment for this review.