Files
ladill-transfer/app/Http/Controllers/WalletTopupController.php
T
isaaccladandClaude Opus 4.8 a0a706093b
Deploy Ladill Transfer / deploy (push) Successful in 48s
Transfer: two-step add-funds modal on insufficient balance
Creating a transfer that the wallet can't cover used to flash a bare error.
Detect the insufficient-balance case and open an in-app two-step modal (billing
explainer -> amount -> Paystack) on the create page instead, with an 'Add funds'
button to top up on demand.

- BillingClient::topup -> POST /api/billing/topup (Transfer already holds its key)
- WalletTopupController + route POST /wallet/topup (user.wallet.topup)
- store() flashes open_topup_modal on TransferWalletErrors::isInsufficientBalance
- service-topup-modal made two-step (uses <x-modal>, plain POST -> checkout)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 07:15:38 +00:00

51 lines
1.8 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Services\Billing\BillingClient;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
/**
* In-app wallet top-up. Posts to the central billing API to start a Paystack
* checkout against the one Ladill wallet, then hands the user to checkout. Backs
* the two-step "Add funds" modal so users never leave for the wallet page when a
* transfer can't be afforded.
*/
class WalletTopupController extends Controller
{
public function store(Request $request, BillingClient $billing): JsonResponse|RedirectResponse
{
$validated = $request->validate([
'amount' => ['required', 'numeric', 'min:5', 'max:5000'],
'return_url' => ['nullable', 'url', 'max:2048'],
]);
$account = ladill_account();
if ($account === null) {
return $request->expectsJson()
? response()->json(['error' => 'Unauthenticated.'], 401)
: redirect()->route('sso.connect');
}
$returnUrl = $validated['return_url'] ?? (string) (url()->previous() ?: route('transfer.transfers.create'));
try {
$checkoutUrl = $billing->topup((string) $account->public_id, (float) $validated['amount'], $returnUrl);
} catch (\Throwable) {
$checkoutUrl = '';
}
if ($checkoutUrl === '') {
return $request->expectsJson()
? response()->json(['error' => 'Unable to start payment. Please try again.'], 422)
: back()->with('error', 'Unable to start payment. Please try again.');
}
return $request->expectsJson()
? response()->json(['checkout_url' => $checkoutUrl])
: redirect()->away($checkoutUrl);
}
}