Paddle Billing Payments Full Stack TypeScript App

Author Sandro Maglione

Sandro Maglione

Contact me

Payments is one of those features that you will find in most apps. Paddle acts as a merchant of record, handling your payments, tax and compliance.

This project template implements payments with Paddle on both client and server:

The template provides a full stack implementation of a working payments system. It includes:

Project structure

The repository of the project is a monorepo initialized using Turborepo. The same project contains both client and server inside the apps folder.

Client

The client is built using React with the latest version of React Router v7 as framework.

The client also uses Effect to organize and execute services (Paddle).

The client state is managed using XState. Using a state machine the client keeps track of the current step during the checkout process, keeping the state in sync with Paddle.

Styles are implemented using the latest version of Tailwind CSS v4. Components are based on React Aria.

This is the final package.json file of the client:

package.json
{
  "name": "@app/client",
  "version": "0.0.0",
  "private": true,
  "sideEffects": false,
  "type": "module",
  "scripts": {
    "dev": "react-router dev",
    "build": "react-router build",
    "start": "react-router-serve ./build/server/index.js",
    "typecheck": "react-router typegen && tsc"
  },
  "dependencies": {
    "@effect/schema": "^0.74.1",
    "@paddle/paddle-js": "^1.2.3",
    "@react-router/node": "7.0.0-pre.0",
    "@react-router/serve": "7.0.0-pre.0",
    "@tailwindcss/vite": "^4.0.0-alpha.25",
    "@xstate/react": "^4.1.3",
    "clsx": "^2.1.1",
    "effect": "^3.8.4",
    "isbot": "^5.1.17",
    "react": "^18.3.1",
    "react-aria-components": "^1.4.0",
    "react-dom": "^18.3.1",
    "react-router": "7.0.0-pre.0",
    "tailwind-merge": "^2.5.3",
    "xstate": "^5.18.2"
  },
  "devDependencies": {
    "@react-router/dev": "7.0.0-pre.0",
    "@types/react": "^18.3.9",
    "@types/react-dom": "^18.3.0",
    "tailwindcss": "^4.0.0-alpha.25",
    "vite": "^5.4.8",
    "vite-tsconfig-paths": "^5.0.1"
  },
  "engines": {
    "node": ">=20.0.0"
  }
}

Server

The server API is built from scratch using Effect. The project is a normal NodeJs app that uses node:http as server.

The API is based on @effect/platform, specifically using the following modules:

  • HttpApi
  • HttpApiBuilder
  • HttpApiEndpoint
  • HttpApiGroup
  • HttpMiddleware
  • HttpServer

Other dependencies include dotenv (to load environment variables) and tsx (to execute the server code).

This is the final package.json file of the server:

package.json
{
  "name": "@app/server",
  "version": "0.0.0",
  "author": "Typeonce",
  "license": "MIT",
  "scripts": {
    "dev": "tsx src/main.ts",
    "typecheck": "tsc"
  },
  "dependencies": {
    "@effect/platform": "^0.66.2",
    "@effect/platform-node": "^0.61.3",
    "@effect/schema": "^0.74.1",
    "@paddle/paddle-node-sdk": "^1.7.0",
    "dotenv": "^16.4.5",
    "effect": "^3.8.4"
  },
  "devDependencies": {
    "@types/node": "^22.7.4",
    "tsx": "^4.19.1"
  }
}

Course content

Instead of explaining step by step how to implement the project, this course focuses on the overall project structure and code architecture.

For both client and server, the course explains the pro and cons of each technology and the role and benefits of each dependency.

It then goes more into the details of client and server, showing how the code is organized and discussing some implementation details for the most important files.

The course aims to provide an overview of how to approach the implementation of a full stack project in the specific example of payments with Paddle.