Back to roadmaps lemonsqueezy Course

Linking the Customer Billing Portal

Instead of building pages inside your application to let users update their credit cards or download PDF invoices, redirect them to the Lemon Squeezy Customer Portal.


1. What is the Customer Portal?

The Customer Portal is a secure dashboard hosted by Lemon Squeezy on behalf of your brand store. Here, your subscribers can:

  • View invoice receipt history.
  • Update payment card details or billing address.
  • Downgrade, upgrade, or cancel active subscriptions.

2. Retrieving Portal Links via the SDK

To generate a custom portal link for a user, query their customer record using the SDK:

import { lemonSqueezySetup, getCustomer } from "@lemonsqueezy/lemonsqueezy.js";

lemonSqueezySetup({
  apiKey: process.env.LEMONSQUEEZY_API_KEY as string,
});

export async function fetchCustomerBillingUrl(customerId: string) {
  try {
    const response = await getCustomer(customerId);

    if (response.error) {
      throw new Error(response.error.message);
    }

    // Retrieve the customer billing portal link URL
    const portalUrl = response.data?.data.attributes.urls.customer_portal;
    return portalUrl;
  } catch (err: any) {
    console.error("Failed to query portal address:", err.message);
    return null;
  }
}

3. Integrating in the Frontend Dashboard

Create a simple link on your settings page:

// app/dashboard/settings/page.tsx
import React from "react";
import { fetchCustomerBillingUrl } from "../../../services/lemonCheckout";

export default async function SettingsPage() {
  const customerId = "cust_01hsabc..."; // Retrieve customer ID from user profile
  const portalUrl = await fetchCustomerBillingUrl(customerId);

  return (
    <div className="p-8 max-w-lg">
      <h2 className="text-xl font-bold">Billing Settings</h2>
      <p className="text-gray-500 text-sm mt-1">Manage payment methods, view invoices, or cancel plans.</p>

      {portalUrl ? (
        <a
          href={portalUrl}
          target="_blank"
          rel="noopener noreferrer"
          className="inline-block bg-gray-900 text-white font-semibold px-4 py-2 rounded-lg text-sm mt-6"
        >
          Open Customer Portal ↗
        </a>
      ) : (
        <p className="text-red-500 text-xs mt-6">Billing portal unavailable. Contact support.</p>
      )}
    </div>
  );
}
Published on Last updated: