Skip to main content

Overview

The getUserSubscription function retrieves the currently authenticated user’s subscription information along with their user record. It returns both the subscription data (if one exists) and the user details.

Function Signature

export async function getUserSubscription(): ServerActionRes<UserSubscription>

type UserSubscription = {
  subscription: SelectSubscription | null;
  user: SelectUser;
}

Parameters

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

Return Value

success
boolean
required
Indicates whether the operation was successful
data
UserSubscription
An object containing both user and subscription data:
user
SelectUser
required
The user’s database record:
supabaseUserId
string
The Supabase authentication user ID
dodoCustomerId
string
The Dodo Payments customer ID
currentSubscriptionId
string | null
The ID of the current active subscription
createdAt
string
ISO timestamp when the user was created
updatedAt
string
ISO timestamp when the user was last updated
deletedAt
string | null
ISO timestamp when the user was deleted (soft delete)
subscription
SelectSubscription | null
The user’s current subscription, or null if no subscription exists:
subscriptionId
string
Unique subscription identifier
userId
string
Reference to the user’s Supabase ID
productId
string
The subscribed product ID
status
string
Subscription status (e.g., “active”, “cancelled”, “past_due”)
recurringPreTaxAmount
number
Recurring amount before tax
currency
string
Currency code (e.g., “USD”, “EUR”)
quantity
number
Number of units subscribed
nextBillingDate
string
ISO timestamp of the next billing date
previousBillingDate
string
ISO timestamp of the previous billing date
cancelAtNextBillingDate
boolean | null
Whether the subscription will cancel at the next billing date
cancelledAt
string | null
ISO timestamp when subscription was cancelled
And other subscription fields…
error
string
Error message if the operation failed:
  • “User not found” - No authenticated session
  • “User details not found” - User exists in Supabase but not in database

Implementation Details

The function:
  1. Retrieves the authenticated Supabase user via getUser()
  2. Queries the database for the user’s record using their Supabase ID
  3. If no subscription ID exists, returns user with subscription: null
  4. If subscription ID exists, queries for the subscription details
  5. Returns both user and subscription data together

Error Handling

  • Returns { success: false, error: "User not found" } if authentication fails
  • Returns { success: false, error: "User details not found" } if user record doesn’t exist in database
  • Returns subscription as null if user has no active subscription (not an error)

Usage Example

import { getUserSubscription } from '@/actions/get-user-subscription';

export default async function AccountPage() {
  const result = await getUserSubscription();

  if (!result.success) {
    return <div>Error: {result.error}</div>;
  }

  const { user, subscription } = result.data;

  return (
    <div>
      <h1>Account Details</h1>
      <p>Customer ID: {user.dodoCustomerId}</p>
      
      {subscription ? (
        <div>
          <h2>Active Subscription</h2>
          <p>Status: {subscription.status}</p>
          <p>Amount: {subscription.recurringPreTaxAmount} {subscription.currency}</p>
          <p>Next Billing: {new Date(subscription.nextBillingDate).toLocaleDateString()}</p>
          {subscription.cancelAtNextBillingDate && (
            <p className="text-red-600">Cancels on {new Date(subscription.nextBillingDate).toLocaleDateString()}</p>
          )}
        </div>
      ) : (
        <p>No active subscription</p>
      )}
    </div>
  );
}

Checking Subscription Status

import { getUserSubscription } from '@/actions/get-user-subscription';

export async function hasActiveSubscription(): Promise<boolean> {
  const result = await getUserSubscription();
  
  if (!result.success || !result.data.subscription) {
    return false;
  }
  
  return result.data.subscription.status === 'active';
}

Client Component Example

'use client';

import { getUserSubscription } from '@/actions/get-user-subscription';
import { useEffect, useState } from 'react';

export function SubscriptionStatus() {
  const [subscription, setSubscription] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    getUserSubscription().then(result => {
      if (result.success) {
        setSubscription(result.data.subscription);
      }
      setLoading(false);
    });
  }, []);

  if (loading) return <div>Loading...</div>;
  
  if (!subscription) {
    return <div>No active subscription. <a href="/pricing">View Plans</a></div>;
  }

  return (
    <div>
      <div>Status: {subscription.status}</div>
      <div>Next billing: {new Date(subscription.nextBillingDate).toLocaleDateString()}</div>
      {subscription.cancelAtNextBillingDate && (
        <div className="text-red-600">Subscription will cancel on next billing date</div>
      )}
    </div>
  );
}

Source Code

Location: actions/get-user-subscription.ts:19

Build docs developers (and LLMs) love