> ## Documentation Index
> Fetch the complete documentation index at: https://docs.centipidbilling.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Razorpay

> Configure Razorpay payment links for Indian UPI, card, netbanking, and wallet collection.

# Collect payments with Razorpay

`RAZORPAY` uses a **hosted payment link** offering UPI, cards, netbanking, and
wallets. Centipid Billing creates the link, sends the payer to its short URL,
and confirms the result on a signed webhook that is re-verified against Razorpay
before anything is credited.

Offered in the country catalog for **India (IN)**.

## Before you start

1. Complete Razorpay onboarding in an account owned by the ISP, and activate the
   payment methods you intend to offer — which of UPI, cards, netbanking, and
   wallets a payer sees is configured on the Razorpay account, not per request.
2. From **Settings → API Keys** in the Razorpay dashboard, generate a key and
   collect the **Key ID** and **Key secret**. The secret is shown once.
3. From **Settings → Webhooks**, create a webhook and collect its **webhook
   secret**. This is issued separately and is **not** the key secret.
4. Plan the walled garden: the payer's browser must reach the payment link, so a
   Hotspot subscriber who is not yet online cannot pay unless Razorpay is
   reachable pre-authentication.

## Configure the gateway

<Steps>
  <Step title="Open Settings → Payments → Razorpay">
    Select Razorpay from the payment marketplace.
  </Step>

  <Step title="Enter the Key ID">
    **Key ID** (required) starts with `rzp_live_` on a live account and
    `rzp_test_` in test mode. The prefix is how you tell the two apart.
  </Step>

  <Step title="Enter the Key secret">
    **Key secret** (required) is stored as a secret and authenticates every
    request to Razorpay.
  </Step>

  <Step title="Enter the webhook secret">
    **Webhook secret** is optional and does not gate the switch, but until it is
    set every webhook is rejected — see [Callback URLs](#callback-urls).
  </Step>

  <Step title="Register the webhook">
    See [Callback URLs](#callback-urls) below.
  </Step>

  <Step title="Run a controlled test payment">
    Pay a small amount from the captive portal on an unauthenticated device, and
    confirm the payment reaches the ledger. Test a real UPI payment, not only a
    sandbox one.
  </Step>
</Steps>

## Credentials

| Field          | Required | Notes                                                             |
| -------------- | -------- | ----------------------------------------------------------------- |
| Key ID         | Yes      | `rzp_live_…` or `rzp_test_…`.                                     |
| Key secret     | Yes      | Secret. Authenticates API requests.                               |
| Webhook secret | No       | Secret. Issued separately from the key secret; signs the webhook. |

The Key ID and Key secret gate the switch. The webhook secret does not, so it is
easy to leave blank by accident — see the warning below for what that costs.

## Callback URLs

| Name         | Path                                        |
| ------------ | ------------------------------------------- |
| Webhook URL  | `https://<your-host>/api/razorpay/callback` |
| Redirect URL | `https://<your-host>/api/razorpay/return`   |

Register the webhook URL in the Razorpay dashboard against the
`payment_link.paid` event. The redirect is where the payer's browser returns
after payment; Razorpay appends the reference itself.

<Warning>
  Webhooks carry an HMAC-SHA256 `x-razorpay-signature` computed with the
  **webhook secret**, not the key secret. A wrong or missing webhook secret
  means every webhook is rejected with HTTP 400. Payers are still provisioned
  when they return to the site, but a payer who closes the tab before the
  redirect is charged and left disconnected until someone reconciles by hand.
</Warning>

## What the payer must provide

Whatever the Razorpay payment link asks for — a UPI ID or app approval, card
details, netbanking credentials, or a wallet. The payer's name, email, and phone
are sent with the link when known; when no email is available a placeholder is
sent so the link can be created, so do not rely on the email shown in Razorpay
to identify a subscriber.

Centipid Billing sends its own receipts, so the link is created with Razorpay's
own SMS and email notifications switched off. Turning them back on in the
dashboard double-messages the subscriber.

The currency is your account's configured currency, defaulting to `INR`.

<Note>
  Amounts are sent in **paise**, the smallest unit — ₹500 is sent as `50000`.
  This is the opposite convention to Monnify, which takes major units. A
  ledger amount that is 100× the Razorpay amount is the expected relationship,
  not a bug.
</Note>

## How a payment completes

<Steps>
  <Step title="Create the link">
    Centipid Billing creates a payment link for the amount with our own
    reference and receives its short URL. A pending row is written against that
    reference.
  </Step>

  <Step title="Payment">
    The payer completes the payment on Razorpay's page.
  </Step>

  <Step title="Confirmation">
    Razorpay posts the signed webhook. The signature is validated against the
    raw request body, the link is then re-queried against the Razorpay API, and
    only a link whose status is `paid` records a payment and applies the
    package. Repeated webhooks are ignored rather than double-credited.
  </Step>
</Steps>

<Note>
  A payment link exists from the moment it is created, with status `created`.
  Only `paid` provisions. This is why a link that exists is not evidence a
  payment was made.
</Note>

## Sending SMS in India

Razorpay handles the money; it does not solve messaging. India's DLT rules mean
an unregistered sender's messages are dropped at the carrier while the delivery
report still reads as success. Pair Razorpay with **MSG91** or **Fast2SMS** and
your registered header and templates — see
[providers and sender IDs](/communications/providers-and-sender-ids).

## Troubleshooting

| Symptom                                                | What it means                                                                                                             | What to do                                                                                                                                                                  |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| *"Unable to process payment. Please try again later."* | Credentials are missing or Razorpay refused the link.                                                                     | Check the Key ID and Key secret, and that a live key is not being used in test mode or the reverse.                                                                         |
| Test payments work, live does not                      | The key pair is still `rzp_test_…`.                                                                                       | Generate live keys and replace both the ID and the secret together.                                                                                                         |
| The payment page never loads on a Hotspot device       | The walled garden does not allow Razorpay.                                                                                | Allow `api.razorpay.com`, `checkout.razorpay.com`, and `rzp.io` pre-authentication — see [Captive device cannot reach checkout](/billing/payment-gateways/troubleshooting). |
| Payments complete at Razorpay, ledger stays empty      | Webhooks are being rejected — usually a missing or wrong webhook secret, or a webhook URL that is not publicly reachable. | Re-copy the webhook secret from the dashboard, confirm the URL is registered and reachable, then re-test.                                                                   |
| Subscribers get two receipts                           | Razorpay's own notifications were re-enabled on the account.                                                              | Turn off SMS and email notifications for payment links in the Razorpay dashboard.                                                                                           |
| The amount looks 100× too large in Razorpay            | It is not — amounts are sent in paise.                                                                                    | Divide by 100 to compare against the ledger.                                                                                                                                |

For every gateway's fields in one place, see the
[credential reference](/billing/payment-gateways/credentials-reference).
