4. What’s under the hood?

🏡 Home 👈 Prev 👉 Next

Template structure

Notion-Paywall is a plug-n-play serverless Next.js boilerplate. It consists of two main parts.
  1. The frontend
      • containing the paywalled Notion page renderer
      • the checkout call-to-action button
      • a simple, password-less email-signin form
      • a thank-you page, shown after a successful purchase
      • and, of course, a dark-mode toggle.
  1. The backend (API routes):
      • /api/checkout_sessions to generate Stripe Checkout links
      • /api/webhooks to listen to Stripe charge_succeeded events
      • /api/upsert_user to store newly created customers
      • /api/send_email to send “welcome” and “sign-in” emails
      • /api/notify_slack to send bot messages to Slack

Required plumbing

Notion token

Notion-Paywall uses the notion-client package. It uses the token_v2 cookie to talk to Notion’s backend and request your Notion content. To retrieve your personal token, you’ll need to sign into Notion.com via the browser — not the Mac/Windows/phone app!
Chrome dev tools screenshot:
notion image


You’ll need a database connection to store your customers’ emails and their sign-in sessions. Notion-Paywall uses Prisma.io to abstract all user auth database operations away. It ships with a schema.prisma that connects to MongoDB but you can easily opt for MySQL, Postgres, and other vendors. If you’re new to this, setting up a MongoDB cluster is super easy.
The default Notion-Paywall schema.prisma config file looks like this:
generator client {
    provider        = "prisma-client-js"
    previewFeatures = ["mongoDb"]

datasource db {
    provider = "mongodb"
    url      = env("MONGODB_URL")

model VerificationToken { ... }
model Session { ... }
model Account { ... }
model User { ... }

SMTP-capable email provider

Notion-Paywall sends emails through the nodemailer package so you’ll need an SMTP transporter. All major email players support this…
For example, your Mailgun credentials would look like this:

Stripe API keys + webhook secret

Notion-Paywall talks to your Stripe account via the publishable key from the frontend and the secret key from the backend. Stripe, in turns, talks to Notion-Paywall via webhooks which need to be verified to prevent malicious activity.
Choosing which webhook events to listen to:
notion image

Optional plumbing


If you’d like to be notified about new purchases in Slack, you’ll need:
  • and the channel ID to post the automatic (bot) messages to.
After setup, a the bot message will look like this:
notion image

😱 Umm yeah no… I don’t speak tech. What do I do?

🏡 Home 👈 Prev 👉 Next

Already purchased? Sign in here.