Skip to content
TatvaPay
Docs menu· Razorpay (test mode)

Payments on Razorpay (test mode)

Planned

The hosted payment page and sandbox simulator you can try now, and the planned Razorpay integration in test mode.

Planned. Razorpay is a planned integration. It is being built against Razorpay's documented API on recorded fixtures, and goes live in test mode once TatvaPay's own Razorpay account and test keys exist. Until then, the hosted payment page runs on the sandbox simulator: no real money moves.

A seller agent makes a quote that names the buyer agent (buyer_agent_id). The buyer's person can approve and pay that quote on a hosted payment page: a link of the form app.tatvapay.com/pay/<quote_id>. Nobody signs in; the person approves the payment on the payment page itself, and the payment still runs through the buyer's rules and lands on a signed receipt. Payment Recovery and Cart Recovery send these links. The page shows the seller, the line items, the total and when the quote expires.

The buyer pays through a licensed payment partner; TatvaPay never holds the money.

What works now, and what is planned

Capability Status
Hosted payment page (/pay/<quote_id>) with a status page Next (sandbox)
Sandbox simulator: end a payment as success or failure, no real money Next (sandbox)
Razorpay orders and Razorpay Checkout on the hosted page, in test mode Planned
UPI AutoPay, e-mandates and card recurring mandates, with a pre-debit notice Planned
Payment links Planned
Refunds, always approved by a person Planned
Settlements fed into the Reconciliation agent Planned
Razorpay webhooks at /v1/webhooks/razorpay Planned
UPI Reserve Pay Planned (pending Razorpay enabling it for us)

Every Planned row is built against Razorpay's documented API on recorded fixtures, and goes live once TatvaPay's own Razorpay account and test keys exist. Nothing here is live.

The hosted payment page

Send the buyer the link. The page reads the quote from the public, unauthenticated pay API:

GET /v1/public/pay/quotes/{quote_id}
{
  "quote": {"id": "qt_…", "seller_name": "…", "amount_paise": 150000, "currency": "INR",
            "line_items": [{"name": "Airport transfer", "quantity": 1, "unit_paise": 150000, "amount_paise": 150000}],
            "expires_at": "…", "status": "…"},
  "rail": "sandbox",
  "mode": "sandbox",
  "payable": true,
  "reason": "",
  "checkout": null
}

rail is sandbox today; razorpay once the integration is live. mode is sandbox, test (Razorpay's test mode, shown on the page as TEST MODE) or live. When payable is false, reason says why in words for the buyer. Amounts are always integer paise.

Pay starts a checkout, then the page completes it:

POST /v1/public/pay/quotes/{quote_id}/checkout
POST /v1/public/pay/quotes/{quote_id}/checkout/{checkout_id}/complete
GET  /v1/public/pay/quotes/{quote_id}/checkout/{checkout_id}

A checkout is created, processing, paid, failed or expired. After paying, the buyer lands on /pay/<quote_id>/status?checkout=<checkout_id>, which checks every few seconds until the payment is settled one way or the other, and shows the payment's reference (its intent id) once paid. A paid quote raises intent.settled to the seller like any other payment (webhooks).

The sandbox simulator

On the sandbox the page shows a panel labelled Sandbox simulator — no real money, with Simulate success and Simulate failure. Each sends {"outcome": "success"} or {"outcome": "failure"} to /complete. Use it to test your seller agent's handling of both endings.

Razorpay Checkout (planned)

Planned. Not live. This section describes how the hosted page will use Razorpay in test mode.

When rail is razorpay, POST …/checkout creates a Razorpay order on the server and returns what Razorpay Checkout needs (key_id, order_id, amount in paise, currency, name, description, callback_url). The page opens Razorpay Checkout with those values. Razorpay's answer (razorpay_payment_id, razorpay_order_id, razorpay_signature) goes to /complete, where the engine checks the signature with the key secret on the server; the browser never sees a secret. If Razorpay redirects instead, it posts the same fields to /pay/<quote_id>/return, which completes the payment the same way. A failed attempt can be retried on the same order.

Test data

In Razorpay's test mode no money moves. Pay with the test details from Razorpay's public test documentation, for example the test UPI ids:

UPI id Result
success@razorpay The payment succeeds
failure@razorpay The payment fails

Recurring payments (planned)

UPI AutoPay, e-mandates and card recurring mandates will sit under a TatvaPay mandate. Before each debit, Razorpay notifies the customer with a pre-debit notice, and the debit runs at least 24 hours later. The customer can pause or cancel in the consent centre or with their bank or UPI app.

Refunds (planned)

Refunds on Razorpay payments use the same flow as every TatvaPay refund: an agent can ask, but a person in the seller's workspace always approves it. No agent can refund on its own.

Settlements (planned)

Razorpay settlement reports go to the Reconciliation agent (TatvaPay Agents), which matches each settlement to its payments, fees and refunds.

Webhooks from Razorpay (planned)

Razorpay will send events to POST /v1/webhooks/razorpay. The engine:

  • checks X-Razorpay-Signature, an HMAC-SHA256 of the raw body with the webhook secret, and refuses anything that does not match;
  • records each X-Razorpay-Event-Id and ignores a repeat, so a retried event is applied once.

You do not configure this endpoint; TatvaPay does. Your servers keep receiving TatvaPay's own signed webhooks.

UPI Reserve Pay (planned)

Reserve Pay blocks an amount in the buyer's UPI account and debits it in parts, which suits pay-per-call agents. It is planned, pending Razorpay enabling it for us.

Last updated 2 October 2026

Something unclear or wrong? Tell us