Files
ladill-meet/app/Services/Billing/BillingClient.php
T
isaaccladandCursor 965fb992e9
Deploy Ladill Meet / deploy (push) Failing after 7s
Initial Ladill Meet release.
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>
2026-06-30 23:35:29 +00:00

65 lines
2.0 KiB
PHP

<?php
namespace App\Services\Billing;
use Illuminate\Support\Facades\Http;
/**
* Client for the platform Billing HTTP API — the one UserWallet lives on the
* platform; CRM only consumes it. Amounts are integer minor units; the user is
* identified by public_id. Authenticates with the per-consumer config('billing.api_key').
*/
class BillingClient
{
private function base(): string
{
return rtrim((string) config('billing.api_url'), '/');
}
private function token(): string
{
return (string) (config('billing.api_key') ?? '');
}
public function balanceMinor(string $publicId): int
{
$res = Http::withToken($this->token())->acceptJson()->timeout(8)
->get($this->base().'/balance', ['user' => $publicId]);
$res->throw();
return (int) ($res->json('balance_minor') ?? 0);
}
public function canAfford(string $publicId, int $amountMinor): bool
{
$res = Http::withToken($this->token())->acceptJson()->timeout(8)
->get($this->base().'/can-afford', ['user' => $publicId, 'amount_minor' => $amountMinor]);
$res->throw();
return (bool) ($res->json('affordable') ?? false);
}
/**
* Debit the wallet. Returns true on success, false on insufficient balance
* (HTTP 402). Idempotent by $reference.
*/
public function debit(string $publicId, int $amountMinor, string $source, string $reference, ?string $description = null): bool
{
$res = Http::withToken($this->token())->acceptJson()->timeout(10)->post($this->base().'/debit', array_filter([
'user' => $publicId,
'amount_minor' => $amountMinor,
'service' => (string) config('billing.service', 'crm'),
'source' => $source,
'reference' => $reference,
'description' => $description,
], static fn ($v) => $v !== null));
if ($res->status() === 402) {
return false;
}
$res->throw();
return true;
}
}