123 lines
3.7 KiB
PHP
123 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\CryptoPayment;
|
|
use App\Services\DepositService;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
class DepositController extends Controller
|
|
{
|
|
public function __construct(private readonly DepositService $deposits)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* GET /wallet/deposits/currencies — returns enabled currencies and limits (Live from API + Admin config)
|
|
*/
|
|
public function currencies(Request $request)
|
|
{
|
|
return response()->json($this->deposits->currenciesForUser(), 200);
|
|
}
|
|
|
|
/**
|
|
* POST /wallet/deposits — start a deposit via NOWPayments
|
|
* Body: { currency: string, amount: number|string }
|
|
*/
|
|
public function create(Request $request)
|
|
{
|
|
$user = Auth::user();
|
|
abort_unless($user, 403);
|
|
|
|
$data = $request->validate([
|
|
'currency' => ['required','string','max:32'],
|
|
'amount' => ['required','numeric','min:0.00000001'], // USD/BTX in MVP
|
|
]);
|
|
|
|
$res = $this->deposits->startDeposit($user, strtoupper($data['currency']), (float) $data['amount']);
|
|
if (!$res || isset($res['error'])) {
|
|
$err = $res['error'] ?? 'unknown_error';
|
|
$payload = ['message' => $err];
|
|
if ($err === 'amount_out_of_bounds') {
|
|
$payload['min_usd'] = $res['min_usd'] ?? null;
|
|
$payload['max_usd'] = $res['max_usd'] ?? null;
|
|
}
|
|
return response()->json($payload, 422);
|
|
}
|
|
|
|
return response()->json($res, 201);
|
|
}
|
|
|
|
/**
|
|
* GET /wallet/deposits/history — get user's payment history
|
|
*/
|
|
public function history(Request $request)
|
|
{
|
|
$user = Auth::user();
|
|
abort_unless($user, 403);
|
|
|
|
$limit = min(50, max(1, (int) $request->query('limit', 10)));
|
|
$history = $this->deposits->getUserHistory($user, $limit);
|
|
|
|
return response()->json(['data' => $history], 200);
|
|
}
|
|
|
|
/**
|
|
* DELETE /wallet/deposits/{order_id} — cancel a pending deposit
|
|
*/
|
|
public function cancel(string $orderId)
|
|
{
|
|
$user = Auth::user();
|
|
abort_unless($user, 403);
|
|
|
|
$cp = CryptoPayment::query()
|
|
->where('user_id', $user->id)
|
|
->where('order_id', $orderId)
|
|
->first();
|
|
|
|
if (!$cp) {
|
|
return response()->json(['message' => 'Not found'], 404);
|
|
}
|
|
|
|
// Only allow cancellation of pending deposits
|
|
if (!in_array($cp->status, ['waiting', 'new', 'confirming'])) {
|
|
return response()->json(['message' => 'This deposit can no longer be canceled.'], 422);
|
|
}
|
|
|
|
$cp->status = 'canceled';
|
|
$cp->save();
|
|
|
|
return response()->json(['message' => 'Deposit canceled.'], 200);
|
|
}
|
|
|
|
/**
|
|
* GET /wallet/deposits/{order_id} — optional polling endpoint to see current status
|
|
*/
|
|
public function show(string $orderId)
|
|
{
|
|
$user = Auth::user();
|
|
abort_unless($user, 403);
|
|
|
|
$cp = CryptoPayment::query()
|
|
->where('user_id', $user->id)
|
|
->where('order_id', $orderId)
|
|
->first();
|
|
|
|
if (!$cp) {
|
|
return response()->json(['message' => 'Not found'], 404);
|
|
}
|
|
|
|
return response()->json([
|
|
'order_id' => $cp->order_id,
|
|
'invoice_id' => $cp->invoice_id,
|
|
'payment_id' => $cp->payment_id,
|
|
'status' => $cp->status,
|
|
'pay_currency' => $cp->pay_currency,
|
|
'price_amount' => (string) $cp->price_amount,
|
|
'credited_btx' => $cp->credited_btx !== null ? (string) $cp->credited_btx : null,
|
|
'credited_at' => $cp->credited_at?->toIso8601String(),
|
|
], 200);
|
|
}
|
|
}
|