> ## Documentation Index
> Fetch the complete documentation index at: https://docs.subscribd.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Trial Management

> Start, convert, extend, and cancel free trial periods

# Trial Management

Trials give users time to evaluate your product before they're charged. Subscribd handles the full trial lifecycle — from starting a no-card trial to converting it to a paid subscription.

## Starting a trial

Trials start automatically when a plan defines `trial_days`. No extra code is needed in the subscription creation call:

```php theme={null}
// config/subscribd.php
'plans' => [
    'pro' => [
        'trial_days' => 14,
        // ...
    ],
],
```

```php theme={null}
use Pixelworxio\Subscribd\Actions\CreateSubscription;
use Pixelworxio\Subscribd\Models\Plan;

$plan = Plan::where('key', 'pro')->firstOrFail();
app(CreateSubscription::class)->execute($user, $plan);

$subscription = $user->subscription();
$subscription->onTrial();       // true
$subscription->trial_ends_at;   // CarbonImmutable 14 days from now
```

## Card-free trials

Set `trial_requires_payment_method` to `false` on the plan to start a trial without collecting payment details:

```php theme={null}
'pro' => [
    'trial_days'                    => 14,
    'trial_requires_payment_method' => false,
    // ...
],
```

With this setting, `CreateSubscription` makes no gateway API call. The subscription's `gateway_id` is `null` until the trial is converted to active via `ConvertTrialToActive`, at which point the gateway creates the subscription and collects payment.

## Converting a trial to active

Use `ConvertTrialToActive` to end the trial immediately and collect payment:

```php theme={null}
use Pixelworxio\Subscribd\Actions\ConvertTrialToActive;

$subscription = $user->subscription();
app(ConvertTrialToActive::class)->execute($subscription);
```

What happens:

1. The gateway creates or updates the subscription and triggers the first charge.
2. On payment success, the subscription transitions to `Active` and `TrialEnded` is fired with `$converted = true`.
3. On payment failure, the subscription transitions to `PastDue` and `TrialEnded` is fired with `$converted = false`. Dunning retries begin.

## Extending a trial

Add days to a trial, or set an explicit end date:

```php theme={null}
use Pixelworxio\Subscribd\Actions\ExtendTrial;
use Carbon\CarbonImmutable;

// Add 14 days to the trial
app(ExtendTrial::class)->execute($subscription, days: 14);

// Set an explicit trial end date
app(ExtendTrial::class)->execute($subscription, until: CarbonImmutable::parse('2026-09-01'));
```

When the active gateway supports trial extension, the new date is pushed to the gateway. Otherwise, only the local `trial_ends_at` column is updated.

**Gateway support for trial extension:**

| Gateway    | Supported |
| ---------- | --------- |
| Stripe     | ✅ Yes     |
| PayPal     | ❌ No      |
| Braintree  | ❌ No      |
| Paddle     | ❌ No      |
| FastSpring | ❌ No      |
| Square     | ❌ No      |

## Canceling a trial

Cancel a `Trialing` subscription before it converts:

```php theme={null}
use Pixelworxio\Subscribd\Actions\CancelTrial;

app(CancelTrial::class)->execute($subscription);
```

This delegates to `CancelSubscription` with `immediately: true`. Throws `SubscriptionException` if the subscription is not in `Trialing` status.

## Trial helpers on the billable

```php theme={null}
// Extend the default subscription's trial by 7 days
$user->extendTrial(days: 7);
$user->extendTrial('team', days: 7);           // named slot

// Cancel the trial
$user->cancelTrial();
$user->cancelTrial('team');

// Convert the trial to active (triggers payment)
$user->convertTrial();
$user->convertTrial('team');
```

These helpers delegate to the corresponding action classes.

## Listening to trial events

```php theme={null}
use Pixelworxio\Subscribd\Events\TrialEnded;

Event::listen(TrialEnded::class, function (TrialEnded $event): void {
    if ($event->converted) {
        // Payment succeeded — subscription is now Active
    } else {
        // Payment failed — subscription is now PastDue
    }
});
```

Other trial-related events dispatched by the package:

| Event                  | Fired when                                    |
| ---------------------- | --------------------------------------------- |
| `TrialEnded`           | Trial converts or payment fails at conversion |
| `SubscriptionUpdated`  | Trial extended                                |
| `SubscriptionCanceled` | Trial canceled                                |

## The TrialStatus Livewire component

Drop the `trial-status` component into any Livewire view to give subscribers a self-service trial management UI:

```blade theme={null}
<livewire:subscribd::subscriber.trial-status />

{{-- Named subscription slot --}}
<livewire:subscribd::subscriber.trial-status :subscription-name="'team'" />
```

The component shows:

* Days remaining in the trial
* A "Convert to paid" button (triggers `ConvertTrialToActive`)
* An "Extend trial" button when the gateway supports it (Stripe)
* A "Cancel trial" button with inline confirmation

It is automatically composed into `subscription-manager` when the subscription is on trial — no extra wiring needed.

### Blade static component

A read-only variant with no action buttons:

```blade theme={null}
<x-subscribd-trial-status />
<x-subscribd-trial-status subscription-name="team" />
```

Renders nothing when the user is not on a trial.

## Scheduled trial expiry

Add the following scheduled command to expire trials automatically. Subscribd runs this via `subscribe:expire-trials`:

```php theme={null}
// routes/console.php
Schedule::command('subscribd:expire-trials')->hourly();
Schedule::command('subscribd:dispatch-trial-ending-events')->daily();
```

`dispatch-trial-ending-events` fires `TrialEnding` for each trial that ends within the next 72 hours, giving you time to send reminder emails.

## Next steps

* **[Subscription Status](/subscriptions/status)** — Full status reference
* **[Hooks and Events](/advanced/hooks-and-events)** — All billing events
* **[Livewire Components](/components/livewire)** — TrialStatus component reference
