Files
ladill-link/app/Services/Link/LinkBillingService.php
T
isaaccladandCursor d9c91ad7d8 Add Ladill Link URL shortener on ladl.link.
Management UI at link.ladill.com with GHS 0.05 per link wallet billing,
click analytics, and legacy fallback to ladill.com/q for QR ecosystem codes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-27 10:58:41 +00:00

72 lines
2.2 KiB
PHP

<?php
namespace App\Services\Link;
use App\Models\LinkTransaction;
use App\Models\LinkWallet;
use App\Models\ShortLink;
use App\Models\User;
use App\Services\Billing\BillingClient;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use RuntimeException;
class LinkBillingService
{
public function __construct(
private BillingClient $billing,
) {}
public function balanceCedis(User $user): float
{
return $this->billing->balanceMinor($user->public_id) / 100;
}
public function canCreate(User $user): bool
{
$priceMinor = (int) round(LinkWallet::pricePerLink() * 100);
return $this->billing->canAfford($user->public_id, $priceMinor);
}
public function debitForLinkCreation(LinkWallet $wallet, ShortLink $link): LinkTransaction
{
$price = LinkWallet::pricePerLink();
$priceMinor = (int) round($price * 100);
$user = $wallet->user;
$reference = 'LINK-DEBIT-'.strtoupper(Str::random(12));
return DB::transaction(function () use ($wallet, $user, $link, $price, $priceMinor, $reference) {
$ok = $this->billing->debit(
$user->public_id,
$priceMinor,
'link',
'link_create',
$reference,
$link->id,
sprintf('Created short link: %s', $link->label ?: $link->slug),
);
if (! $ok) {
throw new RuntimeException('Insufficient wallet balance.');
}
$wallet->increment('links_total');
$balanceAfter = $this->billing->balanceMinor($user->public_id) / 100;
return LinkTransaction::create([
'user_id' => $wallet->user_id,
'link_wallet_id' => $wallet->id,
'short_link_id' => $link->id,
'type' => LinkTransaction::TYPE_DEBIT,
'amount_ghs' => round($price, 4),
'balance_after_ghs' => $balanceAfter,
'reference' => $reference,
'status' => 'completed',
'description' => sprintf('Created short link: %s', $link->label ?: $link->slug),
'metadata' => ['short_link_id' => $link->id],
]);
});
}
}