Subscriptions
Vatly Laravel provides a full subscription lifecycle: creating, checking, swapping plans, canceling, and syncing with the Vatly API.
Starting a subscription
$checkout = $user->subscribe()
->toPlan('subscription_plan_annual')
->create();
return redirect($checkout->links->checkoutUrl->href);
With a free trial
Trials defer the first charge until the trial elapses. Set them on the builder, in whole days or by end date:
// Whole days from checkout creation
$user->subscribe()
->toPlan('subscription_plan_annual')
->withTrialDays(14)
->create();
// Or an end date — the remaining time is rounded *up* to whole days, so the
// trial never ends earlier than requested (Vatly's trial input is day-granular)
$user->subscribe()
->toPlan('subscription_plan_annual')
->withTrialEndsAt(now()->addMonth())
->create();
withTrialDays() throws for a length below 1 day; withTrialEndsAt() throws for a date that isn't in the future. When no trial is set the checkout payload omits trialDays entirely, so any plan-level default at Vatly still applies.
Checking subscription status
// Check if the user is subscribed
$user->subscribed(); // bool
$user->subscribed('premium'); // check a specific subscription type
// Get the subscription as a fluent handle (operations live here)
$subscription = $user->subscription(); // default type, returns ?SubscriptionHandle
$subscription = $user->subscription('premium');
// Get all subscriptions as Eloquent models (state-only)
$subscriptions = $user->subscriptions; // Collection<Subscription>
$user->subscription('default') returns a Vatly\Fluent\SubscriptionHandle — a lightweight wrapper around the underlying Eloquent model that exposes API-driven operations (swap, cancel, sync, updateBilling). Reach the Eloquent model via $subscription->model() if you need it directly.
Subscription state
$subscription->active(); // currently active (including grace period)
$subscription->cancelled(); // has been cancelled
$subscription->onGracePeriod(); // cancelled but still active until ends_at
Swapping plans
// Swap to a new plan
$user->subscription()->swap('subscription_plan_annual');
// Swap and invoice immediately (prorated)
$user->subscription()->swapAndInvoice('subscription_plan_annual');
Canceling
// Cancel the subscription at Vatly
$user->subscription()->cancel();
The actual cancellation is processed via webhooks. Depending on the Vatly configuration, the subscription may:
- End immediately (
SubscriptionCanceledImmediatelyevent) - Enter a grace period (
SubscriptionCanceledWithGracePeriodevent)
Updating billing details
// Create a signed URL where the customer can update their billing details
// (address, VAT number, company name). Going through the hosted flow also
// refreshes the Mollie mandate as a side effect.
$url = $user->subscription()->updateBilling();
return redirect($url);
Syncing with Vatly
Pull the latest subscription data from the Vatly API:
$user->subscription()->sync();
This updates the local plan_id, name, quantity, ends_at, and trial_ends_at fields.
Subscription types
You can have multiple subscriptions per user by using types:
// A user with both a "default" and "addon" subscription
$user->subscription('default'); // main plan
$user->subscription('addon'); // additional features
The default type is 'default'.