Інтеграція LemonSqueezy для SaaS-підписок
LemonSqueezy — платформа Merchant of Record, аналог Paddle, але орієнтована на indie-розробників та малі SaaS-продукти. Береже на себе податки, повернення, fraud detection. Підходить для продуктів на ранній стадії, де немає ресурсів на повноцінний біллінг. Комісія — 5% + 50¢ на безплатному плані, 3.5% + 30¢ на Lemon.js Plus.
Інтеграція займає 1–3 робочих дні.
SDK та настройка
LemonSqueezy надає офіційні SDK для JavaScript/TypeScript та PHP:
npm install @lemonsqueezy/lemonsqueezy.js
composer require lmsqueezy/laravel
Laravel-пакет (lmsqueezy/laravel) додає трейт Billable до моделі User, аналогічно Laravel Cashier:
use LemonSqueezy\Laravel\Billable;
class User extends Authenticatable
{
use Billable;
}
Створення варіанту (variant) для підписки
У LemonSqueezy продукт → варіант (аналог Price у Stripe). Варіанти створюються в dashboard. Для підписки вказується billing interval та trial period.
Checkout
// Сгенерувати checkout URL
$checkout = $user->checkout('variant_id_here', [
'checkout_options' => [
'dark' => true,
'button_color' => '#7C3AED',
'subscription_preview' => true,
],
'checkout_data' => [
'email' => $user->email,
'name' => $user->name,
'custom' => ['user_id' => $user->id],
],
'expires_at' => now()->addHours(24)->toIso8601String(),
]);
return redirect($checkout->url);
Checkout відкривається як оверлей або окрема сторінка на checkout.lemonsqueezy.com. Кастомний домен — тільки на платному плані.
Webhook
// routes/web.php
Route::lemonSqueezyWebhooks('/lemon-squeezy/webhook');
Пакет автоматично верифікує підпис та діспатчить Laravel события:
use LemonSqueezy\Laravel\Events\SubscriptionCreated;
use LemonSqueezy\Laravel\Events\SubscriptionUpdated;
use LemonSqueezy\Laravel\Events\SubscriptionExpired;
use LemonSqueezy\Laravel\Events\OrderRefunded;
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
SubscriptionCreated::class => [ActivateUserSubscription::class],
SubscriptionExpired::class => [DeactivateUserSubscription::class],
OrderRefunded::class => [HandleRefund::class],
];
}
Слухач активації:
class ActivateUserSubscription
{
public function handle(SubscriptionCreated $event): void
{
$userId = $event->subscription->custom_data['user_id'] ?? null;
if (!$userId) return;
$user = User::find($userId);
$user?->update([
'plan' => $event->subscription->product_name,
'subscribed_at' => now(),
'subscription_status' => 'active',
]);
}
}
Управління підпискою
// Отримати підписку користувача
$subscription = $user->subscription();
// Скасувати (в кінці періоду)
$subscription->cancel();
// Негайне скасування
$subscription->cancelNow();
// Відновити відмінену підписку
$subscription->resume();
// Перевірити статус
if ($user->subscribed()) {
// Активна підписка
}
if ($user->onTrial()) {
$trialEndsAt = $user->trialEndsAt();
}
Customer Portal
LemonSqueezy генерує посилання на customer portal:
$portalUrl = $user->customerPortalUrl();
return redirect($portalUrl);
Портал дозволяє змінити карту, завантажити інвойси, скасувати підписку. Кастомізація обмежена.
Ліцензії (одноразові продукти)
LemonSqueezy підтримує не тільки підписки, але й ліцензійні ключі для one-time продуктів. При покупці генерується ключ, який можна активувати через API:
// Активація ліцензійного ключа
$response = Http::withToken(config('lemon-squeezy.api_key'))
->post('https://api.lemonsqueezy.com/v1/licenses/activate', [
'license_key' => $request->license_key,
'instance_name'=> $request->app_name,
]);
if ($response->json('activated')) {
$user->update(['license_key' => $request->license_key, 'is_licensed' => true]);
}
Обмеження
LemonSqueezy не підтримує metered/usage-based billing — тільки фіксовані суми. Для SaaS з оплатою по витраті Stripe Billing або Orb краще. Також немає підтримки B2B інвойсів з відстрочкою платежу. Для простих SaaS-продуктів з фіксованими планами — цілком достатньо.







