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], ]); }); } }