completed · featured
A comprehensive Razorpay integration plugin for Better Auth, bringing one-time payments, recurring subscriptions, invoices, refunds, customer management, marketplace transfers, and webhook handling into a unified, type-safe TypeScript API.

A comprehensive Razorpay integration for Better Auth that brings payment processing, recurring billing, and payment operations into a unified TypeScript plugin. It connects Better Auth's authentication and database ecosystem with Razorpay's APIs, reducing the amount of custom payment infrastructure application teams need to maintain.
Repository: https://github.com/Amank-root/better-auth-razorpay
Payment integration involves more than opening a checkout window. Production applications need order creation, server-side verification, refunds, subscription lifecycle management, invoices, customer records, marketplace transfers, and reliable webhook processing.
Better Auth Razorpay brings these capabilities behind Better Auth plugin endpoints and optional React Query hooks.
The plugin sits between the application and Razorpay. The Better Auth server handles authenticated requests, the Razorpay plugin exposes payment routes and invokes the Razorpay SDK, and the database stores application-side customer and subscription information. Razorpay webhooks deliver asynchronous payment and billing events back to the plugin.
The plugin includes HMAC-SHA256 payment signature verification and a separate status-validation helper. The latter checks the fetched payment's order association, optional expected amount, and captured status. Applications should perform verification on the server and use webhook events as part of reliable fulfillment.
Create Razorpay orders with amount, currency, receipt, notes, and supported partial-payment options. The plugin also exposes payment retrieval, listing, capture, editing, and refund operations.
Amounts use the smallest currency unit: for INR, 50000 represents ₹500.
Example:
tsconst order = await auth.api.razorpayCreateOrder({ body: { amount: 50000, currency: "INR", receipt: "receipt_001", }, });
Subscription functionality includes plan configuration, creation or upgrade, retrieval, updates, pause and resume, cancellation, restoration, pending updates, invoices, and add-ons. Subscription data is represented in the Better Auth database and can be associated with a user or organization.
The plugin verifies webhook signatures and maps Razorpay events to callbacks. Supported event families include payment authorized/captured/failed, order paid, refund created/processed/failed, invoice paid/partially paid/expired, and subscription authentication, activation, charge, cancellation, pause, resume, halt, pending, completion, update, renewal, and offer-update events. A generic onEvent callback is also available.
Webhook consumers should make fulfillment and synchronization idempotent because providers may retry event delivery.
Invoice operations cover creation, retrieval, editing, issuance, notification, cancellation, and deletion. Refund operations include initiation and refund retrieval/listing/editing. Customer operations include create, update, list, retrieval, bank-account management, and saved-token management.
For eligible Razorpay Route accounts, the plugin supports creating transfers to linked accounts, applying settlement holds, retrieving and editing transfers, and reversing transfers.
The optional React entry point provides TanStack Query hooks for subscriptions, payments, refunds, invoices, orders, customers, add-ons, and items. Structured query keys support cache management and invalidation.
tsximport { useSubscriptionList, useUpgradeSubscription, } from "@amank-root/better-auth-razorpay/react"; function BillingPage() { const { data, isLoading } = useSubscriptionList(authClient); const upgrade = useUpgradeSubscription(authClient); if (isLoading) return <p>Loading...</p>; return ( <> {data?.map((subscription) => ( <p key={subscription.id}>{subscription.plan}</p> ))} <button onClick={() => upgrade.mutate({ plan: "pro", annual: true })}> Upgrade </button> </> ); }
Install the package:
bashnpm install @amank-root/better-auth-razorpay
Register the plugin with Better Auth on the server:
tsimport { betterAuth } from "better-auth"; import { razorpayPlugin } from "@amank-root/better-auth-razorpay"; export const auth = betterAuth({ database: yourDatabaseConfig, plugins: [ razorpayPlugin({ keyId: process.env.RAZORPAY_KEY_ID!, keySecret: process.env.RAZORPAY_KEY_SECRET!, razorpayWebhookSecret: process.env.RAZORPAY_WEBHOOK_SECRET!, defaultCurrency: "INR", }), ], });
Keep Razorpay secrets server-side. Configure the webhook endpoint and secret in the Razorpay dashboard, and apply the database schema changes required by the plugin. For subscription billing, enable the subscription option and configure Razorpay plan IDs. Refer to the repository README for the full configuration and API reference.
SaaS products that need recurring plans and trials, marketplaces that need linked-account transfers, membership platforms that tie access to payment state, and full-stack teams that want a reusable Better Auth integration instead of repeatedly building payment plumbing.
Better Auth Razorpay provides a single integration surface for checkout, subscriptions, invoices, refunds, customer operations, transfers, and webhook-driven billing workflows. It is designed to make payment infrastructure easier to integrate into applications already using Better Auth.
Explore the source code: https://github.com/Amank-root/better-auth-razorpay
November 2026