as('api.') ->group(function () { // Auth Route::prefix('client') ->as('client.') ->group(function () { Route::controller(ClientController::class)->group(function () { Route::post('login', 'login')->name('login'); Route::post('register', 'register')->name('register'); Route::post('verify-email', 'verifyEmail')->name('verify-email'); Route::post('resend-verify', 'resendVerifyCode')->name('resend-verify'); Route::post('refresh', 'refresh')->name('refresh'); Route::post('forgot-password', 'forgotPassword')->name('forgot-password'); Route::post('impersonate/exchange', 'impersonateExchange')->name('impersonate.exchange'); Route::group(['middleware' => ['api.auth']], function () { Route::get('me', 'me')->name('me'); Route::post('logout', 'logout')->name('logout'); Route::put('update', 'update')->name('update'); Route::put('change-password', 'changePassword')->name('change-password'); }); }); Route::middleware(['api.auth']) ->controller(OrderControllerRefactor::class) ->group(function () { Route::get('orders', 'getClientOrders')->name('orders.list'); Route::get('orders/num/{orderNum}', 'getClientOrderDetailByOrderNum')->name('orders.detailByOrderNum'); Route::get('orders/{id}', 'getClientOrderDetail')->name('orders.detail'); Route::post('orders/{id}/retry', 'retryOrderProvisioning')->name('orders.retry'); Route::get('invoices', 'getClientInvoices')->name('invoices.list'); Route::get('invoices/number/{invoiceNumber}', 'getClientInvoiceDetailByNumber')->name( 'invoices.detailByNumber', ); Route::post('invoices/number/{invoiceNumber}/pay', 'payClientInvoiceByNumber')->name( 'invoices.payByNumber', ); Route::get('invoices/order/{orderNum}', 'getClientInvoiceDetailByOrderNum')->name( 'invoices.detailByOrderNum', ); Route::get('invoices/order/{orderNum}/pdf', 'downloadInvoicePdfByOrderNum')->name( 'invoices.pdfByOrderNum', ); Route::get('invoices/{id}', 'getClientInvoiceDetail')->name('invoices.detail'); Route::get('dich-vu', 'getClientServices')->name('services.list'); Route::patch('dich-vu/{id}/auto-renew', 'updateClientServiceAutoRenew')->name( 'services.autoRenew.update', ); Route::post('dich-vu/{id}/renew', 'renewService')->name('services.renew'); }); Route::middleware(['api.auth']) ->prefix('client-service/domains') ->controller(ClientDomainController::class) ->as('client-service.domains.') ->group(function () { Route::get('/', 'index')->name('list'); Route::get('{domainId}', 'show')->name('detail'); Route::get('{domainId}/records', 'show')->name('records'); Route::post('{domainId}/records', 'storeRecord')->name('records.store'); Route::put('{domainId}/records/{recordId}', 'updateRecord')->name('records.update'); Route::delete('{domainId}/records/{recordId}', 'destroyRecord')->name('records.destroy'); }); Route::middleware(['api.auth']) ->prefix('client-service') ->controller(ClientServiceController::class) ->as('client-service.') ->group(function () { Route::get('vps', 'indexVps')->name('vps.list'); Route::get('hosting', 'indexHosting')->name('hosting.list'); Route::get('web-design', 'indexWebDesign')->name('web-design.list'); Route::get('{uuid}', 'getDetail')->name('detail'); Route::get('{uuid}/console-ticket', 'getConsoleTicket')->name('console-ticket'); Route::get('{uuid}/available-os', 'getAvailableOs')->name('available-os'); Route::post('{uuid}/rebuild', 'rebuild')->name('rebuild'); Route::patch('{uuid}/auto-renew', 'updateAutoRenew')->name('auto-renew.update'); }); Route::middleware(['api.auth']) ->get('get-ticket-console', [ClientServiceController::class, 'getTicketByOrderNum']) ->name('console-ticket'); Route::middleware(['api.auth']) ->prefix('service') ->controller(ServiceController::class) ->as('service.') ->group(function () { Route::get('/', 'getService')->name('list'); Route::get('{uuid}', 'getDetailServiceCustomer')->name('detail'); }); Route::middleware(['api.auth']) ->controller(TransactionController::class) ->group(function () { Route::get('payment-history', 'getClientPaymentHistory')->name('payment-history.list'); }); Route::middleware(['api.auth']) ->prefix('notifications') ->controller(NotificationController::class) ->group(function () { Route::get('/', fn () => app(NotificationController::class)->index(request(), 'client')); Route::patch('{id}/read', fn ($id) => app(NotificationController::class)->markRead(request(), 'client', (int) $id)); Route::patch('read-all', fn () => app(NotificationController::class)->markAllRead(request(), 'client')); }); Route::middleware(['api.auth']) ->prefix('tickets') ->controller(ClientTicketController::class) ->as('tickets.') ->group(function () { Route::get('/', 'index')->name('index'); Route::post('/', 'store')->name('store'); Route::get('{ticket_num}', 'show')->name('show'); Route::post('{ticket_num}/reply', 'reply')->middleware('throttle:10,1')->name('reply'); Route::patch('{ticket_num}/close', 'close')->name('close'); }); // Domain Orders (auth required) Route::middleware(['api.auth']) ->prefix('domain-orders') ->controller(ClientDomainOrderController::class) ->as('domain-orders.') ->group(function () { Route::post('/', 'store')->name('store'); }); }); // Services (Products) - Public & Protected Routes Route::prefix('services') ->as('services.') ->group(function () { Route::controller(ServiceController::class)->group(function () { Route::get('get-list', 'getService')->name('getList'); Route::get('{product:slug}', 'getDetailService')->name('detail'); }); }); Route::middleware(['api.auth']) ->prefix('orders') ->as('orders.') ->group(function () { Route::controller(OrderControllerRefactor::class)->group(function () { Route::get('/', 'getList')->name('list'); Route::get('check-server-name', 'checkServerName')->name('check-server-name'); Route::post('/', 'storeOrder')->name('store'); Route::post('{id}/pay', 'payOrder')->name('pay'); }); }); Route::prefix('setting') ->as('setting.') ->group(function () { Route::controller(SettingController::class)->group(function () { Route::get('/', 'getSetting')->name('get'); Route::get('email', 'getEmailSetting')->name('email'); }); }); // Public bank list for deposit form Route::get('banks', [ClientBankController::class, 'index'])->name('banks.list'); Route::prefix('post-categories') ->controller(ClientPostCategoryController::class) ->as('client.docs.categories.') ->group(function () { Route::get('/', 'index')->name('index'); }); Route::prefix('posts') ->controller(ClientPostController::class) ->as('client.docs.posts.') ->group(function () { Route::get('/', 'index')->name('index'); Route::get('featured', 'featured')->name('featured'); Route::get('{slug}', 'show')->name('show'); }); // Domain Pricing - Public Routes (no auth required) Route::prefix('domain-pricing') ->as('domain-pricing.') ->controller(DomainPricingController::class) ->group(function () { Route::get('/', 'index')->name('index'); }); // iNET Domain Tools - Public Routes (no auth required) Route::prefix('inet-domain') ->as('inet-domain.') ->controller(InetDomainController::class) ->group(function () { Route::get('whois/{domain}', 'whois')->name('whois'); Route::get('check-available', 'checkAvailable')->name('check-available'); Route::post('bulk-check-available', 'bulkCheckAvailable')->name('bulk-check-available'); Route::post('ai-suggest', 'aiSuggest')->name('ai-suggest'); Route::get('suffixes', 'suffixes')->name('suffixes'); }); // Product Categories - Public Routes (no auth required) Route::prefix('group') ->as('product-categories.') ->group(function () { Route::controller(ProductCategoryController::class)->group(function () { Route::get('get-list', 'getCategories')->name('getList'); Route::get('{product_categories:slug}', 'getDetailCategory')->name('detail'); Route::get('{parentSlug}/{childSlug}', 'getChildCategoryWithParent')->name('childWithParent'); }); }); // Addons - Get available addons for a product Route::prefix('products') ->as('products.') ->group(function () { Route::get('{productId}/addons', [ServiceController::class, 'getProductAddons'])->name('addons'); }); Route::middleware(['api.auth']) ->prefix('transaction') ->as('transaction.') ->group(function () { Route::controller(TransactionController::class)->group(function () { Route::get('get-list', 'getTransactions')->name('getList'); Route::post('pay', 'handle')->name('pay'); Route::get('verify', 'verifyPayment')->name('verify'); Route::get('detail-by-code', 'getByPublicCode')->name('detailByCode'); }); Route::get('manual-deposit/pending', [ManualDepositController::class, 'pending'])->name('manualDeposit.pending'); Route::post('manual-deposit/prepare', [ManualDepositController::class, 'prepare'])->name('manualDeposit.prepare'); Route::post('manual-deposit/confirm', [ManualDepositController::class, 'confirm'])->name('manualDeposit.confirm'); Route::delete('manual-deposit/{uuid}/cancel', [ManualDepositController::class, 'cancel'])->name('manualDeposit.cancel'); Route::post('manual-deposit/upload-proof', [ManualDepositController::class, 'uploadProof'])->name('manualDeposit.uploadProof'); }); }); Route::get('v1/payment/vnpay/return', [TransactionController::class, 'returnCallback']); Route::prefix('v1/system') ->middleware(['api.auth']) ->group(function () { // VM power & network operations Route::controller(VmController::class)->group(function () { Route::get('vm-power-state', 'powerState')->name('vm.power-state'); Route::post('vm-power-on', 'powerOn')->name('vm.power-on'); Route::post('vm-power-off', 'powerOff')->name('vm.power-off'); Route::post('vm-change-ip', 'changeIp')->name('vm.change-ip'); Route::post('vm-change-port', 'changePort')->name('vm.change-port'); Route::post('vm-change-password', 'changePassword')->name('vm.change-password'); Route::get('get-ticket-console', 'consoleTicket')->name('vm.console-ticket'); Route::post('vm-restart', 'restart')->name('vm.restart'); }); // VM Snapshot operations Route::controller(SnapshotController::class)->group(function () { Route::get('vm-snapshots', 'index')->name('vm.snapshots'); Route::post('vm-create-snapshot', 'store')->name('vm.create-snapshot'); Route::post('vm-revert-snapshot', 'revert')->name('vm.revert-snapshot'); Route::post('vm-delete-snapshot', 'destroy')->name('vm.delete-snapshot'); }); // VM Rebuild & Addon operations Route::controller(VmRebuildController::class)->group(function () { Route::get('vm-rebuild-options', 'options')->name('vm.rebuild-options'); Route::post('vm-rebuild', 'rebuild')->name('vm.rebuild'); Route::get('vm-addon-options', 'addonOptions')->name('vm.addon-options'); Route::post('vm-upgrade-addons', 'upgradeAddons')->name('vm.upgrade-addons'); }); }); Route::any('{any}', function () { return response()->json( [ 'error' => true, 'status' => 404, 'message' => 'API Route not found', ], 404, ); })->where('any', '^v1/.*');