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

Коментарі

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

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

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

Human-in-the-Loop
Новини 31 липня 2026

Laravel AI SDK отримав функцію Human-in-the-Loop для підтвердження дій

На Laracon US 2026 команда Laravel представила API human-in-the-loop для Laravel AI SDK. Тепер агенти можуть зупинятися перед виконанням інструмента та чекати на підтвердження, відхилення або редагування аргументів людиною.

Laracon US 2026: відео другого дня вже доступне Рекомендовано
Новини 30 липня 2026

Laracon US 2026: відео другого дня вже доступне

Другий день Laracon US 2026 завершив конференцію в Бостоні, і запис уже доступний. Кент Ч. Доддс про продуктове інженерство в епоху AI, Джо Таненбаум про реалтайм-застосунки на Reverb і Echo, Пауліна Вос про JJ - надбудову над Git з атомарними комітами.

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

PulsePaw Нова
Вчора

Junior Strong/Middle PHP developer

Розробник PHP/Laravel для фінтех-проекту на мікросервісній архітектурі. Відповідатиме за підтримку та покращення кодової бази, оптимізацію продуктивності, роботу з MySQL, Redis, черг. Потрібні 2+ роки комерційної розробки, 1+ років PHP (Laravel), розуміння OOP та SOLID, мінімальні знання HTML/CSS/JS.

AI-Assisted Developer

Розробник, який використовує Claude Code для реалізації фіч та виправлення багів на B2B2C-платформі. Стек: PHP/Laravel (бекенд), Vue.js (фронтенд), REST API. Вимоги: базове розуміння веб-розробки, знайомство з PHP/JavaScript на рівні читання коду, практична робота з Git та AI-інструментами для кодингу, англійська B1+. Фокус на вмінні формулювати завдання для AI, перевіряти результати та інтегрувати в кодову базу.

Back-end розробник, програміст PHP (Laravel, Yii2)

Київ Офіс Full-time Middle від ₴60,000

PHP-розробник для розробки компонентів і модулів на Laravel та Yii2. Потрібні знання PHP, MySQL, ООП, патернів проектування та інтеграція із зовнішніми сервісами. Гнучкий графік, можливість професійного зростання.

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

Bagisto

bagisto/bagisto

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

27,769 v2.4.8 12 15

Lang

laravel-lang/lang

Список 126 мов для Laravel Framework, Laravel Jetstream, Laravel Fortify, Laravel Breeze, Laravel Cashier, Laravel Nova, Laravel Spark та Laravel UI.

7,779 15.33.1 8

Відео за темою