Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Subscriptionify: пакет для управління підписками на основі функцій у Laravel
Новини 16 червня 2026

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

Subscriptionify - це Laravel-пакет, створений Rasel Islam Rafi, для моделювання планів підписки та функцій, які вони відкривають. Якщо Laravel Cashier обгортає API виставлення рахунків платіжного провайдера, то Subscriptionify залишається незалежним від шлюзів: він відстежує плани, квоти функцій та використання у вашій власній базі даних, залишаючи питання оплати на ваш розсуд. Це робить його придатним для додатків, які виставляють рахунки через провайдера, не охопленого Cashier, стягують плату з попередньо оплаченого балансу або надають доступ взагалі без оплати. Пакет вимагає 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 - відстежує споживання з оплатою за використання без обмежень, стягуючи плату за одиницю.

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

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',
]);

Відстеження використання на моделі з підпискою

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

$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() повертає одиниці назад, щоб звільнити слот, що відрізняє ліміт від consumable, який тільки зменшується:

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

Прямі надання незалежно від плану

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

$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, і пакет починає стягувати плату з балансу, яким ви керуєте. З HasFunds функції 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 обмежують контент у виглядах, включаючи стани для пробних версій, безкоштовних планів та пільгового періоду після скасування:

@feature('custom-branding')
    {{-- показується лише коли функція доступна --}}
@endfeature

@onTrial
    {{-- банер зворотного відліку пробного періоду --}}
@endonTrial

За замовчуванням обидва визначають підписника з auth()->user(), що можна змінити за допомогою Subscriptionify::resolveSubscribableUsing(), якщо ваша платоспроможна модель не є автентифікованим користувачем.

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

Підписки мають звичайні методи життєвого циклу (changePlan(), renew(), cancel(), cancelNow() та resume() протягом пільгового періоду), і кожен перехід відправляє подію, таку як SubscriptionCreated, SubscriptionCancelled або FeatureConsumed, на які можуть реагувати ваші власні слухачі. Включена artisan-команда переводить активні підписки після їхньої дати закінчення у статус прострочених:

use Illuminate\Support\Facades\Schedule;

Schedule::command('subscriptionify:expire-overdue')->hourly();

Щоб ознайомитися з повним списком функцій, параметрами конфігурації та хуками налаштування, відвідайте пакет на GitHub.

48

Читати в документації

Коментарі

Увійдіть, щоб залишити коментар

Будьте першим, хто залишить коментар!

Читайте також

Filament v5.10.0
Новини 12 жовтня 2026

Filament v5.10.0: сітка в rich editor, скелетони таблиць і десятки виправлень

Вийшов Filament v5.10.0: елементи керування сіткою в rich editor, допоміжний контент для віджетів-графіків, скелетони завантаження таблиць, submitOnCompletion() для OneTimeCodeInput та багато виправлень авторизації, доступності й стану.

22
Laravel AI SDK на практиці
Новини 09 жовтня 2026

Laravel AI SDK на практиці: агент, що стоїть за There There

Фрік Ван дер Гертен розповідає, як у Spatie побудували AI-шар хелпдеска There There на Laravel AI SDK: клас агента, інструменти з типізованою JSON-схемою та делегування роботи звичайним domain-діям.

18

Вакансії за темою

Intetics Нова
2 дні тому

Senior Full-Stack PHP Developer (Laravel + React/Vue)

Senior Full-Stack PHP розробник створює й підтримує масштабовані веб-застосунки: бекенд на Laravel та фронтенд на React або Vue. Відповідає за архітектурні рішення (дизайн сервісів, моделювання даних, кешування, черги), проєктує REST API та інтеграції, рефакторить legacy-код і оптимізує запити. Вимоги: 5+ років досвіду з сучасним PHP 8.x, 3+ роки з Laravel, 3+ роки з React або Vue, сильний TypeScript, досвід з Redis і чергами, автотести та CI/CD.

AirAdvisor Нова
3 дні тому

PHP Laravel Full Stack Developer with jQuery and JavaScript

Full stack розробник на PHP з фокусом на Laravel: backend-сервіси, веб-застосунки та інтеграція фронтенду на Bootstrap або Tailwind CSS, jQuery і JavaScript. Потрібна робота з MySQL у високонавантажених середовищах, кешування та черги (Redis, Memcached, RabbitMQ), підтримка legacy PHP без фреймворків і міграція на сучасні фреймворки. Вимоги: значний досвід PHP, побудова та масштабування API для high-traffic застосунків, знання HTML, CSS, JavaScript. Віддалена робота, оформлення через B2B або ФОП

King Group Нова
3 дні тому

Middle PHP developer

Розробник PHP middle-рівня для високонавантаженої веб-платформи Social Casino/Online Casino, яка активно масштабується. Основний стек: PHP 7.4, Symfony 4, Yii, PostgreSQL 14, Redis, RabbitMQ, NGINX; частина сервісів переходить на мікросервіси на Symfony. Вимоги: 3-4+ роки продуктового досвіду з PHP, Yii або Symfony, PostgreSQL, розуміння REST API, досвід роботи з Git, знання ООП і SOLID. Буде плюсом досвід з брокерами повідомлень і DDD.

Пакети за темою

Laravel Cashier

laravel/cashier

Підписки і платежі через Stripe: тарифи, пробні періоди, купони, зміна плану, рахунки в PDF і обробка вебхуків. Ховає більшість рутини платіжної інтеграції за виразним API.

2,542 v16.7.0 13 2

Bagisto

bagisto/bagisto

Bagisto — це платформа для електронної комерції, побудована на Laravel. Вона надає готове рішення для створення та управління інтернет-магазинами з підтримкою каталогу товарів, замовлень, платежів та клієнтів.

28,267 v2.5.0 13 26