Skip to content

Conversation

@hackerrahul
Copy link

@hackerrahul hackerrahul commented Dec 4, 2025

📝 Description

Added 2 type definition for hooks and modified hooks to match better-auth stripe's hooks

  1. onUserCreate : onCustomerCreate
  2. onUserUpdate: onCustomerUpdate

🔄 Type of Change

Please check the type of change your PR introduces:

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 🚀 New adapter (adds support for a new framework)
  • 📚 Documentation (changes to documentation only)
  • 🎨 Code style (formatting, missing semicolons, etc; no production code change)
  • ♻️ Refactoring (code change that neither fixes a bug nor adds a feature)
  • Performance (code change that improves performance)

🎯 Affected Packages

Which packages are affected by this change:

  • @dodopayments/core
  • @dodopayments/nextjs
  • @dodopayments/express
  • @dodopayments/fastify
  • @dodopayments/hono
  • @dodopayments/remix
  • @dodopayments/sveltekit
  • @dodopayments/astro
  • @dodopayments/tanstack
  • @dodopayments/nuxt
  • @dodopayments/betterauth
  • @dodopayments/convex
  • Examples
  • Documentation

📚 Documentation

  • I have updated the README.md (if applicable)
  • I have added/updated code comments for complex logic
  • I have updated the CHANGELOG.md (if applicable)

🔍 Code Quality

  • My code follows the project's style guidelines
  • I have performed a self-review of my own code
  • My changes generate no new warnings
  • I have checked my code for potential security issues

🚀 Framework Adapter Checklist

If you're adding a new framework adapter, please ensure:

  • Follows the standard adapter pattern
  • Implements all three core functions (Checkout, Webhooks, CustomerPortal)
  • Has framework-specific documentation
  • Includes working example implementation
  • Follows framework conventions and best practices
  • Has proper TypeScript types
  • Handles errors appropriately

🔐 Security Considerations

  • I have not exposed any sensitive information (API keys, secrets)
  • My changes don't introduce security vulnerabilities
  • I have followed security best practices
  • Input validation is properly implemented
  • Error messages don't leak sensitive information

📖 Additional Context

Add any other context, screenshots, or additional information about the PR here.

Breaking Changes

Dependencies

  • I have not added unnecessary dependencies
  • New dependencies are justified and documented
  • Dependencies are compatible with project requirements
  • I have updated package.json correctly

🎯 Reviewer Notes

Specific areas to focus on during review:

  • API Design - Check consistency with existing patterns
  • Error Handling - Verify proper error handling and messages
  • Type Safety - Ensure full TypeScript compliance
  • Framework Integration - Verify framework-specific implementation
  • Documentation - Check completeness and accuracy
  • Security - Review for potential security issues

📋 Pre-merge Checklist

  • All CI checks are passing
  • Code has been reviewed and approved
  • Documentation is complete and accurate
  • Breaking changes are properly documented
  • CHANGELOG.md is updated (if applicable)

By submitting this pull request, I confirm that my contribution is made under the terms of the GPL v3 license and that I have the right to submit this work under this license.

Summary by CodeRabbit

  • New Features
    • Added optional callbacks for DodoPayments customer lifecycle events: onCustomerCreate (triggered after customer creation) and onCustomerUpdate (triggered after customer updates). These callbacks enable custom handling of customer data following sign-up and profile modifications.

✏️ Tip: You can customize this high-level summary in your review settings.

Added 2 type definition for hooks and modified hooks to match better-auth stripe's hooks

1. onUserCreate : onCustomerCreate
2. onUserUpdate: onCustomerUpdate
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 4, 2025

Walkthrough

The changes integrate DodoPayments customer lifecycle callbacks into better-auth's customer hooks. New optional callbacks (onCustomerCreate and onCustomerUpdate) are added to type definitions and invoked after customer operations complete with merged customer and user data.

Changes

Cohort / File(s) Summary
DodoPayments Customer Lifecycle Callbacks
packages/betterauth/src/hooks/customer.ts, packages/betterauth/src/types.ts
Imports updated to include GenericEndpointContext and User types. Two optional callbacks added to DodoPaymentsOptions interface: onCustomerCreate and onCustomerUpdate, each receiving customer data merged with user information extended by DodoPaymentsCustomerId and execution context. Hook implementation invokes callbacks after customer create/update operations if present and successful.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Verify callback invocation guards correctly check for both callback presence and successful customer operations
  • Confirm type signatures for callback parameters accurately reflect the merged data structure and context

Poem

🐰 A dodo hops, a payment flows,
When customers bloom, the callback grows!
Create and update with grace so fine,
Lifecycle hooks in perfect line. 💳✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description provides clear context about the hooks being added and references the Stripe pattern being followed, with appropriate package selection and security considerations checked.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title accurately describes the main change: adding customer lifecycle hooks (onCustomerCreate and onCustomerUpdate) to the betterauth integration, which is the primary focus of the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/betterauth/src/types.ts (2)

41-55: JSDoc @param tags are misleading and | undefined is redundant.

The @param customer tag references a parameter that doesn't exist in the callback signature. The actual parameters are data (containing DodoCustomer and user) and ctx. Also, | undefined is redundant since the property is already optional with ?.

   /**
-	 * A callback to run after a customer has been created
-	 * @param customer - Customer Data
-	 * @param DodoCustomer - DodoPayments Customer Data
-	 * @returns
+	 * A callback to run after a customer has been created.
+	 * @param data - Contains DodoCustomer and user with DodoPaymentsCustomerId
+	 * @param ctx - The endpoint context
 	 */
   onCustomerCreate?:
-		| ((
+		(
 				data: {
 					DodoCustomer: DodoPayments.Customer;
 					user: User & { DodoPaymentsCustomerId: string };
 				},
 				ctx: GenericEndpointContext,
-		  ) => Promise<void>)
-		| undefined;
+		) => Promise<void>;

56-70: Same JSDoc and redundancy issues as onCustomerCreate.

Apply the same fixes for consistency.

   /**
-	 * A callback to run after a customer has been updated
-	 * @param customer - Customer Data
-	 * @param DodoCustomer - DodoPayments Customer Data
-	 * @returns
+	 * A callback to run after a customer has been updated.
+	 * @param data - Contains DodoCustomer and user with DodoPaymentsCustomerId
+	 * @param ctx - The endpoint context
 	 */
   onCustomerUpdate?:
-		| ((
+		(
 				data: {
 					DodoCustomer: DodoPayments.Customer;
 					user: User & { DodoPaymentsCustomerId: string };
 				},
 				ctx: GenericEndpointContext,
-		  ) => Promise<void>)
-		| undefined;
+		) => Promise<void>;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 24cb915 and e3d3bc3.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • packages/betterauth/src/hooks/customer.ts (3 hunks)
  • packages/betterauth/src/types.ts (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Checks
🔇 Additional comments (3)
packages/betterauth/src/hooks/customer.ts (3)

17-50: onCustomerCreate is invoked even when customer already exists.

When existingCustomer.email === user.email (lines 25-26), no creation or update occurs—the existing customer is simply reused. Yet onCustomerCreate is still called at line 39-50. This may confuse consumers expecting the callback only when a customer is newly created.

Consider whether this is intentional. If not, you could:

  1. Only invoke onCustomerCreate when a new customer is actually created (the else branch at line 32).
  2. Invoke onCustomerUpdate when updating an existing customer (line 19-24).
  3. Skip the callback entirely when the customer already exists unchanged.
+        let wasCreated = false;
         let dodoCustomer: DodoPayments.Customer | undefined;
         if (existingCustomer) {
           if (existingCustomer.email !== user.email) {
             dodoCustomer = await options.client.customers.update(
               existingCustomer.customer_id,
               {
                 name: user.name,
               },
             );
+            // Optionally call onCustomerUpdate here instead
           } else {
             dodoCustomer = existingCustomer;
+            // No callback - customer unchanged
           }
         } else {
           // TODO: Add metadata to customer object via
           // getCustomerCreateParams option when it becomes
           // available in the API
           dodoCustomer = await options.client.customers.create({
             email: user.email,
             name: user.name,
           });
+          wasCreated = true;
         }

         // Call the onCustomerCreate callback if provided
-        if (options.onCustomerCreate && dodoCustomer) {
+        if (options.onCustomerCreate && dodoCustomer && wasCreated) {
           await options.onCustomerCreate(

79-98: LGTM!

The onCustomerUpdate callback is correctly invoked only after a successful update operation. The guard check for updatedCustomer is technically always truthy after the await (since exceptions would throw), but it provides safe defensive coding.


4-4: The import statement referenced in this review comment does not exist in packages/betterauth/src/hooks/customer.ts. Line 4 contains import type { DodoPaymentsOptions } from "../types";, not an import of DodoPayments from the dodopayments package. The file does not import or use DodoPayments directly.

Likely an incorrect or invalid review comment.

@hackerrahul hackerrahul changed the title added hooks in types Add customer lifecycle hooks to betterauth integration Dec 4, 2025
@hackerrahul hackerrahul changed the title Add customer lifecycle hooks to betterauth integration feat. Add customer lifecycle hooks to betterauth integration Dec 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant