4e4ebc567a
BillingTopupService кредитует tenants.balance_rub (bcmath) и пишет append-only строку balance_transactions(type='topup'). BillingController + route POST /api/billing/topup под [auth:sanctum, tenant]. MVP-stub: без платёжного шлюза (ЮKassa — post-Б-1). Sprint 2 Plan C, audit E1 (backend). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
61 lines
2.2 KiB
PHP
61 lines
2.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\User;
|
|
use App\Services\Billing\BillingTopupService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
/**
|
|
* Биллинг тенанта — кошелёк, транзакции, счета, пополнение (audit E1/E3).
|
|
*
|
|
* Все эндпоинты под middleware [auth:sanctum, tenant] (RLS-контекст).
|
|
* Отдельно от TenantChargesController (lead_charges ledger) и
|
|
* AdminBillingController (SaaS-уровневые агрегаты).
|
|
*
|
|
* E1: POST /api/billing/topup — MVP-stub пополнения (без платёжного шлюза).
|
|
* E3: GET wallet/transactions/invoices — данные для BillingView Overview.
|
|
*/
|
|
class BillingController extends Controller
|
|
{
|
|
public function __construct(
|
|
private readonly BillingTopupService $topupService,
|
|
) {}
|
|
|
|
/**
|
|
* POST /api/billing/topup — пополнить рублёвый баланс.
|
|
*
|
|
* MVP-stub: кредитует баланс немедленно (без ЮKassa — реальная оплата
|
|
* post-Б-1). Записывает append-only строку balance_transactions(topup).
|
|
*/
|
|
public function topup(Request $request): JsonResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'amount_rub' => ['required', 'numeric', 'min:100', 'max:1000000', 'decimal:0,2'],
|
|
]);
|
|
|
|
/** @var User $user */
|
|
$user = $request->user();
|
|
|
|
// Нормализуем в DECIMAL-строку scale 2 для bcmath (НЕ float).
|
|
$amountRub = bcadd((string) $validated['amount_rub'], '0', 2);
|
|
|
|
$tx = $this->topupService->topup((int) $user->tenant_id, $amountRub, (int) $user->id);
|
|
|
|
return response()->json([
|
|
'transaction' => [
|
|
'id' => $tx->id,
|
|
'type' => $tx->type,
|
|
'amount_rub' => $tx->amount_rub,
|
|
'balance_rub_after' => $tx->balance_rub_after,
|
|
'created_at' => $tx->created_at,
|
|
],
|
|
'balance_rub' => $tx->balance_rub_after,
|
|
], 201);
|
|
}
|
|
}
|