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
+16 -98
View File
@@ -3,134 +3,52 @@
namespace App\Http\Controllers\Events;
use App\Http\Controllers\Controller;
use App\Models\Events\ProSubscription;
use App\Models\User;
use App\Services\Billing\BillingClient;
use App\Services\Events\SubscriptionService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
/**
* Paid Events plans are retired. Routes remain so old bookmarks and emails
* do not 404; every action redirects to the dashboard.
*/
class ProController extends Controller
{
public function __construct(private readonly SubscriptionService $subscriptions) {}
public function index(Request $request): View
public function index(Request $request): RedirectResponse
{
$user = ladill_account() ?? $request->user();
$planKey = $this->subscriptions->planKey($user);
return view('events.pro.index', [
'subscription' => $this->subscriptions->subscriptionFor($user),
'planKey' => $planKey,
'isPro' => $planKey === ProSubscription::PLAN_PRO,
'isEnterprise' => $planKey === ProSubscription::PLAN_ENTERPRISE,
'hasPaidPlan' => $this->subscriptions->hasPaidPlan($user),
'gatingActive' => $this->subscriptions->gatingActive(),
'proPriceMinor' => $this->subscriptions->priceMinor(),
'enterprisePriceMinor' => $this->subscriptions->enterprisePriceMinor(),
'prepaidMonths' => (array) config('events.prepaid_months', [6, 12, 24]),
'currency' => (string) config('events.pro.currency', 'GHS'),
]);
return $this->retired();
}
public function subscribe(Request $request): RedirectResponse
{
[$ok, $message] = $this->subscriptions->subscribe(ladill_account() ?? $request->user());
return redirect()->route('events.pro.index')->with($ok ? 'success' : 'error', $message);
return $this->retired();
}
public function subscribeEnterprise(Request $request): RedirectResponse
{
[$ok, $message] = $this->subscriptions->subscribeEnterprise(ladill_account() ?? $request->user());
return redirect()->route('events.pro.index')->with($ok ? 'success' : 'error', $message);
return $this->retired();
}
public function subscribePrepaid(Request $request, BillingClient $billing): RedirectResponse
{
$validated = $request->validate([
'plan' => ['required', 'in:pro,enterprise'],
'months' => ['required', 'integer', 'in:6,12,24'],
]);
$user = ladill_account() ?? $request->user();
if ($this->subscriptions->hasPaidPlan($user)) {
return redirect()->route('events.pro.index')
->with('success', 'You already have an active subscription.');
}
$plan = $validated['plan'];
$months = (int) $validated['months'];
$monthlyMinor = $plan === 'enterprise'
? $this->subscriptions->enterprisePriceMinor()
: $this->subscriptions->priceMinor();
try {
$checkout = $billing->initiatePlanCheckout(
$user,
$plan,
$months,
$monthlyMinor * $months,
route('events.pro.paystack.callback'),
['user_id' => $user->id],
);
} catch (\Throwable) {
return redirect()->route('events.pro.index')
->with('error', 'Could not start Paystack checkout. Please try again.');
}
$url = trim((string) ($checkout['checkout_url'] ?? ''));
if ($url === '') {
return redirect()->route('events.pro.index')
->with('error', 'Paystack did not return a checkout URL.');
}
return redirect()->away($url);
return $this->retired();
}
public function paystackCallback(Request $request, BillingClient $billing): RedirectResponse
{
$reference = (string) $request->query('reference', '');
if ($reference === '') {
return redirect()->route('events.pro.index')->with('error', 'Missing payment reference.');
}
try {
$result = $billing->verifyPlanCheckout($reference);
} catch (\Throwable) {
return redirect()->route('events.pro.index')
->with('error', 'Could not verify payment. Contact support with reference: '.$reference);
}
if (! ($result['paid'] ?? false)) {
return redirect()->route('events.pro.index')
->with('error', 'Payment was not completed.');
}
$metadata = (array) ($result['metadata'] ?? []);
$user = User::query()->find((int) ($metadata['user_id'] ?? 0));
$account = ladill_account() ?? $request->user();
if (! $user || ! $account || $user->id !== $account->id) {
return redirect()->route('events.pro.index')
->with('error', 'Account not found for this payment.');
}
$plan = (string) ($result['plan'] ?? 'pro');
$months = (int) ($result['months'] ?? 0);
$this->subscriptions->activatePrepaid($user, $plan, $months);
$label = $plan === 'enterprise' ? 'Events Business' : 'Events Pro';
return redirect()->route('events.pro.index')
->with('success', "{$label} is active for {$months} months.");
return $this->retired();
}
public function cancel(Request $request): RedirectResponse
{
[$ok, $message] = $this->subscriptions->cancel(ladill_account() ?? $request->user());
return $this->retired();
}
return redirect()->route('events.pro.index')->with($ok ? 'success' : 'error', $message);
private function retired(): RedirectResponse
{
return redirect()->route('events.dashboard')
->with('success', 'Ladill Events is free — paid subscriptions are no longer offered. Ticket payments use Ladill Pay with the standard platform fee.');
}
}