Skip to main content

Add Subscriptions

Reflow subscriptions are built on top of our Auth integration. Once a user has created an account and signed in, you can offer them a paid subscription for unlocking additional features in your app.

Reflow supports a lot of subscription features including:

  • Offering multiple plans with different permission levels
  • Monthly and yearly pricing for each plan
  • Stripe or Paddle payment processing
  • Free trials
  • One-time charges at the beginning of a subscription

This page will guide you through a sample subscription integration with the auth-next library. Visit the Subscription Docs for more information on how to configure subscription plans and pricing.

tip

For a comprehensive step-by-step guide, check out our article The Quickest Way to Add Subscriptions in Next.js

Add a Subscribe Button

Similarly to your auth sign-in process, subscriptions are handled entirely in a Reflow-hosted interface displayed in a popup dialog.

To show a payment screen for starting a subscription you just need to call the createSubscription function from a client component. Make sure the user is already signed in before doing this.

app/components/SubscribeButton.tsx
"use client";

import { createSubscription } from "@reflowhq/auth-next/client";

export default function SubscribeButton() {
return (
<button
onClick={() => {
createSubscription({
priceID: 123456,
onSuccess: () => console.log("Subscription success!"),
});
}}
>
Subscribe
</button>
);
}

The createSubscription method requires a priceID parameter that indicates which price the user should subscribe to. You can find the ID of your plan prices when editing them or from the Reflow API.

When the button is clicked, the user will see a pop-up window where they will need to enter their payment details. It will very slightly depending on whether you are using Stripe or Paddle for handling payments.

Subscriber-only Access

To restrict certain parts of your app only to paying user you need to gate the premium content on the server side.

This can be done by calling the auth.subscription() method. This will return a Reflow Subscription object, which contains the subscription plan of the current user.

Depending on this you can decide whether to grant or restrict access. Naturally, this means that you can offer multiple plans and decide what restrictions to apply for each.

app/page.tsx
import getAuth from "@/auth";
import SignInButton from "./components/SignInButton";
import SignOutButton from "./components/SignOutButton";
import SubscribeButton from "./components/SubscribeButton";

export default async function Page() {
const auth = getAuth();
const user = await auth.user();
const sub = await auth.subscription();

if (user && sub) {
return (
<>
<p>Hello, {user.name}.</p>
<p>
You are subscribed to the {sub.plan.name} plan for{" "}
{sub.price.price_formatted} per {sub.price.billing_period}
</p>
<SignOutButton />
</>
);
} else if (user) {
return (
<>
<p>Hello, {user.name}. You are not yet subscribed.</p>
<SubscribeButton />
</>
);
}

return <SignInButton />;
}

The Subscription object contains feature flags that you define in your Plan creation screen in Reflow. If you build your Next app around them, you can use these flags to create new plans with unique limits, or override the features/limits for a specific subscriber from Reflow's project management UI.

User Subscription Updates

Once a user has a subscription going, you need to provide them with ways to:

  • Update their payment method, e.g. to add a new credit card after previous one expires
  • Cancel the subscription
  • Switch to another plan

Luckily, all of these actions and the user interfaces required for them can be handled automatically by the Reflow Auth Next library.

To show a dialog for managing subscriptions, call the modifySubscription method from a client component. This is very similar to the createSubscription example from earlier.

app/components/UpdateSubscriptionButton.tsx
"use client";

import { modifySubscription } from "@reflowhq/auth-next/client";

export default function UpdateSubscriptionButton() {
return <button onClick={modifySubscription}>Update Subscription</button>;
}