> For the complete documentation index, see [llms.txt](https://developer.paddle.com/llms.txt).

# Create a subscription in trial

Get a step-by-step overview of creating a subscription with a free or paid trial — including creating a price with a trial period, offering it through Paddle Checkout, and managing the trial lifecycle.

---

[Trials](https://developer.paddle.com/concepts/subscriptions/trials.md) let customers try your product before they commit to paying. You can offer a **free trial**, where customers aren't charged during the trial period, or a **paid trial**, where customers pay a reduced amount for the trial period before the subscription renews at the full price.

This tutorial walks through creating a subscription with a trial, from creating a price with a trial period to managing the trial lifecycle. It works for both free and paid trials. Cardless trials are in early access, so they're not covered here yet.

{% callout type="note" %}
This tutorial covers trials that collect a payment method at signup. To let customers start a trial without entering payment details, see [Create a cardless trial](https://developer.paddle.com/build/trials/cardless-trials.md)
{% /callout %}

## What are we building?

We'll create a subscription plan with a trial period using [Paddle Checkout](https://developer.paddle.com/concepts/sell/self-serve-checkout.md). When a customer completes their purchase:

- For a **free trial**, they enter payment details but aren't charged until the trial ends.
- For a **paid trial**, they enter payment details, then they're charged the trial price right away and the base price when the trial ends.

In both cases, Paddle creates a subscription with the status `trialing`, then automatically renews it at the base price when the trial ends.

We'll learn how to:

- Create a price for a product that has a trial period, choosing whether it's free or paid
- Sell the trial using Paddle Checkout, which automatically creates a subscription
- Provision access when Paddle creates the subscription
- Manage and convert the trial throughout its lifecycle

## How it works

Whether a subscription has a trial is determined by whether the prices on the subscription have a trial period. A trial is an attribute of a [price entity](https://developer.paddle.com/api-reference/prices.md), set using the `trial_period` object.

There are three kinds of trials:

- **Free trials**  
  Customers enter payment details but aren't charged until the trial ends.
- **Paid trials**  
  Customers pay a reduced amount for the trial period, then the full price when the trial ends.
- **Cardless trials**  
  Customers start the trial without entering payment details. Cardless trials are in early access.

For a paid trial, the trial price and the recurring base price share the same `price_id`. You can set the trial period unit price using the `unit_price` field against the `trial_period` object.

### From checkout to renewal

This diagram shows how a trial is billed, from checkout through to the first renewal.

```mermaid
flowchart TD
    A[Customer completes checkout for a price with a trial] --> B{Trial has a unit price?}
    B -->|No, free trial| C[No charge<br>payment method stored]
    B -->|Yes, paid trial| D[Customer charged the trial price]
    C --> E[Subscription created<br><pre>status: trialing</pre>]
    D --> E
    E --> F[Trial period ends]
    F --> G[Paddle charges the base price<br><pre>status: active</pre>]
```

## Overview

Create and sell a trial in four steps:

1. [**Create a price with a trial period**](#create-a-price-with-a-trial-period)  
   Create a price for a product that has a trial period. Choose whether the trial is free or paid.
2. [**Pass the price to a checkout**](#pass-the-price-to-a-checkout)  
   Pass the price to Paddle Checkout. On completion, Paddle automatically creates a subscription.
3. [**Handle fulfillment**](#handle-fulfillment)  
   Provision access to your app and store the subscription when Paddle creates it.
4. [**Manage and convert the trial**](#manage-and-convert-the-trial)  
   Update, extend, or activate the trial, then let it convert to a paying subscription.

## Before you begin

- **Create a product**  
  Prices relate to products. [Create a product](https://developer.paddle.com/build/products/create-products-prices#create-a-product.md) to describe what you're selling, then keep its Paddle ID to relate a price to it.
- **Set up Paddle Checkout**  
  You'll collect payment details using Paddle Checkout. [Include and initialize Paddle.js](https://developer.paddle.com/paddle-js/about/include-paddlejs.md) and [set a default payment link](https://developer.paddle.com/build/transactions/default-payment-link.md).

## Create a price {% step=true %}

[Create a price](https://developer.paddle.com/build/products/create-products-prices.md) for your product that includes a `trial_period` object with an `interval` and `frequency`. Trials require a `billing_cycle`, so the price must be recurring.

To make the trial **free**, leave out the trial price.

To make the trial **paid**, add a `trial_period.unit_price` with the amount to charge for the trial period. When setting a paid trial price:

- The trial price currency must match the base price currency, otherwise Paddle returns a `trial_currency_mismatch` error.
- You can use unit price overrides to localize the trial price, but you must provide a matching trial price override for the same countries and currency as the base price overrides.

This example creates a monthly price with a 7-day paid trial that charges $1.00 for the trial, then $15.00 on renewal.

{% tabs sync="interaction-preference" %}
{% tab-item title="API" %}

{% api-example method="POST" path="/prices" href="/api-reference/prices/create-price" %}

```json
{
  "product_id": "pro_01k5c106wy997av8jmz1qfng2q",
  "description": "Monthly (per seat) with 7 day paid trial",
  "name": "Monthly (per seat)",
  "trial_period": {
    "interval": "day",
    "frequency": 7,
    "unit_price": {
      "amount": "100",
      "currency_code": "USD"
    }
  },
  "billing_cycle": {
    "interval": "month",
    "frequency": 1
  },
  "unit_price": {
    "amount": "1500",
    "currency_code": "USD"
  }
}
```

```json
{
  "data": {
    "id": "pri_01k5c14mgh9dc3wgk3vb23p0t7",
    "product_id": "pro_01k5c106wy997av8jmz1qfng2q",
    "type": "standard",
    "description": "Monthly (per seat) with 7 day paid trial",
    "name": "Monthly (per seat)",
    "billing_cycle": {
      "interval": "month",
      "frequency": 1
    },
    "trial_period": {
      "interval": "day",
      "frequency": 7,
      "requires_payment_method": true,
      "unit_price": {
        "amount": "100",
        "currency_code": "USD"
      },
      "unit_price_overrides": []
    },
    "tax_mode": "account_setting",
    "unit_price": {
      "amount": "1500",
      "currency_code": "USD"
    },
    "unit_price_overrides": [],
    "custom_data": null,
    "status": "active",
    "quantity": {
      "minimum": 1,
      "maximum": 100
    },
    "import_meta": null,
    "created_at": "2026-06-10T09:00:00.000000Z",
    "updated_at": "2026-06-10T09:00:00.000000Z"
  },
  "meta": {
    "request_id": "a1f4c2e0-8b3d-4f7a-9c21-6d0b5e9a3c14"
  }
}
```

{% /api-example %}

{% /tab-item %}
{% tab-item title="SDKs" %}

```ts {% highlightLines="14-21" collapse=true %}
import { Paddle, Environment } from '@paddle/paddle-node-sdk';

// Initialize the Paddle SDK with your API key and environment.
const paddle = new Paddle('YOUR_API_KEY', {
  environment: Environment.sandbox // or Environment.production
});

async function createPrice() {
  try {
    const newPrice = await paddle.prices.create({
      productId: 'pro_01k5c106wy997av8jmz1qfng2q',
      description: 'Monthly (per seat) with 7 day paid trial',
      name: 'Monthly (per seat)',
      trialPeriod: {
        interval: 'day',
        frequency: 7,
        unitPrice: {
          amount: '100',
          currencyCode: 'USD',
        },
      },
      billingCycle: {
        interval: 'month',
        frequency: 1,
      },
      unitPrice: {
        amount: '1500',
        currencyCode: 'USD',
      },
    });

    console.log('Successfully created price:', newPrice.id);
  } catch (error) {
    console.error('Error creating price:', error);
  }
}

createPrice();
```

{% /tab-item %}
{% /tabs %}

Extract the Paddle ID of the price you create — you'll need this to pass to a checkout in the next step.

## Pass the price to a checkout {% step=true %}

[Paddle Checkout](https://developer.paddle.com/concepts/sell/self-serve-checkout.md) is the simplest way to collect payment for a trial. When the checkout is completed, Paddle automatically creates a subscription for the items on the transaction.

Open a checkout by [passing items to `Paddle.Checkout.open()`](https://developer.paddle.com/build/checkout/pass-update-checkout-items.md), or build a [pricing page](https://developer.paddle.com/build/checkout/build-pricing-page.md) that opens a checkout for the price.

```javascript
Paddle.Checkout.open({
  items: [{ priceId: "pri_01k5c14mgh9dc3wgk3vb23p0t7", quantity: 1 }],
});
```

Paddle Checkout handles the trial workflow for you, presenting a compliant signup based on the customer's jurisdiction. For a paid trial, the checkout shows the trial price and length, and the customer is charged the trial price to complete checkout. For a free trial, the customer enters payment details but isn't charged.

### Display trial pricing in an inline checkout

Inline checkout lets you build branded checkout experiences that are fully integrated with your app. You're responsible for displaying the order summary using the data Paddle.js passes to your [`eventCallback`](https://developer.paddle.com/paddle-js/events.md).

To build a compliant inline checkout, you need to display the trial price and length, the recurring price and interval, and the order subtotal, tax, and total due today. You can use the following fields from the Paddle.js event data:

| Checkout field                                                   | Paddle.js event field                                            |
| ---------------------------------------------------------------- | ---------------------------------------------------------------- |
| Trial length (for example, a 7-day trial)                        | `data.items[].trial_period`: `interval` and `frequency`          |
| Recurring price and interval (for example, $192/month)           | `data.items[].recurring_totals` and `data.items[].billing_cycle` |
| Item line prices, using the non-trial price                      | `data.items[].recurring_totals`                                  |
| Order subtotal, tax, and total due today                         | `data.totals`                                                    |

Render each line item from its `recurring_totals` to show the ongoing price, and the order summary from `data.totals` to show what the customer pays now.

{% collapsible title="What good looks like" isOpen=false %}

It's important that customers know who they're buying from, what they're buying, and how much they're paying.

To build an inline checkout that's compliant and optimized for conversion, your implementation must include:

1. If recurring, how often it recurs and the total to pay on renewal. If a trial, how long the trial lasts.
2. A description of what's being purchased.
3. Transaction totals, including subtotal, total tax, and grand total. Be sure to include the currency too.
4. The full inline checkout frame, including the checkout footer that has information about Paddle, our terms of sale, and our privacy policy.
5. A link to your refund policy, if it differs from the Paddle.com standard refund policy.

{% /collapsible %}

## Handle fulfillment {% step=true %}

Paddle automatically creates a subscription with the status `trialing` once the checkout transaction is completed. Fulfillment for trials is the same as for other subscriptions:

1. Create a webhook endpoint and [create notification destinations](https://developer.paddle.com/webhooks/about/notification-destinations.md) for subscription and transaction events.
2. Listen for the [`subscription.created`](https://developer.paddle.com/webhooks/subscriptions/subscription-created.md) and [`transaction.completed`](https://developer.paddle.com/webhooks/transactions/transaction-completed.md) events.
3. Extract and store the `subscription_id`, then grant the appropriate level of access to your app.

For full details, see [Handle provisioning and fulfillment](https://developer.paddle.com/build/subscriptions/provision-access-webhooks.md).

### Determine the trial type

You might want to handle each trial type differently in your app. For example, you might want to surface the trial price for a paid trial or limit the features available for free trials. Check the `trial_period` on the subscription item's price to tell which type of trial a `trialing` subscription is on.

```mermaid
flowchart TD
    Start{Is <pre>status = trialing</pre>?}
    Start -->|No| NotTrial[Not a trial]
    Start -->|Yes| PM{Subscription item price <pre>requires_payment_method</pre>?}
    PM -->|false| Cardless[Cardless trial<br>always free]
    PM -->|true| Price{Subscription item price <pre>trial_period.</pre><pre>unit_price</pre> set?}
    Price -->|No| Free[Card-required free trial]
    Price -->|Yes| Paid[Card-required paid trial]
```

Check these fields against the `price` for each item in a [subscription entity](https://developer.paddle.com/api-reference/subscriptions.md):

| Field | Description |
| --- | --- |
| `status`           | `trialing` is used for all kinds of trial.                                                                           |
| `items[].price.trial_period` | `null` if the price has no trial period. |
| `items[].price.trial_period.requires_payment_method` | `true` for card-required trials, `false` for cardless trials. |
| `items[].price.trial_period.unit_price` | Set for paid trials, `null` for free trials. |

This gives you three trial types:

- **Card-required free trial**: `requires_payment_method` is `true` and `unit_price` is `null`.
- **Card-required paid trial**: `requires_payment_method` is `true` and `unit_price` is set.
- **Cardless trial**: `requires_payment_method` is `false`. Cardless trials are always free.

## Manage and convert the trial {% step=true %}

While a subscription is `trialing`, you can update items, extend the trial, or activate it early.

Since the subscription isn't on its full billing cycle yet, [proration](https://developer.paddle.com/concepts/subscriptions/proration.md) doesn't apply. Use `do_not_bill` as the `proration_billing_mode` when making changes.

{% card-group cols=2 %}
{% card title="Work with trials" icon="carbon:settings" url="/build/trials/update-trials" %}
Add or remove items, change quantities, and bill for one-time charges.
{% /card %}
{% card title="Extend or activate a trial" icon="carbon:time" url="/build/trials/extend-activate-change-date-trials" %}
Give customers more time, or cut the trial short to start billing.
{% /card %}
{% /card-group %}

When the trial period ends, Paddle charges the base price to the [payment method](https://developer.paddle.com/concepts/payment-methods.md) on file and transitions the subscription to `active`.