Retire Events subscriptions and owner payment gateways.
Deploy Ladill Events / deploy (push) Successful in 55s

Make Ladill Events free for all accounts, remove plan upgrade UI, force Ladill Pay only for tickets and contributions, and reinstate standard platform fees.
This commit is contained in:
isaacclad
2026-07-24 14:15:34 +00:00
parent ce5ef67a7c
commit 25ce2bc9de
10 changed files with 72 additions and 290 deletions
+2 -2
View File
@@ -16,7 +16,7 @@
<div>
<h1 class="text-xl font-semibold text-slate-900">Payments & Payouts</h1>
<p class="mt-1 text-sm text-slate-500">Paid tickets and contributions settle directly to your connected gateway (0% Ladill fee). This wallet is for app subscriptions and older balances only.</p>
<p class="mt-1 text-sm text-slate-500">Paid tickets and contributions settle via Ladill Pay (standard platform fee). Net proceeds land in your Ladill wallet for withdrawal.</p>
</div>
<div class="grid gap-4 sm:grid-cols-2">
@@ -97,7 +97,7 @@
<div class="rounded-2xl border border-slate-200 bg-white">
<div class="border-b border-slate-100 px-5 py-4">
<h2 class="text-sm font-semibold text-slate-900">Event payments</h2>
<p class="mt-0.5 text-xs text-slate-500">Legacy wallet credits from before BYO gateway settlement. New ticket revenue does not land here.</p>
<p class="mt-0.5 text-xs text-slate-500">Ticket and contribution net proceeds after the Ladill Pay platform fee.</p>
</div>
@if($transactions->isEmpty())
+11 -40
View File
@@ -36,7 +36,7 @@
<div class="rounded-2xl border border-slate-200 bg-white px-6 py-5">
<div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<div class="text-sm text-slate-600">
<strong>{{ $isEnterprise ? 'Business' : 'Pro' }}</strong> active
<strong>Business</strong> active
@if ($subscription->current_period_end)
until <strong>{{ $subscription->current_period_end->format('d M Y') }}</strong>
@endif
@@ -52,7 +52,7 @@
<button class="rounded-xl border border-slate-200 px-4 py-2 text-sm font-medium text-slate-600 hover:bg-slate-50">Cancel auto-renew</button>
</form>
@elseif ($subscription->status === 'canceled')
<form method="post" action="{{ route($isEnterprise ? 'events.pro.subscribe-enterprise' : 'events.pro.subscribe') }}">
<form method="post" action="{{ route('events.pro.subscribe-enterprise') }}">
@csrf
<button class="btn-primary">Resume subscription</button>
</form>
@@ -61,7 +61,7 @@
</div>
@endif
<div class="grid gap-5 lg:grid-cols-3">
<div class="grid gap-5 lg:grid-cols-2">
<div class="flex flex-col rounded-2xl border border-slate-200 bg-white p-6 {{ $planKey === 'free' ? 'ring-2 ring-indigo-500' : '' }}">
<p class="text-xs font-semibold uppercase tracking-wide text-slate-500">Free</p>
<p class="mt-2 text-3xl font-bold text-slate-900">GHS 0</p>
@@ -69,54 +69,25 @@
<ul class="mt-5 flex-1 space-y-2 text-sm text-slate-700">
<li>{{ (int) config('events.free.max_live_events', 2) }} live events</li>
<li>{{ (int) config('events.free.max_tickets_per_month', 100) }} tickets / month</li>
<li>Your own Paystack / Flutterwave / Hubtel</li>
<li>0% Ladill platform fee</li>
<li>Ladill Pay (zero-config)</li>
<li>100 emails + 50 SMS / month</li>
</ul>
@if ($planKey === 'free')
<p class="mt-6 text-sm font-medium text-indigo-700">Current plan</p>
@endif
</div>
<div class="flex flex-col rounded-2xl border border-slate-200 bg-white p-6 {{ $planKey === 'pro' ? 'ring-2 ring-indigo-500' : '' }}">
<p class="text-xs font-semibold uppercase tracking-wide text-indigo-600">Pro</p>
<x-plan-tier-price :currency="$currency" :monthly-minor="$proPriceMinor" />
<ul class="mt-5 flex-1 space-y-2 text-sm text-slate-700">
<li>Unlimited events</li>
<li>Unlimited tickets</li>
<li>BYO payment gateway</li>
<li>Priority support</li>
</ul>
<div class="mt-6">
@if ($planKey === 'pro')
<p class="text-sm text-slate-600">Current plan</p>
@elseif ($gatingActive && ! $hasPaidPlan)
<form x-show="billing === 'monthly'" method="post" action="{{ route('events.pro.subscribe') }}">
@csrf
<button class="btn-primary w-full">Upgrade monthly wallet</button>
</form>
@foreach ($prepaidMonths as $months)
<form x-show="billing == {{ $months }}" method="post" action="{{ route('events.pro.subscribe-prepaid') }}">
@csrf
<input type="hidden" name="plan" value="pro">
<input type="hidden" name="months" value="{{ $months }}">
<button type="submit" class="btn-primary w-full">Pay {{ $months }} months via Paystack</button>
</form>
@endforeach
@endif
</div>
</div>
<div class="flex flex-col rounded-2xl border border-slate-200 bg-gradient-to-b from-slate-900 to-slate-800 p-6 text-white {{ $planKey === 'enterprise' ? 'ring-2 ring-amber-400' : '' }}">
<div class="flex flex-col rounded-2xl border border-slate-200 bg-gradient-to-b from-slate-900 to-slate-800 p-6 text-white {{ in_array($planKey, ['enterprise', 'pro'], true) ? 'ring-2 ring-amber-400' : '' }}">
<p class="text-xs font-semibold uppercase tracking-wide text-amber-300">Business</p>
<x-plan-tier-price :currency="$currency" :monthly-minor="$enterprisePriceMinor" dark />
<ul class="mt-5 flex-1 space-y-2 text-sm text-slate-200">
<li>Everything in Pro</li>
<li>Team seats</li>
<li>Advanced attendee tools</li>
<li>Dedicated onboarding</li>
<li>Unlimited events & tickets</li>
<li>Programmes & badges</li>
<li>Unlimited email & SMS</li>
<li>Team seats & dedicated onboarding</li>
</ul>
<div class="mt-6">
@if ($planKey === 'enterprise')
@if (in_array($planKey, ['enterprise', 'pro'], true))
<p class="text-sm text-slate-200">Current plan</p>
@elseif ($gatingActive && ! $hasPaidPlan)
<form x-show="billing === 'monthly'" method="post" action="{{ route('events.pro.subscribe-enterprise') }}">
@@ -40,17 +40,5 @@
<span class="flex-1 truncate">Settings</span>
</a>
@php $proActive = request()->routeIs('events.pro.*'); @endphp
@if (! empty($hasPaidPlan))
<a href="{{ route('events.pro.index') }}" class="group mt-0.5 flex items-center gap-3 rounded-lg px-3 py-2 text-[13px] transition {{ $proActive ? 'bg-indigo-50 text-indigo-700 font-semibold' : 'text-slate-600 hover:bg-slate-50 hover:text-slate-900' }}">
<svg class="h-[18px] w-[18px] shrink-0 text-amber-500" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.25c.3 0 .58.18.7.46l2.36 5.5 5.96.5a.75.75 0 0 1 .43 1.31l-4.53 3.9 1.36 5.83a.75.75 0 0 1-1.12.81L12 17.77l-5.16 3a.75.75 0 0 1-1.12-.81l1.36-5.83-4.53-3.9a.75.75 0 0 1 .43-1.31l5.96-.5 2.36-5.5c.12-.28.4-.46.7-.46Z"/></svg>
<span>{{ ! empty($isEnterprise) ? 'Events Business' : 'Events Pro' }}</span>
</a>
@else
<a href="{{ route('events.pro.index') }}" class="group mt-0.5 flex items-center gap-3 rounded-lg bg-gradient-to-r from-indigo-600 to-emerald-500 px-3 py-2 text-[13px] font-semibold text-white shadow-sm transition hover:opacity-95">
<svg class="h-[18px] w-[18px] shrink-0" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.25c.3 0 .58.18.7.46l2.36 5.5 5.96.5a.75.75 0 0 1 .43 1.31l-4.53 3.9 1.36 5.83a.75.75 0 0 1-1.12.81L12 17.77l-5.16 3a.75.75 0 0 1-1.12-.81l1.36-5.83-4.53-3.9a.75.75 0 0 1 .43-1.31l5.96-.5 2.36-5.5c.12-.28.4-.46.7-.46Z"/></svg>
<span>Upgrade to Pro</span>
</a>
@endif
</div>
</div>
+3 -25
View File
@@ -272,31 +272,9 @@
<div class="rounded-2xl border border-slate-200 bg-white p-5 space-y-4">
<div>
<h2 class="text-base font-semibold text-slate-900">Online payments</h2>
<p class="mt-1 text-sm text-slate-500">Ladill Pay is the recommended default and needs no API keys. Pro and Business may optionally select an owner gateway.</p>
<p class="mt-1 text-sm text-slate-500">All ticket and contribution checkouts use Ladill Pay zero-config, no owner API keys.</p>
</div>
<p class="rounded-lg bg-emerald-50 px-3 py-2 text-sm text-emerald-800">Ladill Pay is active on all plans and remains the automatic fallback.</p>
@if ($canUsePaymentGateway ?? false)
<select name="gateway_provider" class="w-full rounded-lg border-slate-200 text-sm">
@php $selectedGateway = old('gateway_provider', $gateway?->is_active ? $gateway?->provider : ''); @endphp
<option value="">Ladill Pay (recommended)</option>
@foreach (['paystack' => 'Paystack', 'flutterwave' => 'Flutterwave', 'hubtel' => 'Hubtel'] as $value => $label)
<option value="{{ $value }}" @selected($selectedGateway === $value)>{{ $label }}</option>
@endforeach
</select>
<div class="grid gap-3 sm:grid-cols-2">
<input name="gateway_public_key" value="" placeholder="{{ $gateway?->public_key ? 'Public key saved — leave blank to keep' : 'Public key / merchant account' }}" class="rounded-lg border-slate-200 text-sm">
<input type="password" name="gateway_secret_key" value="" placeholder="{{ $gateway?->secret_key ? 'Secret saved — leave blank to keep' : 'Secret / API key' }}" autocomplete="new-password" class="rounded-lg border-slate-200 text-sm">
</div>
<input type="password" name="gateway_webhook_secret" value="" placeholder="Webhook secret (optional)" autocomplete="new-password" class="w-full rounded-lg border-slate-200 text-sm">
<label class="flex items-center gap-2 text-sm text-slate-700">
<input type="hidden" name="gateway_is_active" value="0">
<input type="checkbox" name="gateway_is_active" value="1" @checked(old('gateway_is_active', $gateway?->is_active ?? false)) class="rounded border-slate-300 text-indigo-600">
Use my gateway instead of Ladill Pay
</label>
<p class="text-xs text-slate-500">Incomplete or invalid credentials automatically fall back to Ladill Pay.</p>
@else
<p class="rounded-lg bg-indigo-50 px-3 py-2 text-sm text-indigo-800">Free uses Ladill Pay only. Upgrade to Pro to optionally connect your own gateway.</p>
@endif
<p class="rounded-lg bg-emerald-50 px-3 py-2 text-sm text-emerald-800">Ladill Pay is the only payment option. Standard platform fees apply on paid tickets and contributions and settle to your Ladill wallet.</p>
</div>
<button type="submit" class="btn-primary">
@@ -309,7 +287,7 @@
<p class="mt-1 text-xs text-slate-500">
Attendee and speaker email/SMS use suite messaging by default no Bird or SMS API keys required.
Set a Ladill mailbox (From address) and optional SMS sender ID under Account Messaging.
Plan allowances cover included sends; Pro overage bills your wallet.
Included suite messaging allowances apply; overage bills your wallet.
</p>
<div class="mt-3 flex flex-wrap gap-x-4 gap-y-2 text-sm font-semibold">
<a href="{{ $messagingSettingsUrl ?? '#' }}" class="text-indigo-600 hover:text-indigo-800" target="_blank" rel="noopener">