Two-step add-funds modal instead of wallet redirect on insufficient balance
Deploy Ladill QR Plus / deploy (push) Successful in 40s
Deploy Ladill QR Plus / deploy (push) Successful in 40s
When a user hits an action they can't afford (e.g. creating a QR code with 0/low balance), open an in-app two-step modal instead of bouncing them to the central wallet page. Step 1 explains pay-as-you-go billing + shows the action cost and current balance; step 2 takes an amount and starts a Paystack checkout via the central identity wallet-topup API, returning the user where they were. - service-topup-modal: rebuilt as two-step (billing explainer -> amount/pay) - IdentityClient::walletTopup + WalletTopupController + POST /wallet/topup - balanceGate.openTopup / qrCustomizer.redirectTopup now prefer the modal, falling back to the wallet page only when no modal is wired - qr-codes index + create render the modal and open it on insufficient balance Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
bbef00b2f0
commit
73faa20fff
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\Identity\IdentityClient;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* In-app wallet top-up. Posts to the central identity API to start a Paystack
|
||||
* checkout against the one Ladill wallet, then hands the user to checkout. This
|
||||
* backs the two-step "Add funds" modal so users never leave for the wallet page
|
||||
* when they hit an insufficient-balance action.
|
||||
*/
|
||||
class WalletTopupController extends Controller
|
||||
{
|
||||
public function store(Request $request, IdentityClient $identity): JsonResponse|RedirectResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'amount' => ['required', 'numeric', 'min:5', 'max:5000'],
|
||||
'return_url' => ['nullable', 'url', 'max:2048'],
|
||||
]);
|
||||
|
||||
$returnUrl = $validated['return_url'] ?? (string) (url()->previous() ?: url('/'));
|
||||
|
||||
try {
|
||||
$checkoutUrl = $identity->walletTopup(
|
||||
(string) $request->user()->public_id,
|
||||
(float) $validated['amount'],
|
||||
$returnUrl,
|
||||
);
|
||||
} catch (\Throwable) {
|
||||
$checkoutUrl = '';
|
||||
}
|
||||
|
||||
if ($checkoutUrl === '') {
|
||||
if ($request->expectsJson()) {
|
||||
return response()->json(['error' => 'Unable to start payment. Please try again.'], 422);
|
||||
}
|
||||
|
||||
return back()->with('error', 'Unable to start payment. Please try again.');
|
||||
}
|
||||
|
||||
if ($request->expectsJson()) {
|
||||
return response()->json(['checkout_url' => $checkoutUrl]);
|
||||
}
|
||||
|
||||
return redirect()->away($checkoutUrl);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user