@deiondz/better-auth-razorpay 2.0.9 → 2.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -63,8 +63,57 @@ The package includes `razorpay` and `zod` as dependencies.
63
63
 
64
64
  2. **Configure the Plugin**
65
65
 
66
+ You can either pass an existing Razorpay instance (`razorpayClient`) or let the plugin create it from credentials (`razorpayKeyId` + `razorpayKeySecret`).
67
+
68
+ **Option A: Pass credentials (plugin creates the Razorpay instance)**
69
+
66
70
  ```typescript
67
71
  // src/lib/auth.ts (or your auth configuration file)
72
+ import { betterAuth } from 'better-auth'
73
+ import { razorpayPlugin } from '@deiondz/better-auth-razorpay'
74
+
75
+ export const auth = betterAuth({
76
+ // ... your Better Auth configuration
77
+ database: mongodbAdapter(await connect()), // or your adapter
78
+ secret: process.env.BETTER_AUTH_SECRET,
79
+ baseURL: process.env.BETTER_AUTH_URL,
80
+
81
+ plugins: [
82
+ razorpayPlugin({
83
+ razorpayKeyId: process.env.RAZORPAY_KEY_ID!,
84
+ razorpayKeySecret: process.env.RAZORPAY_KEY_SECRET!, // also enables verify-payment endpoint when set
85
+ razorpayWebhookSecret: process.env.RAZORPAY_WEBHOOK_SECRET,
86
+ createCustomerOnSignUp: true, // optional
87
+ subscription: {
88
+ enabled: true,
89
+ plans: [
90
+ {
91
+ name: 'Starter',
92
+ monthlyPlanId: 'plan_xxxxxxxxxxxx',
93
+ annualPlanId: 'plan_yyyyyyyyyyyy', // optional
94
+ limits: { features: 5 },
95
+ freeTrial: { days: 7 }, // optional
96
+ },
97
+ ],
98
+ onSubscriptionActivated: async ({ subscription, plan }) => {
99
+ console.log(`Subscription ${subscription.id} activated for plan ${plan.name}`)
100
+ },
101
+ },
102
+ onWebhookEvent: async (payload, context) => {
103
+ const { event, subscription, payment } = payload
104
+ if (event === 'subscription.charged' && payment) {
105
+ // Send confirmation email, etc.
106
+ }
107
+ },
108
+ }),
109
+ ],
110
+ })
111
+ ```
112
+
113
+ **Option B: Pass an existing Razorpay client**
114
+
115
+ ```typescript
116
+ // src/lib/auth.ts
68
117
  import Razorpay from 'razorpay'
69
118
  import { betterAuth } from 'better-auth'
70
119
  import { razorpayPlugin } from '@deiondz/better-auth-razorpay'
@@ -76,7 +125,7 @@ const razorpayClient = new Razorpay({
76
125
 
77
126
  export const auth = betterAuth({
78
127
  // ... your Better Auth configuration
79
- database: mongodbAdapter(await connect()), // or your adapter
128
+ database: mongodbAdapter(await connect()),
80
129
  secret: process.env.BETTER_AUTH_SECRET,
81
130
  baseURL: process.env.BETTER_AUTH_URL,
82
131
 
@@ -165,9 +214,10 @@ npx @better-auth/cli@latest generate
165
214
 
166
215
  ```typescript
167
216
  interface RazorpayPluginOptions {
168
- razorpayClient: Razorpay // Required: Initialized Razorpay instance (key_id, key_secret)
169
- razorpayWebhookSecret?: string // Optional: Webhook secret for signature verification
170
- razorpayKeySecret?: string // Optional: API key secret for payment signature verification; when set, enables POST /razorpay/verify-payment (same secret as Razorpay client, not webhook secret)
217
+ razorpayClient?: Razorpay // Optional: Initialized Razorpay instance; omit when using razorpayKeyId + razorpayKeySecret
218
+ razorpayKeyId?: string // Optional: Razorpay API key ID; required when razorpayClient is not provided (plugin creates the instance)
219
+ razorpayKeySecret?: string // Optional: Razorpay API key secret; required when razorpayClient is not provided; when set, enables POST /razorpay/verify-payment
220
+ razorpayWebhookSecret?: string // Optional: Webhook secret for signature verification
171
221
  createCustomerOnSignUp?: boolean // Optional: Create Razorpay customer on user sign-up (default: false)
172
222
  onCustomerCreate?: (args) => Promise<void>
173
223
  getCustomerCreateParams?: (args) => Promise<{ params?: Record<string, unknown> }>
@@ -287,7 +337,7 @@ All endpoints are prefixed with `/api/auth/razorpay/` (or your configured `baseP
287
337
 
288
338
  | Action | Method | Endpoint | Description |
289
339
  |--------|--------|----------|-------------|
290
- | Create or update | `POST` | `subscription/create-or-update` | Start a subscription or update; returns `checkoutUrl` for Razorpay payment page. Body: `plan`, `annual?`, `seats?`, `subscriptionId?`, `successUrl?`, `disableRedirect?`. |
340
+ | Create or update | `POST` | `subscription/create-or-update` | Start a subscription or update; returns `checkoutUrl` for Razorpay payment page. Body: `plan` (plan **name** or Razorpay plan ID `plan_*`), `annual?`, `seats?`, `subscriptionId?`, `successUrl?`, `disableRedirect?`. |
291
341
  | Cancel | `POST` | `subscription/cancel` | Cancel by local subscription ID. Body: `subscriptionId`, `immediately?`. |
292
342
  | Restore | `POST` | `subscription/restore` | Restore a subscription scheduled to cancel. Body: `subscriptionId`. |
293
343
  | List | `GET` | `subscription/list` | List active/trialing subscriptions. Query: `referenceId?` (default: current user). |
@@ -685,6 +735,7 @@ if (plansRes.success) console.log(plansRes.data)
685
735
  const listRes = await authClient.razorpay.listSubscriptions({ referenceId: 'optional' })
686
736
 
687
737
  // Create or update subscription (returns checkoutUrl for Razorpay payment page)
738
+ // plan: use the plan name (e.g. 'Starter') or the Razorpay plan ID (e.g. 'plan_xxxxxxxxxxxx')
688
739
  const result = await authClient.razorpay.createOrUpdateSubscription({
689
740
  plan: 'Starter',
690
741
  annual: false,
@@ -1,10 +1,10 @@
1
- import { S as SubscriptionRecord } from '../types-B25gyPpX.js';
1
+ import { S as SubscriptionRecord } from '../types-VZW_XCzQ.js';
2
2
  import * as _tanstack_react_query from '@tanstack/react-query';
3
3
  import { UseMutationOptions, UseQueryOptions } from '@tanstack/react-query';
4
4
  import * as react from 'react';
5
5
  import { ReactNode } from 'react';
6
- import { c as RazorpayAuthClient, d as CancelSubscriptionResponse, a as CancelSubscriptionInput, e as CreateOrUpdateSubscriptionResponse, C as CreateOrUpdateSubscriptionInput, P as PlanSummary, f as RestoreSubscriptionResponse, b as RestoreSubscriptionInput, g as ListSubscriptionsResponse, h as VerifyPaymentResponse, V as VerifyPaymentInput, L as ListSubscriptionsInput } from '../types-C0_Sreb6.js';
7
- export { G as GetPlansResponse, i as RazorpayApiError, R as RazorpayApiResult, j as RazorpayClientActions } from '../types-C0_Sreb6.js';
6
+ import { c as RazorpayAuthClient, d as CancelSubscriptionResponse, a as CancelSubscriptionInput, e as CreateOrUpdateSubscriptionResponse, C as CreateOrUpdateSubscriptionInput, P as PlanSummary, f as RestoreSubscriptionResponse, b as RestoreSubscriptionInput, g as ListSubscriptionsResponse, h as VerifyPaymentResponse, V as VerifyPaymentInput, L as ListSubscriptionsInput } from '../types-C2IdKTof.js';
7
+ export { G as GetPlansResponse, i as RazorpayApiError, R as RazorpayApiResult, j as RazorpayClientActions } from '../types-C2IdKTof.js';
8
8
  import 'razorpay';
9
9
 
10
10
  /** Context holding the Razorpay-capable auth client. Default is null. */
package/dist/client.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { S as SubscriptionRecord } from './types-B25gyPpX.js';
1
+ import { S as SubscriptionRecord } from './types-VZW_XCzQ.js';
2
2
  import { razorpayPlugin } from './index.js';
3
- import { R as RazorpayApiResult, P as PlanSummary, L as ListSubscriptionsInput, C as CreateOrUpdateSubscriptionInput, a as CancelSubscriptionInput, b as RestoreSubscriptionInput, V as VerifyPaymentInput } from './types-C0_Sreb6.js';
3
+ import { R as RazorpayApiResult, P as PlanSummary, L as ListSubscriptionsInput, C as CreateOrUpdateSubscriptionInput, a as CancelSubscriptionInput, b as RestoreSubscriptionInput, V as VerifyPaymentInput } from './types-C2IdKTof.js';
4
4
  import 'razorpay';
5
5
  import 'better-auth';
6
6
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { BetterAuthPlugin } from 'better-auth';
2
- import { R as RazorpayPluginOptions } from './types-B25gyPpX.js';
3
- export { O as OnWebhookEventCallback, a as RazorpayApiResponse, b as RazorpayErrorResponse, c as RazorpayPlan, d as RazorpaySubscription, e as RazorpaySuccessResponse, f as RazorpayUserRecord, g as RazorpayWebhookContext, h as RazorpayWebhookEvent, i as RazorpayWebhookPayload, S as SubscriptionRecord, j as SubscriptionStatus } from './types-B25gyPpX.js';
2
+ import { R as RazorpayPluginOptions } from './types-VZW_XCzQ.js';
3
+ export { O as OnWebhookEventCallback, a as RazorpayApiResponse, b as RazorpayErrorResponse, c as RazorpayPlan, d as RazorpaySubscription, e as RazorpaySuccessResponse, f as RazorpayUserRecord, g as RazorpayWebhookContext, h as RazorpayWebhookEvent, i as RazorpayWebhookPayload, S as SubscriptionRecord, j as SubscriptionStatus } from './types-VZW_XCzQ.js';
4
4
  import 'razorpay';
5
5
 
6
6
  interface WebhookResult {
@@ -18,9 +18,10 @@ interface WebhookResult {
18
18
  * - Plans: named plans with monthly/annual IDs, limits, free trial
19
19
  *
20
20
  * @param options - Plugin configuration
21
- * @param options.razorpayClient - Initialized Razorpay instance (key_id, key_secret)
21
+ * @param options.razorpayClient - Initialized Razorpay instance (optional; omit when using razorpayKeyId + razorpayKeySecret)
22
+ * @param options.razorpayKeyId - Razorpay API key ID (required when razorpayClient is not provided; plugin creates the Razorpay instance)
23
+ * @param options.razorpayKeySecret - Razorpay API key secret (required when razorpayClient is not provided; when set, also enables POST /razorpay/verify-payment)
22
24
  * @param options.razorpayWebhookSecret - Webhook secret for signature verification
23
- * @param options.razorpayKeySecret - API key secret for payment signature verification (optional; when set, enables POST /razorpay/verify-payment)
24
25
  * @param options.createCustomerOnSignUp - Create Razorpay customer when user signs up (default: false)
25
26
  * @param options.onCustomerCreate - Callback after customer is created
26
27
  * @param options.getCustomerCreateParams - Custom params when creating customer
package/dist/index.js CHANGED
@@ -2,6 +2,9 @@ import {
2
2
  __export
3
3
  } from "./chunk-PZ5AY32C.js";
4
4
 
5
+ // index.ts
6
+ import Razorpay from "razorpay";
7
+
5
8
  // api/cancel-subscription.ts
6
9
  import { createAuthEndpoint, sessionMiddleware } from "better-auth/api";
7
10
 
@@ -4114,7 +4117,7 @@ function handleRazorpayError(error) {
4114
4117
 
4115
4118
  // lib/schemas.ts
4116
4119
  var createOrUpdateSubscriptionSchema = external_exports.object({
4117
- plan: external_exports.string().min(1, "Plan name is required"),
4120
+ plan: external_exports.string().min(1, "Plan name or Razorpay plan ID (plan_*) is required"),
4118
4121
  annual: external_exports.boolean().optional().default(false),
4119
4122
  seats: external_exports.number().int().min(1).optional().default(1),
4120
4123
  subscriptionId: external_exports.string().optional(),
@@ -4238,7 +4241,9 @@ var createOrUpdateSubscription = (razorpay, options) => createAuthEndpoint2(
4238
4241
  };
4239
4242
  }
4240
4243
  const plans = await resolvePlans(subOpts.plans);
4241
- const plan = plans.find((p) => p.name === body.plan);
4244
+ const plan = body.plan.startsWith("plan_") ? plans.find(
4245
+ (p) => p.monthlyPlanId === body.plan || p.annualPlanId === body.plan
4246
+ ) : plans.find((p) => p.name === body.plan);
4242
4247
  if (!plan) {
4243
4248
  return {
4244
4249
  success: false,
@@ -4414,6 +4419,7 @@ var getPlans = (options) => createAuthEndpoint3("/razorpay/get-plans", { method:
4414
4419
  name: p.name,
4415
4420
  monthlyPlanId: p.monthlyPlanId,
4416
4421
  annualPlanId: p.annualPlanId,
4422
+ description: p.description,
4417
4423
  limits: p.limits,
4418
4424
  freeTrial: p.freeTrial ? { days: p.freeTrial.days } : void 0
4419
4425
  }))
@@ -4824,18 +4830,31 @@ async function processWebhookEvent(adapter, rawBody, fallbackBody, onWebhookEven
4824
4830
  var razorpayPlugin = (options) => {
4825
4831
  const {
4826
4832
  razorpayClient,
4827
- razorpayWebhookSecret,
4833
+ razorpayKeyId,
4828
4834
  razorpayKeySecret,
4835
+ razorpayWebhookSecret,
4829
4836
  createCustomerOnSignUp = false,
4830
4837
  onCustomerCreate,
4831
4838
  getCustomerCreateParams,
4832
4839
  subscription: subOpts,
4833
4840
  onEvent
4834
4841
  } = options;
4835
- if (!razorpayClient) {
4836
- throw new Error("Razorpay plugin: razorpayClient is required");
4837
- }
4838
- const razorpay = razorpayClient;
4842
+ const hasClient = Boolean(razorpayClient);
4843
+ const hasCredentials = Boolean(razorpayKeyId && razorpayKeySecret);
4844
+ if (!hasClient && !hasCredentials) {
4845
+ throw new Error(
4846
+ "Razorpay plugin: provide either razorpayClient or both razorpayKeyId and razorpayKeySecret"
4847
+ );
4848
+ }
4849
+ if (hasClient && hasCredentials) {
4850
+ throw new Error(
4851
+ "Razorpay plugin: provide either razorpayClient or credentials (razorpayKeyId + razorpayKeySecret), not both"
4852
+ );
4853
+ }
4854
+ if (!hasClient && (typeof razorpayKeyId !== "string" || typeof razorpayKeySecret !== "string")) {
4855
+ throw new Error("Razorpay plugin: both razorpayKeyId and razorpayKeySecret are required when not providing razorpayClient");
4856
+ }
4857
+ const razorpay = razorpayClient ?? new Razorpay({ key_id: razorpayKeyId, key_secret: razorpayKeySecret });
4839
4858
  const plugin = {
4840
4859
  id: "razorpay-plugin",
4841
4860
  schema: {