Implementing Subscription Management with Next.js and Clerk Billing

Clerk Billingを使ったサブスクリプション管理をNext.jsで実装する方法を解説。環境構築から料金プラン設定、認証連携まで、Clerkの新機能を活用したサブスク機能の導入手順を詳しく紹介します。

広告ここから
広告ここまで

目次

    Clerk has recently released Clerk Billing, a new feature that simplifies subscription management for web applications. This article will guide you through implementing Clerk Billing in a Next.js application and explain its basic usage.

    Setting Up the Environment

    Let’s start by creating a new Next.js application:

    npx create-next-app@latest nextjs-clerk-billing-app
    

    For this tutorial, we’ll use the default settings. Just keep pressing Enter when prompted:

    ✓ Would you like to use TypeScript? … No / Yes
    ✓ Would you like to use ESLint? … No / Yes
    ✓ Would you like to use Tailwind CSS? … No / Yes
    ✓ Would you like your code inside a src/ directory? … No / Yes
    ✓ Would you like to use App Router? (recommended) … No / Yes
    ✓ Would you like to use Turbopack for next dev? … No / Yes
    ✓ Would you like to customize the import alias (@/* by default)? … No / Yes
    

    Setting Up the Clerk SDK

    After creating your application, install the Clerk SDK. You can follow the instructions in the Clerk dashboard for guidance:

    npm install @clerk/nextjs
    

    Setting Environment Variables

    Create a .env file in your project root and set up your Clerk API keys. You can copy and paste this data from the tutorial in the dashboard:

    NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxx
    CLERK_SECRET_KEY=sk_test_xxx
    

    Configuring Middleware

    Next, create a src/middleware.ts file to set up Clerk’s middleware, which will provide the foundation for user authentication:

    import { clerkMiddleware } from '@clerk/nextjs/server';
    export default clerkMiddleware();
    export const config = {
      matcher: [
        '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',  
        '/(api|trpc)(.*)',
      ],
    };
    

    Setting Up Clerk Billing

    Clerk Billing needs to be enabled from the dashboard. You’ll notice a new [Subscription (beta)] tab has been added. Click the [Get Started] button to proceed.

    To use Clerk Billing, you’ll need to register for a plan and migrate to Session JWT v2. For JWT v2, you can follow the instructions in the Changelog.

    Setting Up Pricing Data

    Clerk Billing allows you to configure subscription plan information through the Clerk dashboard.

    There’s a Free plan already available. Click [Add plan] to create a new plan, which you can delete later if needed.

    Set up the plan name, slug, and description. When you enter the plan name, Clerk will automatically generate a slug using lowercase letters and underscores (_).

    Next, configure the pricing. Currently, it appears that only USD subscriptions are supported. For the [Annual Discount], enter the monthly equivalent price after discount rather than the discount amount itself. For example, if you want to set a $4.98/month plan with an annual price of $48, enter 4 (because $48 ÷ 12 = $4). Additionally, if you turn off “Publicly available,” the plan won’t appear in Clerk-provided components.

    While creating the pricing, you should also create a feature list.

    Set the feature name and slug. The slug will be used in Clerk components.

    After saving the features, save the entire plan to complete the addition.

    Enabling Clerk Billing

    Once all the preliminary setup is complete, the [Enable Billing] button will appear on your dashboard. Click it to activate Clerk Billing.

    Activation is now complete. It looks like you can also bring your own Stripe account if desired.

    Basic Usage of Clerk Billing

    Displaying the Pricing Table

    Displaying a pricing table on your homepage is surprisingly simple. Just use the PricingTable component:

    import { PricingTable } from "@clerk/nextjs";
    import Image from "next/image";
    
    export default async function Home() {
      return (
        <main>
          <PricingTable />
        </main>
      );
    }
    

    If you’ve registered two plans, they will be displayed like this. The features you registered will appear as a feature list in the pricing table.

    Note that Clerk login is required to process payments. Therefore, it’s advisable to place the PricingTable component on a page that is displayed when the user is logged in.

    The payment form appears as a floating panel.

    Once payment is complete, Clerk components like PricingTable will immediately reflect the changes.

    Access Control

    To control access to specific features based on subscriptions, the Protect component is useful:

    import { PricingTable, Protect } from "@clerk/nextjs";
    import Image from "next/image";
    
    export default async function Home() {
      return (
        <main>
          <Protect
            feature="dashboard_access"
            fallback={<p>Sorry, you don't have dashboard Access.</p>}
          >
            <div>
              <h1>Protected</h1>
            </div>
          </Protect>
        </main>
      );
    }
    

    With this configuration, only people who have subscribed to a plan with the specified feature slug will see the child elements.

    Server-Side Control

    You can implement feature restrictions not only on the client side but also in server-side processing such as APIs and SSR. This can also be used for API control, so the distinction between this and Protect may be a subject for further research.

    import { PricingTable, Protect } from "@clerk/nextjs";
    import { auth } from "@clerk/nextjs/server";
    import Image from "next/image";
    
    export default async function Home() {
      const { has } = await auth()
      const canAccessDashboard = has({ feature: "dashboard_access" })
      
      if (!canAccessDashboard) {
        return (
          <main>
            <p>Sorry, you don't have dashboard Access.</p>
          </main>
        )
      }
      
      return (
        <main>
          <PricingTable />
          <Protect
            feature="dashboard_access"
            fallback={<p>Sorry, you don't have dashboard Access.</p>}
          >
            <div>
              <h1>Protected</h1>
            </div>
          </Protect>
        </main>
      );
    }
    

    Pricing

    When using Clerk Billing, an additional fee of 0.7% is charged on top of the Stripe processing fee.

    https://clerk.com/billing

    This additional fee applies only in production environments, but the benefit of significantly reduced implementation and maintenance effort makes it cost-effective in many cases.

    Conclusion

    By implementing Clerk Billing, you can easily display pricing tables and control access based on subscriptions. Since feature restrictions can be applied on both the client and server sides, flexible implementation is possible. Considering the effort required for implementation and operational costs, it’s well worth the additional fee. This should bring significant benefits, especially for small teams and individual developers, by saving development time.

    広告ここから
    広告ここまで

    Random posts

    Home
    Search
    Bookmark