From 151c15cb859ca2a76aedf260b8c6b4324dd2184f Mon Sep 17 00:00:00 2001 From: isaacclad Date: Mon, 8 Jun 2026 17:13:19 +0000 Subject: [PATCH] Return insufficient_wallet when Transfer billing fails for zero balance. Expose a stable error_code on chunked upload finalize so webmail can prompt wallet top-up instead of a generic upload failure. Co-authored-by: Cursor --- .../Api/ChunkedUploadController.php | 8 +++++++- app/Support/TransferWalletErrors.php | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 app/Support/TransferWalletErrors.php diff --git a/app/Http/Controllers/Api/ChunkedUploadController.php b/app/Http/Controllers/Api/ChunkedUploadController.php index edc90c9..41297e7 100644 --- a/app/Http/Controllers/Api/ChunkedUploadController.php +++ b/app/Http/Controllers/Api/ChunkedUploadController.php @@ -6,6 +6,7 @@ use App\Http\Controllers\Controller; use App\Services\Identity\MailboxUserResolver; use App\Services\Transfer\TransferService; use App\Services\Upload\ChunkedUploadService; +use App\Support\TransferWalletErrors; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Str; @@ -128,7 +129,12 @@ class ChunkedUploadController extends Controller 'retention_days' => $retentionDays, ], [$uploadedFile]); } catch (RuntimeException $e) { - return response()->json(['message' => $e->getMessage()], 422); + $payload = ['message' => $e->getMessage()]; + if (TransferWalletErrors::isInsufficientBalance($e)) { + $payload['error_code'] = TransferWalletErrors::CODE_INSUFFICIENT_WALLET; + } + + return response()->json($payload, 422); } finally { $this->uploads->cleanup($validated['upload_id']); } diff --git a/app/Support/TransferWalletErrors.php b/app/Support/TransferWalletErrors.php new file mode 100644 index 0000000..a0fecc1 --- /dev/null +++ b/app/Support/TransferWalletErrors.php @@ -0,0 +1,18 @@ +getMessage()); + + return str_contains($message, 'insufficient wallet') + || str_contains($message, 'top up'); + } +}