**Subscriptionify: керування підписками в Laravel на основі доступних функцій**

Перекладено ШІ 0 Laravel News 16 червня, 2026

Subscriptionify пропонує гнучке моделювання планів підписки та лімітів функцій незалежно від обраного платіжного сервісу. Дізнайтеся, як цей пакет допоможе вам легко налаштувати квоти та відстежувати використання ресурсів у вашому Laravel-проєкті.

Subscriptionify — це пакет для Laravel, розроблений Rasel Islam Rafi для гнучкого моделювання тарифних планів та функцій, які вони відкривають. На відміну від Laravel Cashier, що фокусується на платіжних API, Subscriptionify не залежить від конкретного шлюзу (gateway-agnostic): він відстежує плани, квоти та споживання ресурсів у вашій базі даних. Це робить його ідеальним для проєктів, які використовують нестандартні платіжні системи, списують кошти з внутрішнього балансу або надають доступ безкоштовно. Пакет потребує PHP 8.2 та підтримує Laravel 11, 12 і 13.

Процес інсталяції додає файл конфігурації та міграції для шести таблиць: плани, функції, зв’язки між ними, підписки, записи про використання та пряме надання функцій:

composer require revoltify/subscriptionify
 
php artisan vendor:publish --tag=subscriptionify-config
php artisan vendor:publish --tag=subscriptionify-migrations
php artisan migrate

Будь-яка модель може стати об'єктом підписки, якщо реалізувати контракт Subscribable та додати трейт InteractsWithSubscriptions. Це дозволяє прив’язувати тарифи до User, Organisation або Workspace залежно від архітектури застосунку:

use Revoltify\Subscriptionify\Concerns\InteractsWithSubscriptions;
use Revoltify\Subscriptionify\Contracts\Subscribable;
 
class Workspace extends Model implements Subscribable
{
    use InteractsWithSubscriptions;
}

# Чотири типи функцій для різних сценаріїв

Основна концепція полягає в тому, що різні можливості споживаються по-різному. Subscriptionify пропонує чотири типи функцій із власними правилами:

  • Toggle — простий перемикач (увімкнено/вимкнено), що визначає доступ до конкретної можливості.
  • Consumable — квота, що оновлюється за графіком (наприклад, ліміт API-запитів на місяць).
  • Limit — жорстке обмеження на кількість активних елементів (наприклад, кількість проєктів або учасників), де видалення одного елемента звільняє місце.
  • Metered — оплата за фактичне використання без фіксованого ліміту.

Функції створюються один раз, а потім прив’язуються до планів із визначенням лімітів для кожного конкретного тарифу:

use Revoltify\Subscriptionify\Models\Feature;
use Revoltify\Subscriptionify\Enums\FeatureType;
 
$reports = Feature::create([
    'name' => 'Exported Reports',
    'slug' => 'reports',
    'type' => FeatureType::Consumable,
]);
 
$plan->features()->attach($reports, [
    'value'          => 500,           // 0 означає необмежено
    'unit_price'     => '0.02000000',  // ціна за одиницю після вичерпання квоти
    'reset_period'   => 1,
    'reset_interval' => 'month',
]);

# Відстеження використання ресурсів

Після оформлення підписки методи для роботи з використанням доступні безпосередньо в моделі. Ви можете перевіряти доступ, наявність вільних одиниць та фіксувати споживання, не звертаючись до таблиць підписок вручну:

$workspace->subscribe($plan);
 
$workspace->hasFeature('reports');          // чи доступна функція взагалі?
$workspace->canConsume('reports', 10);      // чи є зараз 10 доступних одиниць?
$workspace->consume('reports', 10);         // фіксує використання, видає помилку при перевищенні
$workspace->tryConsume('reports', 10);      // повертає false замість помилки
$workspace->remainingUsage('reports');      // залишок одиниць у поточному періоді

Для функцій типу Limit метод release() повертає одиницю ресурсу, що відрізняє цей тип від звичайних лімітів, які лише зменшуються:

$workspace->consume('projects', 1);  // створення проєкту (займає слот)
$workspace->release('projects', 1);  // видалення проєкту (звільняє слот)

# Пряме надання функцій поза планом

Метод grantFeature() дозволяє призначити функцію моделі безпосередньо, додаючи її до можливостей основного плану. Це зручно для одноразових бонусів або індивідуальних налаштувань для клієнта без створення окремого тарифу:

$workspace->grantFeature('reports', value: 1_000);
 
// З автоматичним оновленням за власним графіком
use Revoltify\Subscriptionify\Enums\Interval;
 
$workspace->grantFeature('reports', value: 100, resetPeriod: 1, resetInterval: Interval::Month);
 
// Скасування індивідуального доступу (діятимуть лише ліміти плану)
$workspace->revokeFeature('reports');

# Опціональна тарифікація та оплата за використання

Функції білінгу можна підключити за потреби. Реалізуйте контракт HasFunds разом із Subscribable, і пакет почне списувати кошти з керованого вами балансу. У такому разі типи Consumable та Limit дозволяють перевищувати ліміти за додаткову плату (якщо вказана unit_price), а Metered тарифікуватимуться з першої одиниці використання:

use Revoltify\Subscriptionify\Contracts\HasFunds;
 
class Workspace extends Model implements Subscribable, HasFunds
{
    use InteractsWithSubscriptions;
 
    public function getBalance(): string
    {
        return $this->balance;
    }
 
    public function hasSufficientFunds(string $amount): bool
    {
        return bccomp($this->balance, $amount, 8) >= 0;
    }
 
    public function deductFunds(string $amount, string $description): void
    {
        $this->update(['balance' => bcsub($this->balance, $amount, 8)]);
    }
}

Завдяки використанню bccomp усі фінансові обчислення виконуються з довільною точністю, що виключає помилки округлення чисел із рухомою комою. Без HasFunds пакет просто блокуватиме дії при вичерпанні лімітів.

# Контроль доступу через Middleware та Blade

Для захисту маршрутів передбачено три Middleware, які повертають помилку 403 у разі невідповідності умовам:

Route::middleware('subscribed')->group(function () {
    // будь-яка активна або пробна підписка
});
 
Route::middleware('plan:pro')->group(function () {
    // конкретний тарифний план
});
 
Route::middleware('feature:reports')->group(function () {
    // доступ до конкретної функції
});

Спеціальні Blade-директиви спрощують керування контентом у шаблонах, враховуючи пробні періоди, безкоштовні плани та пільговий період після скасування (grace period):

@feature('custom-branding')
    {{-- відображається лише за наявності доступу до функції --}}
@endfeature
 
@onTrial
    {{-- банер із відліком пробного періоду --}}
@endonTrial

# Життєвий цикл, події та автоматичне скасування

Subscriptionify підтримує всі етапи життєвого циклу підписки: зміну плану (changePlan()), поновлення (renew()), скасування (cancel()) та відновлення (resume()). Кожна зміна стану викликає подію (наприклад, SubscriptionCreated або FeatureConsumed). Також пакет містить команду для автоматичного переведення протермінованих підписок у статус "expired":

use Illuminate\Support\Facades\Schedule;
 
Schedule::command('subscriptionify:expire-overdue')->hourly();

Детальніше про налаштування та можливості кастомізації читайте на сторінці проєкту в GitHub.

Популярні

Інше, що варто прочитати

30 Оновлено 16 червня, 2026

Інтеграція Laravel Socialite з бібліотекою Google Client PHP

Ви хочете навчитися, як інтегрувати Google OAuth у вашому проекті Laravel, використовуючи Socialite? Дізнайтеся, як налаштувати доступ до сервісів Google, таких як Календар, у нашій сьогоднішній статті

11 Оновлено 16 червня, 2026

Генерація документації в Laravel за допомогою штучного інтелекту

Docudoodle — це потужний пакет для генерації документації в Laravel, який допомагає легко аналізувати вашу кодову базу та створювати документацію за допомогою обраного вами AI. Чи готові ви дізнатися, як цей інструмент може спростити вашу роботу з документуванням коду? Читайте далі!

16 Оновлено 16 червня, 2026

Журнал аудиту в Laravel

Хочете забезпечити повну прозорість у своїх Laravel-додатках? Пакет Laravel Audit Log допоможе вам детально відстежувати всі зміни моделей Eloquent та відповідати вимогам регуляторів. Читайте далі, щоб дізнатися, як цей потужний інструмент може підвищити надійність вашого проєкту