Back to Docs

Checkout Links

Create and manage shareable payment links for your business.

How It Works

Create a link, share it, receive payments

Create LinkShare URLCustomer PaysFunds Received
1

What are Checkout Links?


Checkout links are shareable payment URLs that allow customers to pay you directly without needing to set up a complicated checkout flow.

**Key Benefits:**
- Share a single URL with customers
- No code required for basic payments
- Customizable plan names and descriptions
- Support for recurring and one-time payments
- Track payments in your dashboard
2

Creating a Checkout Link


Use the `createCheckoutLink` server action to create a new payment link.

**Required Parameters:**
```typescript
import { createCheckoutLink } from "@/lib/checkout-links";

type CreateCheckoutLinkInput = {
  planName: string;      // Display name (e.g., "Premium Plan")
  plan: string;          // Internal ID (e.g., "premium")
  description: string;   // Customer-facing description
  price: string;         // Amount in USD (e.g., "50.00")
  billing: "recurring" | "one-time";
  initialFee: string;    // Optional upfront charge
  trial: string;         // Optional trial days
  stock: string;         // Optional inventory limit
};

await createCheckoutLink("biz_your_business_id", {
  planName: "Premium Plan",
  plan: "premium",
  description: "Full access to all features",
  price: "50.00",
  billing: "recurring",
  initialFee: "10.00",
  trial: "7",
  stock: "100",
});
```

**Response:**
```typescript
// Success
{ ok: true }

// Error
{ ok: false; error: "Plan name is required." }
```
3

Checkout Link Properties


Each checkout link has the following properties:

```typescript
import { checkoutLinks } from "@/db/schema";

export const checkoutLinks = pgTable("checkout_links", {
  id: uuid("id").primaryKey().defaultRandom(),
  businessId: uuid("business_id")
    .notNull()
    .references(() => businesses.id, { onDelete: "cascade" }),
  planId: text("plan_id").notNull().unique(),
  planName: text("plan_name").notNull(),
  plan: text("plan"),
  description: text("description"),
  price: numeric("price", { precision: 20, scale: 6 }).notNull(),
  currency: text("currency").notNull().default("USDC"),
  network: text("network").notNull().default("base-sepolia"),
  billing: billingEnum("billing").notNull().default("recurring"),
  initialFee: numeric("initial_fee", { precision: 20, scale: 6 }),
  trialDays: integer("trial_days"),
  stock: integer("stock"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at").notNull().defaultNow(),
});
```

**Field Descriptions:**

| Field | Type | Description |
|-------|------|-------------|
| `id` | UUID | Unique identifier |
| `businessId` | UUID | Owner business |
| `planId` | string | Unique plan identifier (plan_...) |
| `planName` | string | Display name shown to customers |
| `plan` | string | Internal plan identifier |
| `description` | string | Detailed description |
| `price` | numeric | Price in USD |
| `currency` | string | Payment currency (default: USDC) |
| `network` | string | Blockchain network |
| `billing` | enum | "recurring" or "one-time" |
| `initialFee` | numeric | Optional upfront charge |
| `trialDays` | integer | Optional free trial period |
| `stock` | integer | Optional inventory limit |
4

Retrieving Checkout Links


Fetch all checkout links for your business:

```typescript
import { getCheckoutLinks } from "@/lib/checkout-links";

// Get all links for a business
const links = await getCheckoutLinks("biz_your_business_id");

// Example response
links.forEach(link => {
  console.log(`${link.planName}: ${link.price} USD`);
});
```

**Response Structure:**
```typescript
CheckoutLink[] {
  id: string;
  businessId: string;
  planId: string;
  planName: string;
  plan: string | null;
  description: string | null;
  price: string;
  currency: string;
  network: string;
  billing: "recurring" | "one-time";
  initialFee: string | null;
  trialDays: number | null;
  stock: number | null;
  createdAt: Date;
  updatedAt: Date;
}
```
5

Deleting a Checkout Link


Remove a checkout link when it's no longer needed:

```typescript
import { deleteCheckoutLink } from "@/lib/checkout-links";

await deleteCheckoutLink("biz_your_business_id", "plan_abc123");

// Response
// { ok: true } | { ok: false; error: "..." }
```

**Important:** Deleting a link prevents new payments but doesn't affect existing transactions.

Code Examples

One-Time Payment

// One-time payment for a service
await createCheckoutLink("biz_abc123", {
  planName: "Website Redesign",
  plan: "web-design",
  description: "Full website redesign with 5 pages",
  price: "500.00",
  billing: "one-time",
  initialFee: "",
  trial: "",
  stock: "",
});

Recurring Subscription

// Monthly subscription with trial
await createCheckoutLink("biz_abc123", {
  planName: "Premium Monthly",
  plan: "premium-monthly",
  description: "Monthly premium subscription",
  price: "29.00",
  billing: "recurring",
  initialFee: "10.00",
  trial: "7",
  stock: "100",
});

Best Practices

  • Use Descriptive Plan Names

    Make plan names clear and descriptive so customers understand what they're paying for.

  • Set Trial Periods

    Offer trial periods to reduce friction and increase conversion rates.

  • Include Detailed Descriptions

    Provide comprehensive descriptions to reduce customer questions and support requests.

Payment Buttons