diff --git a/app/Http/Controllers/Api/Service/ProductCategoryController.php b/app/Http/Controllers/Api/Service/ProductCategoryController.php index cafb0a8..8e4f8ac 100644 --- a/app/Http/Controllers/Api/Service/ProductCategoryController.php +++ b/app/Http/Controllers/Api/Service/ProductCategoryController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Api\Service; +use App\Enums\Product\ProductTypeEnums; use App\Http\Controllers\Controller; use App\Http\Resources\Api\Service\ProductCategoryResource; use App\Http\Resources\Api\Service\ServiceResource; @@ -23,7 +24,14 @@ class ProductCategoryController extends Controller * operationId="getProductCategoryList", * tags={"Product Categories"}, * summary="Get list of product categories", - * description="Returns a list of active product categories with their children", + * description="Returns a list of active product categories filtered by type. The `type` parameter is required.", + * @OA\Parameter( + * name="type", + * in="query", + * description="Product type filter (e.g. vps, hosting, cloud, email, ssl, domain, web design, addon)", + * required=true, + * @OA\Schema(type="string") + * ), * @OA\Response( * response=200, * description="Successful operation", @@ -47,12 +55,35 @@ class ProductCategoryController extends Controller * )) * )) * ) + * ), + * @OA\Response( + * response=422, + * description="Missing or invalid type filter" * ) * ) */ public function getCategories(Request $request) { + $type = $request->query('type'); + + if (!$type) { + return response()->json([ + 'error' => true, + 'message' => 'Vui lòng chọn Phân loại sản phẩm', + 'data' => [], + ], 422); + } + + if (!ProductTypeEnums::tryFrom($type)) { + return response()->json([ + 'error' => true, + 'message' => 'Phân loại sản phẩm không hợp lệ', + 'data' => [], + ], 422); + } + $categories = ProductCategories::where('is_active', true) + ->where('type', $type) ->whereNull('parent_id') ->with(['children' => function($query) { $query->where('is_active', true) diff --git a/app/Http/Controllers/Api/Transaction/TransactionController.php b/app/Http/Controllers/Api/Transaction/TransactionController.php index 6ba7d4f..e47d768 100644 --- a/app/Http/Controllers/Api/Transaction/TransactionController.php +++ b/app/Http/Controllers/Api/Transaction/TransactionController.php @@ -8,8 +8,10 @@ use App\Http\Requests\DepositRequest; use App\Http\Services\VNPayService; use App\Jobs\Mail\Customer\DepositSuccessJob; use App\Models\Customer; +use App\Models\Invoice; use App\Models\Log; use App\Models\Transaction; +use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log as FacadesLog; @@ -242,6 +244,57 @@ class TransactionController extends Controller ]); } + /** + * GET /v1/client/payment-history — combined deposit transactions + order invoice payments + */ + public function getClientPaymentHistory(Request $request): JsonResponse + { + $user = $request->user(); + + $deposits = Transaction::where('customer_id', $user->id) + ->orderByDesc('created_at') + ->get() + ->map(fn(Transaction $t) => [ + 'type' => 'deposit', + 'public_code' => $t->public_code, + 'trans' => $t->trans, + 'description' => 'Nạp tiền vào tài khoản', + 'amount' => (float) $t->amount, + 'status' => $t->status, + 'status_label' => TransactionStatus::from((int) $t->status)->label(), + 'reference_id' => null, + 'reference_num'=> null, + 'created_at' => $t->created_at?->toISOString(), + ]); + + $invoicePayments = Invoice::with(['order.orderItems.product']) + ->where('customer_id', $user->id) + ->orderByDesc('created_at') + ->get() + ->map(fn(Invoice $inv) => [ + 'type' => 'order_payment', + 'public_code' => $inv->invoice_number, + 'trans' => null, + 'description' => 'Thanh toán đơn hàng: ' . ($inv->order?->orderItems->first()?->product?->name ?? $inv->order?->order_num), + 'amount' => (float) $inv->total, + 'status' => $inv->status, + 'status_label' => \App\Enums\Invoice\InvoiceStatus::tryFrom((int) $inv->status)?->label() ?? '-', + 'reference_id' => $inv->order?->id, + 'reference_num'=> $inv->order?->order_num, + 'created_at' => $inv->created_at?->toISOString(), + ]); + + $combined = $deposits->concat($invoicePayments) + ->sortByDesc('created_at') + ->values(); + + return response()->json([ + 'error' => false, + 'message' => 'Lấy lịch sử thanh toán thành công', + 'data' => $combined, + ]); + } + public function getByPublicCode(Request $request) { $code = $request->query('code'); diff --git a/routes/api.php b/routes/api.php index 22f8b6c..8f7f62e 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,5 +1,6 @@ group(function () { Route::prefix('administrator')->group(function () { - Route::post('login', [AuthController::class, 'login']); + Route::post('login', [AuthController::class, 'login']); Route::middleware('api.auth:admin')->group(function () { - Route::post('logout', [AuthController::class, 'logout']); + Route::post('logout', [AuthController::class, 'logout']); Route::post('refresh', [AuthController::class, 'refresh']); - Route::get('me', [AuthController::class, 'me']); + Route::get('me', [AuthController::class, 'me']); // Role Permissions Route::prefix('role-permissions')->group(function () { @@ -71,44 +72,45 @@ Route::prefix('v1') }); // Customers (module: customer) - Route::prefix('customers')->group(function () { - Route::get('trash', [CustomerController::class, 'trash'])->middleware('perm:customer.view'); - Route::get('/', [CustomerController::class, 'index'])->middleware('perm:customer.view'); - Route::post('/', [CustomerController::class, 'store'])->middleware('perm:customer.create'); - Route::get('{uuid}', [CustomerController::class, 'show'])->middleware('perm:customer.view'); - Route::put('{uuid}', [CustomerController::class, 'update'])->middleware('perm:customer.edit'); - Route::delete('{uuid}', [CustomerController::class, 'destroy'])->middleware('perm:customer.destroy'); - Route::delete('{uuid}/destroy', [CustomerController::class, 'destroy'])->middleware('perm:customer.destroy'); - Route::post('{uuid}/reset-password', [CustomerController::class, 'resetPassword'])->middleware('perm:customer.edit'); - Route::post('{uuid}/add-credit', [CustomerController::class, 'addCredit'])->middleware('perm:customer.edit'); - Route::get('{uuid}/services', [CustomerController::class, 'getServices'])->middleware('perm:customer.view'); - Route::get('{uuid}/orders', [CustomerController::class, 'getOrders'])->middleware('perm:customer.view'); - Route::get('{uuid}/invoices', [CustomerController::class, 'getInvoices'])->middleware('perm:customer.view'); - Route::get('{uuid}/transactions', [CustomerController::class, 'getTransactions'])->middleware('perm:customer.view'); - Route::get('{uuid}/domains', [CustomerController::class, 'getDomains'])->middleware('perm:customer.view'); - Route::post('{uuid}/restore', [CustomerController::class, 'restore'])->middleware('perm:customer.edit'); - Route::delete('{uuid}/force', [CustomerController::class, 'forceDelete'])->middleware('perm:customer.destroy'); + Route::prefix('customers')->controller(CustomerController::class)->group(function () { + Route::get('trash', 'trash')->middleware('perm:customer.view'); + Route::get('/', 'index')->middleware('perm:customer.view'); + Route::post('/', 'store')->middleware('perm:customer.create'); + Route::get('{uuid}', 'show')->middleware('perm:customer.view'); + Route::put('{uuid}', 'update')->middleware('perm:customer.edit'); + Route::delete('{uuid}', 'destroy')->middleware('perm:customer.destroy'); + Route::delete('{uuid}/destroy', 'destroy')->middleware('perm:customer.destroy'); + Route::post('{uuid}/reset-password', 'resetPassword')->middleware('perm:customer.edit'); + Route::post('{uuid}/add-credit', 'addCredit')->middleware('perm:customer.edit'); + Route::get('{uuid}/services', 'getServices')->middleware('perm:customer.view'); + Route::get('{uuid}/orders', 'getOrders')->middleware('perm:customer.view'); + Route::get('{uuid}/invoices', 'getInvoices')->middleware('perm:customer.view'); + Route::get('{uuid}/transactions', 'getTransactions')->middleware('perm:customer.view'); + Route::get('{uuid}/domains', 'getDomains')->middleware('perm:customer.view'); + Route::post('{uuid}/restore', 'restore')->middleware('perm:customer.edit'); + Route::delete('{uuid}/force', 'forceDelete')->middleware('perm:customer.destroy'); }); // Products (module: product-service) - Route::prefix('products')->group(function () { - Route::get('export', [ProductController::class, 'export'])->middleware('perm:product-service.manager'); - Route::get('/', [ProductController::class, 'index'])->middleware('perm:product-service.view'); - Route::post('/', [ProductController::class, 'store'])->middleware('perm:product-service.create'); - Route::post('import', [ProductController::class, 'import'])->middleware('perm:product-service.create'); + Route::prefix('products')->controller(ProductController::class)->group(function () { + Route::get('export', 'export')->middleware('perm:product-service.manager'); + Route::get('/', 'index')->middleware('perm:product-service.view'); + Route::post('/', 'store')->middleware('perm:product-service.create'); + Route::post('import', 'import')->middleware('perm:product-service.create'); - // OS list for product configuration - must be before {id} routes - Route::get('os', [ProductController::class, 'getOsList'])->middleware('perm:product-service.view'); + Route::controller(ProductController::class)->group(function () { + Route::get('os', 'getOsList')->middleware('perm:product-service.view'); - Route::get('{id}', [ProductController::class, 'show'])->middleware('perm:product-service.view'); - Route::get('{id}/os', [ProductController::class, 'getOs'])->middleware('perm:product-service.view'); - Route::get('{id}/operating-systems', [ProductController::class, 'getOperatingSystems'])->middleware('perm:product-service.view'); - Route::put('{id}', [ProductController::class, 'update'])->middleware('perm:product-service.edit'); - Route::delete('{id}', [ProductController::class, 'destroy'])->middleware('perm:product-service.destroy'); - Route::post('{id}/duplicate', [ProductController::class, 'duplicate'])->middleware('perm:product-service.create'); + Route::get('{id}', 'show')->middleware('perm:product-service.view'); + Route::get('{id}/os', 'getOs')->middleware('perm:product-service.view'); + Route::get('{id}/operating-systems', 'getOperatingSystems')->middleware('perm:product-service.view'); + Route::put('{id}', 'update')->middleware('perm:product-service.edit'); + Route::delete('{id}', 'destroy')->middleware('perm:product-service.destroy'); + Route::post('{id}/duplicate', 'duplicate')->middleware('perm:product-service.create'); + }); }); - // Product Categories / Groups (module: product-service) + Route::prefix('product-categories') ->controller(ProductCategoryController::class) ->as('product-categories.') @@ -120,44 +122,44 @@ Route::prefix('v1') Route::delete('{id}', 'destroy')->middleware('perm:product-service.destroy')->name('destroy'); }); - // Orders (module: order) - Route::prefix('orders')->controller(OrderController::class)->group(function () { - Route::get('/', 'index')->middleware('perm:order.view'); - Route::post('/upload-proof', 'uploadProof')->middleware('perm:order.create'); - Route::post('/', 'store')->middleware('perm:order.create'); - Route::get('{id}', 'show')->middleware('perm:order.view'); - Route::put('{id}', 'update')->middleware('perm:order.edit'); - Route::delete('{id}', 'destroy')->middleware('perm:order.destroy'); - Route::post('{id}/accept', 'accept')->middleware('perm:order.edit'); - Route::post('{id}/cancel', 'cancel')->middleware('perm:order.edit'); + // Orders (module: order) + Route::prefix('orders')->controller(OrderController::class)->group(function () { + Route::get('/', 'index')->middleware('perm:order.view'); + Route::post('/upload-proof', 'uploadProof')->middleware('perm:order.create'); + Route::post('/', 'store')->middleware('perm:order.create'); + Route::get('{id}', 'show')->middleware('perm:order.view'); + Route::put('{id}', 'update')->middleware('perm:order.edit'); + Route::delete('{id}', 'destroy')->middleware('perm:order.destroy'); + Route::post('{id}/accept', 'accept')->middleware('perm:order.edit'); + Route::post('{id}/cancel', 'cancel')->middleware('perm:order.edit'); }); // Invoices (module: invoice) - Route::prefix('invoices')->group(function () { - Route::get('/', [InvoiceController::class, 'index'])->middleware('perm:invoice.view'); - Route::get('/datatable', [InvoiceController::class, 'datatable'])->middleware('perm:invoice.view'); - Route::post('/', [InvoiceController::class, 'store'])->middleware('perm:invoice.create'); - Route::get('{id}', [InvoiceController::class, 'show'])->middleware('perm:invoice.view'); - Route::put('{id}', [InvoiceController::class, 'update'])->middleware('perm:invoice.edit'); - Route::delete('{id}', [InvoiceController::class, 'destroy'])->middleware('perm:invoice.destroy'); - Route::post('{id}/paid', [InvoiceController::class, 'markAsPaid'])->middleware('perm:invoice.edit'); - Route::post('{id}/cancel', [InvoiceController::class, 'cancel'])->middleware('perm:invoice.edit'); + Route::prefix('invoices')->controller(InvoiceController::class)->group(function () { + Route::get('/', 'index')->middleware('perm:invoice.view'); + Route::get('/datatable', 'datatable')->middleware('perm:invoice.view'); + Route::post('/', 'store')->middleware('perm:invoice.create'); + Route::get('{id}', 'show')->middleware('perm:invoice.view'); + Route::put('{id}', 'update')->middleware('perm:invoice.edit'); + Route::delete('{id}', 'destroy')->middleware('perm:invoice.destroy'); + Route::post('{id}/paid', 'markAsPaid')->middleware('perm:invoice.edit'); + Route::post('{id}/cancel', 'cancel')->middleware('perm:invoice.edit'); // Attachments - Route::get('{id}/attachments', [InvoiceController::class, 'listAttachments'])->middleware('perm:invoice.view'); - Route::post('{id}/attachments', [InvoiceController::class, 'uploadAttachment'])->middleware('perm:invoice.edit'); - Route::delete('{id}/attachments/{attachmentId}', [InvoiceController::class, 'deleteAttachment'])->middleware('perm:invoice.edit'); + Route::get('{id}/attachments', 'listAttachments')->middleware('perm:invoice.view'); + Route::post('{id}/attachments', 'uploadAttachment')->middleware('perm:invoice.edit'); + Route::delete('{id}/attachments/{attachmentId}', 'deleteAttachment')->middleware('perm:invoice.edit'); // Send mail notification - Route::post('{id}/send-mail', [InvoiceController::class, 'sendMail'])->middleware('perm:invoice.edit'); + Route::post('{id}/send-mail', 'sendMail')->middleware('perm:invoice.edit'); }); // Payments (module: payment) - Route::prefix('payments')->group(function () { - Route::get('for-select', [PaymentController::class, 'forSelect']); - Route::get('/', [PaymentController::class, 'index'])->middleware('perm:payment.view'); - Route::post('/', [PaymentController::class, 'store'])->middleware('perm:payment.create'); - Route::get('{id}', [PaymentController::class, 'show'])->middleware('perm:payment.view'); - Route::put('{id}', [PaymentController::class, 'update'])->middleware('perm:payment.edit'); - Route::delete('{id}', [PaymentController::class, 'destroy'])->middleware('perm:payment.destroy'); + Route::prefix('payments')->controller(PaymentController::class)->group(function () { + Route::get('for-select', 'forSelect'); + Route::get('/', 'index')->middleware('perm:payment.view'); + Route::post('/', 'store')->middleware('perm:payment.create'); + Route::get('{id}', 'show')->middleware('perm:payment.view'); + Route::put('{id}', 'update')->middleware('perm:payment.edit'); + Route::delete('{id}', 'destroy')->middleware('perm:payment.destroy'); }); // OS Groups & OS Entries (module: module-vcenter) @@ -182,68 +184,68 @@ Route::prefix('v1') }); // VPS (module: module-vcenter) - Route::prefix('vps')->group(function () { - Route::get('/', [VPSController::class, 'index'])->middleware('perm:module-vcenter.view'); - Route::get('{id}', [VPSController::class, 'show'])->middleware('perm:module-vcenter.view'); - Route::put('{id}', [VPSController::class, 'update'])->middleware('perm:module-vcenter.edit'); - Route::post('{id}/power-on', [VPSController::class, 'powerOn'])->middleware('perm:module-vcenter.edit'); - Route::post('{id}/power-off', [VPSController::class, 'powerOff'])->middleware('perm:module-vcenter.edit'); - Route::post('{id}/restart', [VPSController::class, 'restart'])->middleware('perm:module-vcenter.edit'); - Route::get('{id}/console-ticket', [VPSController::class, 'getConsoleTicket'])->middleware('perm:module-vcenter.view'); + Route::prefix('vps')->controller(VPSController::class)->group(function () { + Route::get('/', 'index')->middleware('perm:module-vcenter.view'); + Route::get('{id}', 'show')->middleware('perm:module-vcenter.view'); + Route::put('{id}', 'update')->middleware('perm:module-vcenter.edit'); + Route::post('{id}/power-on', 'powerOn')->middleware('perm:module-vcenter.edit'); + Route::post('{id}/power-off', 'powerOff')->middleware('perm:module-vcenter.edit'); + Route::post('{id}/restart', 'restart')->middleware('perm:module-vcenter.edit'); + Route::get('{id}/console-ticket', 'getConsoleTicket')->middleware('perm:module-vcenter.view'); }); // vCenter (module: module-vcenter) - Route::prefix('vcenter')->group(function () { - Route::get('tree', [VCenterController::class, 'tree'])->middleware('perm:module-vcenter.view'); - Route::get('console-ticket', [VCenterController::class, 'consoleTicket'])->middleware('perm:module-vcenter.view'); - Route::post('/', [VCenterController::class, 'store'])->middleware('perm:module-vcenter.create'); - Route::post('sync', [VCenterController::class, 'sync'])->middleware('perm:module-vcenter.edit'); - Route::put('node/{type}/{id}', [VCenterController::class, 'updateNode'])->middleware('perm:module-vcenter.edit'); - Route::delete('node/{type}/{id}', [VCenterController::class, 'destroyNode'])->middleware('perm:module-vcenter.destroy'); + Route::prefix('vcenter')->controller(VCenterController::class)->group(function () { + Route::get('tree', 'tree')->middleware('perm:module-vcenter.view'); + Route::get('console-ticket', 'consoleTicket')->middleware('perm:module-vcenter.view'); + Route::post('/', 'store')->middleware('perm:module-vcenter.create'); + Route::post('sync', 'sync')->middleware('perm:module-vcenter.edit'); + Route::put('node/{type}/{id}', 'updateNode')->middleware('perm:module-vcenter.edit'); + Route::delete('node/{type}/{id}', 'destroyNode')->middleware('perm:module-vcenter.destroy'); }); // DNS Manager — Domains (module: domain.manager) - Route::prefix('domains')->group(function () { - Route::get('/', [DnsDomainController::class, 'index'])->middleware('perm:domain.manager'); - Route::post('/', [DnsDomainController::class, 'store'])->middleware('perm:domain.manager'); - Route::get('{id}', [DnsDomainController::class, 'show'])->middleware('perm:domain.manager'); - Route::put('{id}', [DnsDomainController::class, 'update'])->middleware('perm:domain.manager'); - Route::delete('{id}', [DnsDomainController::class, 'destroy'])->middleware('perm:domain.manager'); - // DNS Records - Route::get('{id}/dns', [DnsDomainController::class, 'dnsIndex'])->middleware('perm:domain.manager'); - Route::post('{id}/dns', [DnsDomainController::class, 'dnsStore'])->middleware('perm:domain.manager'); - Route::put('{id}/dns/{recordId}', [DnsDomainController::class, 'dnsUpdate'])->middleware('perm:domain.manager'); - Route::delete('{id}/dns/{recordId}', [DnsDomainController::class, 'dnsDestroy'])->middleware('perm:domain.manager'); + Route::prefix('domains')->controller(DnsDomainController::class)->group(function () { + Route::get('/', 'index')->middleware('perm:domain.manager'); + Route::post('/', 'store')->middleware('perm:domain.manager'); + Route::get('{id}', 'show')->middleware('perm:domain.manager'); + Route::put('{id}', 'update')->middleware('perm:domain.manager'); + Route::delete('{id}', 'destroy')->middleware('perm:domain.manager'); + // DNS Records + Route::get('{id}/dns', 'dnsIndex')->middleware('perm:domain.manager'); + Route::post('{id}/dns', 'dnsStore')->middleware('perm:domain.manager'); + Route::put('{id}/dns/{recordId}', 'dnsUpdate')->middleware('perm:domain.manager'); + Route::delete('{id}/dns/{recordId}', 'dnsDestroy')->middleware('perm:domain.manager'); }); // DNS Manager — Servers (module: domain.manager) - Route::prefix('dns-servers')->group(function () { - Route::get('/', [DnsServerController::class, 'index'])->middleware('perm:domain.manager'); - Route::post('/', [DnsServerController::class, 'store'])->middleware('perm:domain.manager'); - Route::get('{id}', [DnsServerController::class, 'show'])->middleware('perm:domain.manager'); - Route::put('{id}', [DnsServerController::class, 'update'])->middleware('perm:domain.manager'); - Route::delete('{id}', [DnsServerController::class, 'destroy'])->middleware('perm:domain.manager'); + Route::prefix('dns-servers')->controller(DnsServerController::class)->group(function () { + Route::get('/', 'index')->middleware('perm:domain.manager'); + Route::post('/', 'store')->middleware('perm:domain.manager'); + Route::get('{id}', 'show')->middleware('perm:domain.manager'); + Route::put('{id}', 'update')->middleware('perm:domain.manager'); + Route::delete('{id}', 'destroy')->middleware('perm:domain.manager'); }); // Staff Online - Route::prefix('staff-online')->group(function () { - Route::get('/', [StaffOnlineController::class, 'index']); - Route::post('ping', [StaffOnlineController::class, 'ping']); + Route::prefix('staff-online')->controller(StaffOnlineController::class)->group(function () { + Route::get('/', 'index'); + Route::post('ping', 'ping'); }); // Queue Monitor (Horizon) - Route::prefix('queue')->group(function () { - Route::get('jobs/recent', [QueueMonitorController::class, 'recent']); - Route::get('jobs/pending', [QueueMonitorController::class, 'pending']); - Route::get('jobs/failed', [QueueMonitorController::class, 'failed']); - Route::get('jobs/metrics', [QueueMonitorController::class, 'metrics']); + Route::prefix('queue')->controller(QueueMonitorController::class)->group(function () { + Route::get('jobs/recent', 'recent'); + Route::get('jobs/pending', 'pending'); + Route::get('jobs/failed', 'failed'); + Route::get('jobs/metrics', 'metrics'); }); // vCenter Manager Power Operations (module: module-vcenter) - Route::prefix('vcenter-manager')->group(function () { - Route::post('vm/power-on', [App\Http\Controllers\admin\VCenterManagerController::class, 'powerOn'])->middleware('perm:module-vcenter.edit'); - Route::post('vm/power-off', [App\Http\Controllers\admin\VCenterManagerController::class, 'powerOff'])->middleware('perm:module-vcenter.edit'); - Route::get('vms/powered-off', [App\Http\Controllers\admin\VCenterManagerController::class, 'getPoweredOffVms'])->middleware('perm:module-vcenter.view'); + Route::prefix('vcenter-manager')->controller(VCenterManagerController::class)->group(function () { + Route::post('vm/power-on', 'powerOn')->middleware('perm:module-vcenter.edit'); + Route::post('vm/power-off', 'powerOff')->middleware('perm:module-vcenter.edit'); + Route::get('vms/powered-off', 'getPoweredOffVms')->middleware('perm:module-vcenter.view'); }); }); }); @@ -322,12 +324,6 @@ Route::prefix('v1') }); }); -// Compression Testing Routes (Development/Testing only) -Route::prefix('v1/system/compression')->middleware(['api'])->group(function () { - Route::get('test', [CompressionTestController::class, 'test'])->name('api.compression.test'); - Route::get('stats', [CompressionTestController::class, 'stats'])->name('api.compression.stats'); -}); - Route::any('{any}', function () { return response()->json([ 'error' => true, diff --git a/routes/client.php b/routes/client.php index 43640a3..1694f38 100644 --- a/routes/client.php +++ b/routes/client.php @@ -34,6 +34,10 @@ Route::prefix('v1')->as('api.')->group(function () { Route::patch('dich-vu/{id}/auto-renew', 'updateClientServiceAutoRenew')->name('services.autoRenew.update'); }); + Route::middleware(['api.auth'])->controller(TransactionController::class)->group(function () { + Route::get('payment-history', 'getClientPaymentHistory')->name('payment-history.list'); + }); + Route::middleware(['api.auth'])->get('get-ticket-console', function (\Illuminate\Http\Request $request, \App\Http\Services\vCenter $serviceVCenter) { $orderNum = (string)$request->query('order_num', ''); if ($orderNum === '') {