Skip to main content

Overview

The createUser function creates a new user record in the database after Supabase authentication. It retrieves the authenticated user, checks if they already exist in the database, creates a Dodo Payments customer, and then inserts a new user record.

Function Signature

export async function createUser(): ServerActionRes<string>

Parameters

This function does not accept any parameters. It automatically retrieves the authenticated user from the Supabase session.

Return Value

success
boolean
required
Indicates whether the operation was successful
data
string
Success message: either “User created” or “User already exists”
error
string
Error message if the operation failed. Possible values:
  • “User not found” - No authenticated user session
  • “Failed to create customer” - Dodo Payments customer creation failed

Implementation Details

The function performs the following steps:
  1. Retrieves the authenticated user via getUser()
  2. Checks if a user record already exists with the Supabase user ID
  3. If the user exists, returns success without creating a duplicate
  4. Creates a Dodo Payments customer using the user’s email and name
  5. Inserts a new user record with:
    • supabaseUserId: The Supabase authentication user ID
    • dodoCustomerId: The Dodo Payments customer ID
    • currentSubscriptionId: Empty string (no subscription yet)
    • createdAt: Current timestamp
    • updatedAt: Current timestamp

Error Handling

The function returns structured error responses:
  • Returns { success: false, error: "User not found" } if authentication fails
  • Returns { success: false, error: "Failed to create customer" } if Dodo customer creation fails
  • Returns { success: true, data: "User already exists" } if user record already exists (idempotent)

Usage Example

import { createUser } from '@/actions/create-user';

export default async function OnboardingPage() {
  const result = await createUser();

  if (!result.success) {
    console.error('Failed to create user:', result.error);
    return;
  }

  console.log(result.data); // "User created" or "User already exists"
}

Client Component Example

'use client';

import { createUser } from '@/actions/create-user';
import { useState } from 'react';

export function OnboardingButton() {
  const [loading, setLoading] = useState(false);
  const [message, setMessage] = useState('');

  const handleCreateUser = async () => {
    setLoading(true);
    const result = await createUser();
    
    if (result.success) {
      setMessage(result.data);
    } else {
      setMessage(`Error: ${result.error}`);
    }
    
    setLoading(false);
  };

  return (
    <div>
      <button onClick={handleCreateUser} disabled={loading}>
        {loading ? 'Creating...' : 'Complete Setup'}
      </button>
      {message && <p>{message}</p>}
    </div>
  );
}

Source Code

Location: actions/create-user.ts:10

Build docs developers (and LLMs) love