Razorpay model
| Razorpay concept | Meaning in InsForge |
|---|---|
| Item | Amount-bearing sellable unit. Mirrored in payments.razorpay_items. |
| Plan | Recurring subscription definition around an item. Mirrored in payments.razorpay_plans. |
| Order | One-time payment object. Created through POST /api/payments/razorpay/{environment}/orders and mirrored in payments.razorpay_orders. |
| Payment | Provider payment result. Projected into payments.transactions from webhooks and sync. |
| Subscription | Razorpay subscription tied to a Plan. Mirrored in payments.razorpay_subscriptions. |
| Webhook event | Verified provider event in payments.webhook_events with provider = 'razorpay'. |
payments.razorpay_subscriptions RLS UPDATE policies.
For one-time products, Razorpay Orders can be created with only an amount, currency, and receipt. Still, prefer creating Razorpay Items for sellable products so the catalog is visible in InsForge and Razorpay after sync. Treat Orders as payment attempts, not as your product catalog.
Setup
Configuretest and live Razorpay Key ID and Key Secret in Dashboard -> Payments -> Settings or through the admin API. InsForge generates a webhook signing secret if one does not already exist.
Razorpay webhooks must be created manually in the Razorpay Dashboard. Razorpay normal merchant API keys do not support automatic webhook registration.
- Open Dashboard -> Payments -> Settings -> Webhooks.
- Copy the Razorpay Webhook URL and Webhook Secret.
- In the Razorpay Dashboard, create a webhook with the copied URL and secret.
- Select the events InsForge handles.
- Save the webhook and complete a test payment to confirm delivery.
payment.authorizedpayment.capturedpayment.failedorder.paidinvoice.paidinvoice.expiredrefund.createdrefund.processedrefund.failedsubscription.createdsubscription.activatedsubscription.chargedsubscription.updatedsubscription.cancelledsubscription.pausedsubscription.resumedsubscription.haltedsubscription.completedsubscription.expired
One-time orders
Create an app-owned pending order first. Then create a Razorpay Order with the current InsForge user token.POST /api/payments/razorpay/{environment}/orders. The response includes checkoutOptions with Razorpay Checkout-native fields such as key and order_id. Load https://checkout.razorpay.com/v1/checkout.js in the frontend and pass those options to new Razorpay(options).open().
If your fulfillment trigger reads notes.order_id, pass notes: { order_id: ... } when creating the Order or Subscription.
After Razorpay Checkout returns razorpay_order_id, razorpay_payment_id, and razorpay_signature, verify the signature on the backend:
Subscriptions
Create or sync a Razorpay Plan before creating subscriptions. A Plan is not the same thing as a Stripe Price. It is a recurring definition around a Razorpay Item.POST /api/payments/razorpay/{environment}/subscriptions. The response includes checkoutOptions.subscription_id. Open Razorpay Checkout with that subscription ID. After Checkout returns razorpay_subscription_id, razorpay_payment_id, and razorpay_signature, verify the authorization payment:
INSERT policies on payments.razorpay_subscriptions. Cancel, pause, and resume evaluate UPDATE policies on the same table. PostgreSQL also applies SELECT policies to rows returned by INSERT/UPDATE ... RETURNING, so make the same subject visible to the caller when a policy probe needs to return the row. Grant users only the table access needed for policy checks; provider mutations still run through the backend.
Webhooks and fulfillment
Razorpay’s Checkout callback and signature verification are not a replacement for webhooks. Usepayments.webhook_events for fulfillment triggers. Do not attach fulfillment triggers to provider mirror tables such as payments.razorpay_subscriptions; sync and webhook projection can update those rows independently of provider event delivery.
Sync and dashboard state
Razorpay sync mirrors Items, Plans, Customers, Subscriptions, Invoices, and Payments. Invoices and payments feed thepayments.transactions dashboard/reporting projection. Transactions include provider reference IDs such as payment, invoice, order, subscription, and refund IDs so you can inspect the source record in the Razorpay Dashboard.
Keep user-facing order, credit, and entitlement state in your own app tables. Treat payments.transactions as dashboard/reporting state, not as the primary business workflow.