Initial Ladill Meet release.
Deploy Ladill Meet / deploy (push) Failing after 7s

Phases 0–18: core meetings, webinar, breakouts, team chat, live streaming, town hall, billing, and Ladill Mail calendar wiring.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-06-30 23:35:29 +00:00
co-authored by Cursor
commit 965fb992e9
319 changed files with 30322 additions and 0 deletions
@@ -0,0 +1,76 @@
<?php
namespace App\Services\Billing;
use App\Models\CrmPurchase;
use Illuminate\Support\Str;
class OneTimePurchaseService
{
public function __construct(private readonly BillingClient $billing)
{
}
/** @return array<string, mixed>|null */
public function product(string $productKey): ?array
{
$product = config('crm_products.'.$productKey);
return is_array($product) ? $product : null;
}
public function hasPurchased(string $ownerRef, string $productKey): bool
{
return CrmPurchase::has($ownerRef, $productKey);
}
public function priceMinor(string $productKey): int
{
return (int) ($this->product($productKey)['price_minor'] ?? 0);
}
public function purchase(string $ownerRef, string $productKey): bool
{
if ($this->hasPurchased($ownerRef, $productKey)) {
return true;
}
$product = $this->product($productKey);
if (! $product) {
return false;
}
$costMinor = (int) ($product['price_minor'] ?? 0);
if ($costMinor > 0) {
try {
if (! $this->billing->canAfford($ownerRef, $costMinor)) {
return false;
}
$charged = $this->billing->debit(
$ownerRef,
$costMinor,
'purchase',
'crm-purchase-'.$productKey.'-'.$ownerRef,
'CRM: '.($product['name'] ?? $productKey),
);
if (! $charged) {
return false;
}
} catch (\Throwable) {
return false;
}
}
CrmPurchase::create([
'owner_ref' => $ownerRef,
'product_key' => $productKey,
'cost_minor' => $costMinor,
'purchased_at' => now(),
]);
return true;
}
}