Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
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

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

Коментарі

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

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

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

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

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

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

9
CSRF і завантаження
Новини 09 жовтня 2026

Порада з безпеки: як завантаження файлів може обійти захист від CSRF

Стівен Ріс-Картер пояснює, чому файли користувачів варто віддавати з окремого домену: HTML і JS у межах основного застосунку дають доступ до cookie та CSRF-токенів.

18

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

N-iX Нова
Вчора

Senior/ Lead PHP Engineer (with AI Skills) (#5828)

Розробка та підтримка backend-сервісів і API на PHP та Laravel з повним циклом володіння фічами від дизайну до моніторингу. Ключове завдання - інтеграція агентних AI-workflow (LLM-агенти, tool calling) у продукт і внутрішні інструменти, а також менторство інших інженерів. Вимоги: 6+ років PHP, 4+ роки з Laravel, досвід GenAI, знання MySQL/PostgreSQL, Docker та хмарних платформ, робота за часовим поясом EDT.

Full Stack Developer (middle+)

Full Stack розробник розвиватиме та підтримуватиме вебпродукти FinTech-компанії: доопрацьовуватиме backend і frontend, функціонал особистого кабінету клієнта, інтеграції через REST API з платіжними та ідентифікаційними сервісами. Ключовий стек: PHP, Laravel, Vue.js (Vue Router, Pinia або Vuex), MySQL/PostgreSQL, Docker, Git. Вимоги: понад 3 роки комерційного Full Stack досвіду, робота з наявним кодом, участь у code review та розборі інцидентів.

Bulls-media Нова
2 дні тому

Junior+ Full Stack Developer

Розробник PHP/Laravel для роботи на фулстеку: розробка та підтримка бекенду на PHP/Laravel і фронтенду на JavaScript/HTML/CSS. Основний стек: PHP, Laravel, MySQL, REST API, Git. Вимоги: 1+ років досвіду в веб-розробці, хороше знання PHP, базово-проміжна рівень Laravel, розуміння JavaScript, HTML/CSS, REST API та OOP. Менторство від досвідчених розробників, робота з реальними комерційними проєктами.

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

Laravel Cashier

laravel/cashier

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

2,542 v16.7.0 13 1

Bagisto

bagisto/bagisto

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

28,221 v2.5.0 13 26