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

# Create a cardless trial

Get a step-by-step overview of how to create a cardless trial — including creating prices, creating a transaction, and collecting for payment.

---

[Cardless trials](https://developer.paddle.com/concepts/subscriptions/trials.md) let customers try your app before they commit to paying. Unlike card-required trials, they don't require a credit card to sign up, making it easier for customers to try your product.

{% callout type="default" %}
Access to Cardless trials is limited to users who are part of our early access program. If you're interested in joining the program, review this guide then [fill out the form](https://developer.paddle.com/changelog/2025/cardless-trials-developer-preview.md) to apply. We'll reach out when space is available if you meet the program requirements.
{% /callout %}

## What are we building?

In this tutorial, we'll create a subscription that doesn't require a payment method when signing up. We'll then add a payment method to the subscription, so that it's ready to transition to paying.

We'll learn how to:

- Create a price for an item that has a trial period that doesn't require a payment method
- Create a transaction using the API for a customer, which automatically creates a subscription.
- Build a payment workflow using the API and Paddle.js, so customers can transition to paying.

You can view the demo app on GitHub to see how a basic cardless trial implementation works. It includes signup, cardless trial detection, and payment collection.

[Get sample code on GitHub to see how to build a cardless trial implementation.](https://github.com/PaddleHQ/paddle-sample-cardless-trials)

## How it works

Cardless trials work in a similar way to [card-required trials](https://developer.paddle.com/build/subscriptions/update-trials.md), except that they can only be created using the API — not Paddle.js. To create a cardless trial, [create a transaction](https://developer.paddle.com/build/transactions/create-transaction.md) using the API. Because no payment is required, the transaction is automatically completed and Paddle automatically creates a subscription for the customer.

A core part of the cardless trial lifecycle is collecting payment details from the customer. You should email customers with details about their signup and encourage them to convert throughout their trial period. To build [a payment workflow](https://developer.paddle.com/build/subscriptions/update-payment-details.md), you can use the API and Paddle.js.

If customers don't enter payment details before the trial ends, Paddle automatically cancels the subscription.

```mermaid
sequenceDiagram
    participant PC as Paddle.js
    participant Cust as Customer/Frontend
    participant YS as Your Server
    participant PA as Paddle API
    participant PW as Paddle Webhooks
    Note over PC,PW: Customer signup
    Cust->>YS: Sign up for trial
    YS->>PA: POST /transactions<br/>(status: billed)
    PA->>YS: Transaction created (status: paid)
    Note over PC,PW: Fulfillment
    PA<<->>PW: transaction.completed webhook
    PW->>YS: Subscription ID and details
    YS->>YS: Store subscription, grant access
    YS->>Cust: Welcome email and app access
    Note over PC,PW: Collect payment method (during trial)
    Cust->>YS: Click "Add payment method"
    YS->>PA: GET /subscriptions/{id}/update-payment-method-transaction
    PA->>YS: Extract transaction ID
    YS->>PC: Pass transaction ID to Paddle.Checkout.open()
    PC->>Cust: Show checkout
    Cust->>PC: Enter payment details
    PC->>PA: Payment method stored securely
    PA<<->>PW: subscription.updated webhook
    PW->>YS: Payment method added
    Note over PC,PW: End of trial
    alt No payment method
        PA<<->>PW: subscription.paused/canceled webhook
        PW->>YS: Subscription paused/canceled
        YS->>Cust: Trial expired email
    else Payment method on file
        PA<<->>PW: subscription.activated webhook
        PW->>YS: Subscription now active
        PA->>Cust: First payment charged
    end
```

## Overview

Create a cardless trial in five steps:

1. [**Create a price with a cardless trial period**](#create-price)  
   Create a price for a product that has a cardless trial period. When added to a subscription, the customer doesn't need to enter a payment method when signing up.
2. [**Create a transaction for a customer**](#create-transaction)  
   Use the Paddle API to create a transaction for a customer, which automatically creates a subscription on completion.
3. [**Handle fulfillment**](#handle-fulfillment)  
   Create a record for a cardless trial in your database, provision access to your app, and email the customer with details about their signup.
4. [**Incentivize customers to convert**](#incentivize-conversion) {% badge label="Optional" variant="outline" /%}  
   Incentivize customers to convert by emailing them throughout their trial period.
5. [**Handle non-converting trials**](#reactivate-trials) {% badge label="Optional" variant="outline" /%}  
   Handle non-converting trials by giving customers a way to reactivate their subscription.

## Before you begin

- **Build a page that includes Paddle.js**  
  You need to use Paddle.js to collect a payment method from customers so they can convert to paying. [Include and initialize Paddle.js](https://developer.paddle.com/paddlejs/include-paddlejs.md) on a page in your app or website.
- **Set your default payment link**  
  Set a payment link under **Paddle > Checkout > Checkout settings > Default payment link**, then get it approved if you're working with the live environment.
- **Use one-page checkout**  
  You can only present customers with a workflow to enter payment details for a cardless trial using one-page checkout. Multi-step checkouts aren't supported.

{% callout type="info" %}
We recommend starting the domain approval early in your integration process, so your domains are approved for when you're ready to go-live.
{% /callout %}

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

### Model your pricing

In Paddle, [a complete product](https://developer.paddle.com/build/products/create-products-prices.md) is made up of a product and a price. Whether a subscription has a trial period is determined by whether the prices on the subscription have a trial period.

Prices can have [two kinds of trial periods](https://developer.paddle.com/concepts/subscriptions/trials.md):

- **Card-required trials**  
  Customers must enter payment details at signup, but aren't charged until the trial ends.
- **Cardless trials**  
  Customers can sign up for a subscription without entering their payment details.

For this tutorial, we're going to create a price for a product that has a cardless trial.

### Create products and prices

{% callout type="info" %}
**Dashboard support is coming soon.** While in developer preview, you can only create or update prices with a cardless trial period using the API.
{% /callout %}

You can [create products and prices](https://developer.paddle.com/build/products/create-products-prices.md) using the Paddle dashboard or API, but you can only set a cardless trial period using the API while in developer preview.

We recommend creating a new price for cardless trials, rather than updating an existing price. This makes it easier for you to compare how cardless trials perform against card-required trials or no-trial prices over time.

#### Get or create a product

Prices relate to products. To create a price, you'll need to get the Paddle ID of an existing product to relate it to, or create a new product:

- **Get an existing product**
  Send a `GET` request to the [`/products` endpoint](https://developer.paddle.com/api-reference/products/list-products.md) to get a list of all products. Extract the Paddle ID of the product you want to relate the price to.
- **Create a new product**
  Send a `POST` request to the [`/products` endpoint](https://developer.paddle.com/api-reference/products/create-product.md) to create a new product. Extract the Paddle ID of the product you create.

#### Create a price with a cardless trial period

Build a request [that includes information about your new price](https://developer.paddle.com/api-reference/prices/create-price.md), then send a `POST` request to the `/prices` endpoint with the payload you built.

When creating a price, you must include the `trial_period` object with `requires_payment_method` set to `false` to make it a cardless trial.

{% 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/seat with cardless trial",
  "name": "Monthly (per seat)",
  "trial_period": {
    "requires_payment_method": false,
    "interval": "day",
    "frequency": 30
  },
  "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/seat with cardless trial",
    "name": "Monthly (per seat)",
    "billing_cycle": {
      "interval": "month",
      "frequency": 1
    },
    "trial_period": {
      "interval": "day",
      "requires_payment_method": false,
      "frequency": 30
    },
    "tax_mode": "external",
    "unit_price": {
      "amount": "3000",
      "currency_code": "USD"
    },
    "unit_price_overrides": [],
    "custom_data": null,
    "status": "active",
    "quantity": {
      "minimum": 1,
      "maximum": 100
    },
    "import_meta": null,
    "created_at": "2025-09-17T14:26:59.729668Z",
    "updated_at": "2025-10-08T13:13:00.258616Z"
  },
  "meta": {
    "request_id": "c57fc900-8c61-47bf-92c6-721647450fa4"
  }
}
```

{% /api-example %}

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

```ts {% highlightLines="14-18" 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/seat with cardless trial',
      name: 'Monthly (per seat)',
      trialPeriod: {
        requiresPaymentMethod: false,
        interval: 'day',
        frequency: 30,
      },
      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 create a transaction in the next step.

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

[Transactions](https://developer.paddle.com/api-reference/transactions/overview.md) are the central billing entity in Paddle. Paddle automatically creates a transaction when a customer opens a checkout, when a subscription renews, and for other subscription lifecycle events.

[Subscriptions](https://developer.paddle.com/api-reference/subscriptions/overview.md) are automatically created when a transaction is completed. In a card-required workflow, when the customer completes their purchase using [Paddle Checkout](https://developer.paddle.com/concepts/sell/self-serve-checkout.md), the related transaction is automatically completed. At this point, Paddle automatically creates a subscription for the items on the transaction.

Cardless trials work in a similar way in that Paddle automatically creates a subscription for items on the transaction on completion. However, Paddle Checkout doesn't support cardless trials, so you must [create a transaction](https://developer.paddle.com/build/transactions/create-transaction.md) manually using the API. Because there's no payment required, the transaction is automatically completed once it's billed.

```mermaid
flowchart TD
    subgraph CardRequired["Card-required trial"]
        CR1[Customer opens checkout] --> CR2[Paddle.js creates transaction]
        CR2 --> CR3[Paddle.js creates or updates<br/>customer entities]
        CR3 --> CR4[Customer completes checkout]
        CR4 --> CR5[Payment captured, so<br>transaction completed]
    end
    
    subgraph Cardless["Cardless trial"]
        CL1[Customer lands on your<br>signup page] --> CL2[You create or update<br/>customer entities]
        CL2 --> CL3[You create transaction<br/>via API<br>status:billed]
        CL3 --> CL4[No payment required, so<br>transaction completed]
    end
    
    CR5 --> SUB[✅ Subscription automatically created]
    CL4 --> SUB
    
    style CR5 fill:#fff3cd
    style CL4 fill:#fff3cd
    style SUB fill:#d4edda
    style CR2 fill:#e3f2fd
    style CL3 fill:#e3f2fd
```

### Capture customer details

Transactions require a customer and address to say who the transaction is for, what currency they should be billed in, and how tax is calculated.

If users are signed in already, you can include the Paddle ID for the customer, address, and business of the signed in user in your request. If they're not signed in, you should create a new customer and address, and optionally a business:

1. **Create a customer**
   [Customers](https://developer.paddle.com/api-reference/customers/overview.md) hold information about the people and businesses that make purchases. Send a `POST` request to the [`/customers` endpoint](https://developer.paddle.com/api-reference/customers/create-customer.md) to create a new customer. Extract the Paddle ID of the customer you create.
2. **Create an address**
   [Addresses](https://developer.paddle.com/api-reference/addresses/overview.md) hold billing address information for customers. Send a `POST` request to the [`/customers/{customer_id}/addresses` endpoint](https://developer.paddle.com/api-reference/addresses/create-address.md) to create a new address for a customer, passing the `customer_id` you extracted previously. Extract the Paddle ID for the address you create.
3. **Create a business** {% badge label="Optional" variant="outline" /%}
   [Businesses](https://developer.paddle.com/api-reference/businesses/overview.md) entities hold information about customer businesses. Send a `POST` request to the [`/customers/{customer_id}/businesses` endpoint](https://developer.paddle.com/api-reference/businesses/create-business.md) to create a new business for a customer, passing the `customer_id` you extracted previously. Extract the Paddle ID for the business you create.

If you're building a signup workflow, we recommend using the [`Paddle.TransactionPreview()`](https://developer.paddle.com/paddlejs/methods/paddle-transactionpreview.md) method (client side) or [preview a transaction operation](https://developer.paddle.com/api-reference/transactions/preview-transaction.md) (server side) to present localized prices to your customer.

{% callout type="warning" %}
To prevent free trial abuse, consider [blocking known disposable email address domains](https://github.com/disposable-email-domains/disposable-email-domains) or implementing a CAPTCHA using a service like [reCAPTCHA](https://developers.google.com/recaptcha) or [Cloudflare Turnstile](https://developers.cloudflare.com/turnstile).
{% /callout %}

### Create a transaction

Once you've captured the customer and address information, you can [create a transaction](https://developer.paddle.com/build/transactions/create-transaction.md) by calling the Paddle API.

Build a request that includes the customer ID, address ID, business ID (optional), and an array of objects for each item. Items should be prices with trial periods where `requires_payment_method: false`.

Include the `status` field with the value `billed` to say that the transaction is finalized. Paddle automatically completes the transaction once it's billed, creating a subscription for you.

{% callout type="info" %}
If you don't want to automatically complete the transaction, you can omit the `status` field. Paddle creates a `ready` transaction. Update a transaction to `billed` using the API to complete it.
{% /callout %}

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

{% api-example method="POST" path="/transactions" href="/api-reference/transactions/create-transaction" %}

```json
{
  "items": [
    {
      "price_id": "pri_01k5c14mgh9dc3wgk3vb23p0t7",
      "quantity": 10
    }
  ],
  "customer_id": "ctm_01hx93hx7d5fj4f0ah1x4t22yq",
  "address_id": "add_01hyjbr14xazf3hhgz79ysp6hj",
  "currency_code": "USD",
  "collection_mode": "automatic",
  "status": "billed"
}
```

```json
{
  "data": {
    "id": "txn_01k71zeadwbrvevb8czprm2r6c",
    "status": "paid",
    "customer_id": "ctm_01hx93hx7d5fj4f0ah1x4t22yq",
    "address_id": "add_01hyjbr14xazf3hhgz79ysp6hj",
    "business_id": null,
    "custom_data": null,
    "origin": "api",
    "collection_mode": "automatic",
    "subscription_id": null,
    "invoice_id": null,
    "invoice_number": null,
    "billing_details": null,
    "billing_period": null,
    "currency_code": "USD",
    "discount_id": null,
    "created_at": "2025-10-08T13:16:19.504257826Z",
    "updated_at": "2025-10-08T13:16:19.52223072Z",
    "revised_at": null,
    "billed_at": "2025-10-08T13:16:19.260260695Z",
    "items": [
      {
        "price": {
          "id": "pri_01k5c14mgh9dc3wgk3vb23p0t7",
          "description": "Monthly/seat with cardless trial",
          "type": "standard",
          "name": "Monthly (per seat)",
          "product_id": "pro_01k5c106wy997av8jmz1qfng2q",
          "billing_cycle": {
            "interval": "month",
            "frequency": 1
          },
          "trial_period": {
            "interval": "day",
            "frequency": 30
          },
          "tax_mode": "external",
          "unit_price": {
            "amount": "3000",
            "currency_code": "USD"
          },
          "unit_price_overrides": [],
          "custom_data": null,
          "quantity": {
            "minimum": 1,
            "maximum": 100
          },
          "status": "active",
          "created_at": "2025-09-17T14:26:59.729668Z",
          "updated_at": "2025-10-08T13:13:00.258616Z",
          "import_meta": null
        },
        "quantity": 10,
        "proration": null
      }
    ],
    "details": {
      "tax_rates_used": [
        {
          "tax_rate": "0.08875",
          "totals": {
            "subtotal": "0",
            "discount": "0",
            "tax": "0",
            "total": "0"
          }
        }
      ],
      "totals": {
        "subtotal": "0",
        "tax": "0",
        "discount": "0",
        "total": "0",
        "grand_total": "0",
        "fee": null,
        "credit": "0",
        "credit_to_balance": "0",
        "balance": "0",
        "earnings": null,
        "currency_code": "USD",
        "exchange_rate": "1"
      },
      "adjusted_totals": {
        "subtotal": "0",
        "tax": "0",
        "total": "0",
        "grand_total": "0",
        "fee": null,
        "retained_fee": "0",
        "earnings": null,
        "currency_code": "USD"
      },
      "payout_totals": null,
      "adjusted_payout_totals": null,
      "line_items": [
        {
          "id": "txnitm_01k71zean5595meshft148t7cc",
          "price_id": "pri_01k5c14mgh9dc3wgk3vb23p0t7",
          "quantity": 10,
          "totals": {
            "subtotal": "0",
            "tax": "0",
            "discount": "0",
            "total": "0"
          },
          "product": {
            "id": "pro_01k5c106wy997av8jmz1qfng2q",
            "name": "AeroEdit Pro",
            "description": "Designed for professional pilots, including all features plus in Basic plus compliance monitoring, route optimization, and third-party integrations.",
            "type": "standard",
            "tax_category": "standard",
            "image_url": "https://paddle.s3.amazonaws.com/user/165798/bT1XUOJAQhOUxGs83cbk_pro.png",
            "custom_data": null,
            "status": "active",
            "import_meta": null,
            "created_at": "2025-09-17T14:24:34.718Z",
            "updated_at": "2025-09-17T14:24:34.718Z"
          },
          "tax_rate": "0.08875",
          "unit_totals": {
            "subtotal": "0",
            "tax": "0",
            "discount": "0",
            "total": "0"
          },
          "proration": null
        }
      ]
    },
    "payments": [],
    "checkout": {
      "url": "https://aeroedit.com/checkout?_ptxn=txn_01k71zeadwbrvevb8czprm2r6c"
    }
  },
  "meta": {
    "request_id": "765a9708-7e6b-4192-8a6e-cb7cfa215f52"
  }
}
```

{% /api-example %}

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

```ts {% 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 createTransaction() {
  try {
    const newTransaction = await paddle.transactions.create({
      items: [
        {
          priceId: 'pri_01k5c14mgh9dc3wgk3vb23p0t7',
          quantity: 10,
        },
      ],
      customerId: 'ctm_01hx93hx7d5fj4f0ah1x4t22yq',
      addressId: 'add_01hyjbr14xazf3hhgz79ysp6hj',
      currencyCode: 'USD',
      collectionMode: 'automatic',
      status: 'billed',
    });

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

createTransaction();
```

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

The response status is `paid` — this is an interim status while Paddle completes transaction processing (typically less than a second), after which the subscription is automatically created. Extract the transaction ID to match this to the created subscription.

## Handle fulfillment {% step=true %}

Paddle automatically creates a subscription for the items on the transaction once it's completed. Fulfillment for cardless trials is the same as for card-required trials or other kinds of subscriptions:

1. Create a webhook endpoint and [create notification destinations](https://developer.paddle.com/webhooks/notification-destinations.md) for subscription and transaction events.
2. Listen for the [`transaction.completed`](https://developer.paddle.com/webhooks/transactions/transaction-completed.md) webhook, using the transaction ID from the create transaction response to match the event to the transaction.
3. Extract and store the `subscription_id` and other relevant information from the payload, then grant the appropriate level of access to your app.

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

### Determine if a subscription is a cardless trial

It's likely that you'll want to present customers with different screens in your app or website if they're on a cardless trial. For example, they won't have a payment method on file, so you might want to present them with a screen that asks them to [enter their payment method](https://developer.paddle.com/build/subscriptions/update-payment-details.md).

```mermaid
flowchart TD
    Start{Is status = 'trialing'?}
    Start -->|No| NotTrial[Not a trial]
    Start -->|Yes| CheckNext{Is next_billed_at = null?}
    
    CheckNext -->|No| CardReq[Card-required trial, or<br>cardless trial with payment method added]
    CheckNext -->|Yes| CheckScheduled{Is scheduled_change = null?}
    
    CheckScheduled -->|Yes| Cardless[Cardless trial]
    CheckScheduled -->|No| CardReqScheduled[Card-required trial<br/>scheduled to cancel]
    
    style Cardless fill:#d4edda,stroke:#28a745,stroke-width:3px
    style NotTrial fill:#f8f9fa
    style CardReq fill:#cfe2ff
    style CardReqScheduled fill:#cfe2ff
```

You can determine that a subscription is a cardless trial by checking the following fields against a [subscription entity](https://developer.paddle.com/api-reference/subscriptions/overview.md):

| Field                   | Value          | Description                                                                                                                                    |
| ------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `status`           | `trialing` | `trialing` is used for both card-required and cardless trials.                                                                           |
| `next_billed_at`   | `null`     | Cardless trials don't have a next billing date because there's no payment method on file. Card-required trials have a next billing date. |
| `scheduled_change` | `null`     | Cardless trials can't be scheduled to cancel, so there can't be a scheduled change. Card-required trials can be scheduled to cancel.     |

You can also use the [list subscriptions operation](https://developer.paddle.com/api-reference/subscriptions/list-subscriptions.md) and pass the `status`, `next_billed_at`, and `scheduled_change_action` parameters to filter for cardless trials. Pass `null` for `next_billed_at` to return subscriptions with no billing date.

{% api-endpoint method="GET" path="/subscriptions?status=trialing&next_billed_at=null&scheduled_change_action=none" href="/api-reference/subscriptions/list-subscriptions" /%}

## Collect payment details {% step=true %}

{% callout type="info" %}
**Customer portal support is coming soon.** While in developer preview, you can't use [customer portal](https://developer.paddle.com/concepts/customer-portal.md) to add payment details for cardless trials. You need to build your own payment workflow.
{% /callout %}

[Paddle Checkout](https://developer.paddle.com/concepts/sell/self-serve-checkout.md) handles securely capturing card details or [other payment method details](https://developer.paddle.com/concepts/payment-methods/overview.md). To convert cardless trials to paying, you'll need to build a payment method update workflow by getting a payment method update transaction, then passing it to Paddle.js to open a checkout for it.

### Get a payment method update transaction

[Payment method update transactions](https://developer.paddle.com/build/subscriptions/update-payment-details.md) are a special kind of zero-value transaction that you can pass to Paddle.js to store a payment method.

To create a payment method update transaction, use the [get a transaction to update payment method operation](https://developer.paddle.com/api-reference/subscriptions/update-payment-method.md). You only need the subscription ID.

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

{% api-example method="GET" path="/subscriptions/{subscription_id}/update-payment-method-transaction" href="/api-reference/subscriptions/update-payment-method" %}

```json
{
  "data": {
    "id": "txn_01k71zrv404gcm17jgtxm8escg",
    "status": "ready",
    "customer_id": "ctm_01hx93hx7d5fj4f0ah1x4t22yq",
    "address_id": "add_01hyjbr14xazf3hhgz79ysp6hj",
    "business_id": null,
    "custom_data": null,
    "origin": "subscription_payment_method_change",
    "collection_mode": "automatic",
    "subscription_id": "sub_01k71zeayp3v7j86zy0k70wd22",
    "invoice_id": null,
    "invoice_number": null,
    "discount_id": null,
    "billing_details": null,
    "billing_period": {
      "starts_at": "2025-10-08T13:16:19.793Z",
      "ends_at": "2025-10-08T13:16:19.793Z"
    },
    "currency_code": "USD",
    "created_at": "2025-10-08T13:22:04.282458451Z",
    "updated_at": "2025-10-08T13:22:04.282458451Z",
    "billed_at": null,
    "revised_at": null,
    "items": [
      {
        "price": {
          "id": "pri_01k5c14mgh9dc3wgk3vb23p0t7",
          "product_id": "pro_01k5c106wy997av8jmz1qfng2q",
          "type": "standard",
          "description": "Monthly/seat with cardless trial",
          "name": "Monthly (per seat)",
          "billing_cycle": {
            "interval": "month",
            "frequency": 1
          },
          "trial_period": {
            "interval": "day",
            "frequency": 30
          },
          "tax_mode": "external",
          "unit_price": {
            "amount": "3000",
            "currency_code": "USD"
          },
          "unit_price_overrides": [],
          "custom_data": null,
          "status": "active",
          "quantity": {
            "minimum": 1,
            "maximum": 100
          },
          "import_meta": null,
          "created_at": "2025-09-17T14:26:59.729668Z",
          "updated_at": "2025-10-08T13:13:00.258616Z"
        },
        "quantity": 10,
        "proration": null
      }
    ],
    "details": {
      "tax_rates_used": [
        {
          "tax_rate": "0.08875",
          "totals": {
            "subtotal": "0",
            "discount": "0",
            "tax": "0",
            "total": "0"
          }
        }
      ],
      "totals": {
        "subtotal": "0",
        "tax": "0",
        "discount": "0",
        "total": "0",
        "grand_total": "0",
        "fee": null,
        "credit": "0",
        "credit_to_balance": "0",
        "balance": "0",
        "earnings": null,
        "currency_code": "USD",
        "exchange_rate": "1"
      },
      "adjusted_totals": {
        "subtotal": "0",
        "tax": "0",
        "total": "0",
        "grand_total": "0",
        "fee": null,
        "earnings": null,
        "currency_code": "USD"
      },
      "payout_totals": null,
      "adjusted_payout_totals": null,
      "line_items": [
        {
          "id": "txnitm_01k71zrvbav9gned4k8mexw3e8",
          "price_id": "pri_01k5c14mgh9dc3wgk3vb23p0t7",
          "quantity": 10,
          "totals": {
            "subtotal": "0",
            "tax": "0",
            "discount": "0",
            "total": "0"
          },
          "product": {
            "id": "pro_01k5c106wy997av8jmz1qfng2q",
            "name": "AeroEdit Pro",
            "type": "standard",
            "tax_category": "standard",
            "description": "Designed for professional pilots, including all features plus in Basic plus compliance monitoring, route optimization, and third-party integrations.",
            "image_url": "https://paddle.s3.amazonaws.com/user/165798/bT1XUOJAQhOUxGs83cbk_pro.png",
            "custom_data": null,
            "status": "active",
            "created_at": "2025-09-17T14:24:34.718Z",
            "updated_at": "2025-09-17T14:24:34.718Z"
          },
          "tax_rate": "0.08875",
          "unit_totals": {
            "subtotal": "0",
            "discount": "0",
            "tax": "0",
            "total": "0"
          },
          "proration": null
        }
      ]
    },
    "payments": [],
    "checkout": {
      "url": "https://aeroedit.com/checkout?_ptxn=txn_01k71zrv404gcm17jgtxm8escg"
    },
    "customer": {
      "id": "ctm_01hx93hx7d5fj4f0ah1x4t22yq",
      "name": null,
      "email": "michael.mcgovern@paddle.com",
      "locale": "en",
      "marketing_consent": false,
      "custom_data": null,
      "status": "active",
      "import_meta": null,
      "created_at": "2024-05-07T08:43:35.533Z",
      "updated_at": "2024-05-07T15:30:54.876311Z"
    },
    "address": {
      "id": "add_01hyjbr14xazf3hhgz79ysp6hj",
      "customer_id": "ctm_01hx93hx7d5fj4f0ah1x4t22yq",
      "description": null,
      "first_line": null,
      "second_line": null,
      "city": null,
      "postal_code": "10021",
      "region": null,
      "country_code": "US",
      "status": "active",
      "custom_data": null,
      "import_meta": null,
      "created_at": "2024-05-23T09:15:36.477Z",
      "updated_at": "2024-05-23T09:15:36.477Z"
    },
    "adjustments_totals": {
      "subtotal": "0",
      "tax": "0",
      "total": "0",
      "fee": "0",
      "earnings": "0",
      "breakdown": {
        "credit": "0",
        "refund": "0",
        "chargeback": "0"
      },
      "currency_code": "USD"
    },
    "available_payment_methods": ["apple_pay", "card", "paypal", "google_pay"]
  },
  "meta": {
    "request_id": "951d4ff2-9aff-4f96-b78c-b0b3e2d50420"
  }
}
```

{% /api-example %}

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

```ts {% 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 getPaymentMethodUpdateTransaction() {
  try {
    const transaction = await paddle.subscriptions.getPaymentMethodChangeTransaction(
      'sub_01hv8wptq8ztpc9j05szh22cgn'
    );

    console.log('Transaction ID for payment method update:', transaction.id);
  } catch (error) {
    console.error('Error retrieving payment method update transaction:', error);
  }
}

getPaymentMethodUpdateTransaction();
```

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

### Pass the transaction ID to Paddle.js

Extract the transaction ID from the response, then use the [`Paddle.Checkout.open()`](https://developer.paddle.com/paddlejs/methods/paddle-checkout-open.md) method to open a checkout for it. Only one-page checkout is supported.

```javascript
Paddle.Checkout.open({
  transactionId: "txn_01k71zrv404gcm17jgtxm8escg",
  settings: {
    variant: "one-page"
  }
});
```

You can also use the `checkout.url` field in the transaction response to automatically open a checkout for the transaction using [your default payment link](https://developer.paddle.com/build/transactions/default-payment-link.md).

For more information, see [Pass a transaction to a checkout](https://developer.paddle.com/build/transactions/pass-transaction-checkout.md)

### Activate immediately {% badge="Optional" %}

When a customer adds their payment details, they still have free access to your app until the end of the trial period. Some customers might want to start paying right away. You can activate a subscription immediately to cut the trial period short and start charging a customer for it.

Use the [activate a trialing subscription operation](https://developer.paddle.com/api-reference/subscriptions/activate-subscription.md) in the Paddle API to build a workflow to activate a subscription immediately. We recommend providing a way for customers to [make changes to their subscription](https://developer.paddle.com/build/subscriptions/update-trials.md), like adding or removing users or changing their plan, before activating a subscription.

For more details, see [Activate a trialing subscription](https://developer.paddle.com/build/subscriptions/extend-activate-change-date-trials.md)

## Incentivize customers to convert {% step=true badge="Optional" %}

{% callout type="info" %}
**Paddle emails are coming soon.** While in developer preview, Paddle doesn't email customers trial ending reminders for cardless trials. You need to send your own emails.
{% /callout %}

The barrier of entry for cardless trials is lower than for card-required trials, which means you'll typically see a higher signup rate compared to card-required trials. However, this often means a lower conversion rate since customers haven't committed to paying yet.

To incentivize customers to convert, we recommend emailing customers throughout their trial period:

| Email type             | When to send                                             | What to include                                                                                 |
| ---------------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| **Trial welcome**      | When the trial starts                                    | Highlight key features and give customers a reminder of their signup information.               |
| **Mid-trial check-in** | Halfway through the trial                                | Prompt to add payment details.                                                                  |
| **Expiring reminder**  | 2-3 days before the trial ends                           | Reminder that the trial is ending and prompt to add payment details or extend the trial period. |
| **Paid plan welcome**  | If a payment method is added                             | Confirmation that the payment method was added and the customer is all set.                     |
| **Expired follow-up**  | After the trial has ended, if no payment method is added | Offer an incentive to reactivate the subscription.                                              |

## Handle non-converting trials {% step=true badge="Optional" %}

By default, when a cardless trial ends and there's no payment method on file, Paddle automatically cancels the subscription.

It's common for customers to sign up for a trial but forget to add their payment details. Customers looking to reactivate a trial have a strong intent to buy, so you should build a way for them to reactivate rather than letting them sign up for another trial. Once reactivated, you can funnel them into a conversion workflow.

To reactivate non-converting trials, build a custom workflow to reinstate the subscription:

1. When a user whose trial expired returns to your app, [get the previous subscription](https://developer.paddle.com/api-reference/subscriptions/list-subscriptions.md) from Paddle or from your database.
2. Extract the items and details like the customer, address, business, and currency code from the previous subscription.
3. [Create a transaction](https://developer.paddle.com/build/transactions/create-transaction.md) using the items and other information that you extracted. Set to `billed` to complete the transaction and create a new subscription.
4. As part of your fulfillment workflow, update the existing subscription record in your database to point to the new subscription in Paddle rather than creating a new one.

On reactivation, we recommend giving customers a shorter trial period and encouraging them to convert by [offering a discount](https://developer.paddle.com/build/products/offer-discounts-promotions-coupons.md) or other incentive. You might like to launch a checkout for the customer to collect payment right away, then [transition the subscription to active](https://developer.paddle.com/build/subscriptions/extend-activate-change-date-trials.md).