Vatly
Php

Subscription Plans

Vatly PHP SDK - Subscription Plans

Subscription plans define recurring billing products. Create them in the Vatly dashboard or through the API, then use them in checkouts. Live plans are reviewed and approved by Vatly before they can be added to checkouts.

The Subscription Plan Resource

Below you'll find all properties for the Vatly Subscription Plan resource.

Properties

NameTypeDescription
idstringUnique identifier for the plan (subscription_plan_...).
namestringDisplay name of the plan.
descriptionstring | nullDescription of the plan.
basePriceMoneyPrice per interval as a Money object — read ->value (decimal string) and ->currency (ISO 4217 code).
taxBehaviorstringWhether basePrice is tax-exclusive (B2B) or tax-inclusive (B2C). Immutable after creation. See Vatly\API\Types\TaxBehavior.
intervalstringBilling interval: day, week, month, or year.
intervalCountintegerNumber of intervals between billings.
productTypestringTax classification. Always saas for plans.
testmodeboolWhether this is a test plan.
statusstringThe status: active (subscribable), pending (awaiting approval), or rejected.
archivedAtstring | nullWhen the plan was archived (ISO 8601), or null while it is open to new business. Use $plan->isArchived() for a boolean.
pendingUpdatesobject | nullThe changes that will take effect once a submitted update is approved, or null when there is none. Only the fields that differ from the live plan are present.
updateStatusstring | nullLifecycle of a pending update: pending, reviewing, or null. See Vatly\API\Types\UpdateStatus.
createdAtstringCreation timestamp (ISO 8601).

Create a plan

POST /v1/subscription-plans

Create a subscription plan. A plan created with a live_ token starts in pending status and must be approved by Vatly before it can be added to checkouts; a plan created with a test_ token is auto-approved (active).

Required attributes

NameTypeDescription
namestringDisplay name (3–255 characters).
descriptionstringDetailed description of the plan.
basePricearrayPrice per interval as ['value' => '29.00', 'currency' => 'EUR'].
productTypestringTax classification. Only saas is billable on a recurring basis.
intervalstringBilling interval unit. day is sandbox-only; live plans support week, month, year.
intervalCountintegerInterval units between billings (≤ 365 days / 52 weeks / 12 months). For year, billing is always annual and this is ignored.

Optional attributes

NameTypeDescription
taxBehaviorstringexclusive (default) or inclusive. Immutable after creation.
$plan = $vatly->subscriptionPlans->create([
    'name' => 'Pro Monthly',
    'description' => 'Full access to all Pro features, billed monthly',
    'basePrice' => ['value' => '29.00', 'currency' => 'EUR'],
    'productType' => 'saas',
    'interval' => 'month',
    'intervalCount' => 1,
    'taxBehavior' => 'exclusive', // optional; defaults to 'exclusive'
]);

echo $plan->id;      // subscription_plan_...
echo $plan->status;  // 'pending' (live) or 'active' (test)

Update a plan

PATCH /v1/subscription-plans/:id

Submit an update to a live plan. Each request is the complete set of changes relative to the current live plan and must contain at least one field. In live mode the change is held as a pending update and reviewed by Vatly before it takes effect (updateStatus moves pendingreviewing → applied); in test mode it is approved automatically. A request that nets to no change clears any pending update; while an update is being reviewed, further requests return 409.

The interval cannot be changed once the plan has ever been used by a subscription (active or not) — that returns 409. The price stays changeable.

Optional attributes

NameTypeDescription
namestringNew display name (3–255 characters).
descriptionstringNew description.
basePricearrayNew price per interval as ['value' => '9.00', 'currency' => 'EUR'].
intervalstringNew billing interval. Requires intervalCount.
intervalCountintegerRequired when interval is provided.
productTypestringsaas.
$plan = $vatly->subscriptionPlans->update('subscription_plan_abc123', [
    'name' => 'Pro Weekly',
    'basePrice' => ['value' => '9.00', 'currency' => 'EUR'],
    'interval' => 'week',
    'intervalCount' => 1,
]);

echo $plan->updateStatus;              // 'pending'
echo $plan->pendingUpdates->interval;  // 'week'

Archive a plan

POST /v1/subscription-plans/:id/archive

Close a plan to new business. It is hidden from list calls (unless includeArchived=true), refused by new checkouts, and can no longer be switched to from a subscription update. Subscribers already on the plan are deliberately untouched — a subscription snapshots its plan at signup and renews off that snapshot, so archiving never cancels anyone or changes what they are billed. Nothing is deleted; the plan keeps a non-null archivedAt. The call returns no content.

$vatly->subscriptionPlans->archive('subscription_plan_abc123');

// or, on a resource you already hold:
$plan->archive();

Unarchive a plan

DELETE /v1/subscription-plans/:id/archive

Re-open an archived plan to new business. It reappears in listings and can be added to checkouts and switched to again. Returns the plan, now open to new business (archivedAt is null).

$plan = $vatly->subscriptionPlans->unarchive('subscription_plan_abc123');

Retrieve a plan

GET /v1/subscription-plans/:id

Retrieve a subscription plan by its ID.

$plan = $vatly->subscriptionPlans->get('subscription_plan_abc123');

echo $plan->name;
echo $plan->basePrice->value . ' ' . $plan->basePrice->currency;
echo $plan->interval;

List all plans

GET /v1/subscription-plans

Retrieve a paginated list of all subscription plans.

Optional attributes

NameTypeDescription
limitintegerThe number of plans to return (default: 10, max: 100).
startingAfterstringA cursor for pagination.
includeArchivedbooleanInclude archived plans in the list. Archived plans are hidden by default; pass true to see them (tell them apart by the non-null archivedAt).
$plans = $vatly->subscriptionPlans->page();

foreach ($plans as $plan) {
    echo $plan->name . ': ' . $plan->basePrice->value . ' ' . $plan->basePrice->currency;
}

// Include archived plans in the listing:
$all = $vatly->subscriptionPlans->page(null, null, null, ['includeArchived' => true]);
Copyright © 2026