namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use App\Models\User; use App\Models\Service; use App\Models\Order; use App\Models\ApiKey; use App\Services\Order\OrderService; use App\Services\Wallet\WalletService; use Illuminate\Http\Request; use Illuminate\Support\Facades\Validator; use App\Http\Resources\OrderResource; use App\Http\Resources\ServiceResource; class ResellerController extends Controller { protected OrderService $orderService; protected WalletService $walletService; public function __construct(OrderService $orderService, WalletService $walletService) { $this->orderService = $orderService; $this->walletService = $walletService; } /** * Authenticate API request */ protected function authenticate(Request $request): ?User { $apiKey = $request->header('X-API-Key'); if (!$apiKey) { return null; } $key = ApiKey::with('user') ->where('key', $apiKey) ->where('status', 'active') ->first(); if (!$key || ($key->expires_at && $key->expires_at->isPast())) { return null; } // Check IP whitelist if (!empty($key->ip_whitelist) && !in_array($request->ip(), $key->ip_whitelist)) { return null; } // Update last used $key->update(['last_used_at' => now()]); return $key->user; } /** * Get user balance */ public function balance(Request $request) { $user = $this->authenticate($request); if (!$user) { return response()->json([ 'error' => 'Invalid or expired API key', ], 401); } return response()->json([ 'status' => 'success', 'balance' => (float) ($user->wallet->balance ?? 0), 'currency' => config('app.currency', 'USD'), ]); } /** * Get services list */ public function services(Request $request) { $user = $this->authenticate($request); if (!$user) { return response()->json([ 'error' => 'Invalid or expired API key', ], 401); } $services = Service::where('status', 'active') ->where('is_hidden', false) ->with('category') ->orderBy('category_id') ->orderBy('name') ->get(); return ServiceResource::collection($services); } /** * Place order */ public function order(Request $request) { $user = $this->authenticate($request); if (!$user) { return response()->json([ 'error' => 'Invalid or expired API key', ], 401); } // Validate request $validator = Validator::make($request->all(), [ 'service' => 'required|integer|exists:services,id', 'link' => 'required|string|url|max:1000', 'quantity' => 'required|integer|min:1', 'custom_data' => 'nullable|array', ]); if ($validator->fails()) { return response()->json([ 'error' => 'Validation failed', 'messages' => $validator->errors(), ], 422); } $service = Service::findOrFail($request->service); // Check service status if ($service->status !== 'active') { return response()->json([ 'error' => 'Service is not available', ], 400); } // Check quantity limits if ($request->quantity < $service->min_order) { return response()->json([ 'error' => "Minimum quantity is {$service->min_order}", ], 400); } if ($service->max_order && $request->quantity > $service->max_order) { return response()->json([ 'error' => "Maximum quantity is {$service->max_order}", ], 400); } // Calculate price $price = $service->price * $request->quantity; // Check balance if (!$user->hasSufficientBalance($price)) { return response()->json([ 'error' => 'Insufficient balance', 'balance' => (float) ($user->wallet->balance ?? 0), 'required' => $price, ], 400); } try { // Create order $order = $this->orderService->createOrder($user, [ 'service_id' => $service->id, 'link' => $request->link, 'quantity' => $request->quantity, 'custom_fields' => $request->custom_data, 'order_type' => 'api', ]); // Process payment $this->walletService->processOrderPayment($user, $order); return response()->json([ 'status' => 'success', 'order_id' => $order->order_id, 'service' => $service->name, 'quantity' => $order->quantity, 'price' => (float) $order->price, 'balance' => (float) ($user->wallet->balance ?? 0), 'created_at' => $order->created_at->toIso8601String(), ]); } catch (\Exception $e) { return response()->json([ 'error' => 'Failed to create order: ' . $e->getMessage(), ], 500); } } /** * Get order status */ public function status(Request $request, $orderId) { $user = $this->authenticate($request); if (!$user) { return response()->json([ 'error' => 'Invalid or expired API key', ], 401); } $order = Order::where('order_id', $orderId) ->where('user_id', $user->id) ->first(); if (!$order) { return response()->json([ 'error' => 'Order not found', ], 404); } return new OrderResource($order); } /** * Get multiple orders status */ public function multiStatus(Request $request) { $user = $this->authenticate($request); if (!$user) { return response()->json([ 'error' => 'Invalid or expired API key', ], 401); } $validator = Validator::make($request->all(), [ 'order_ids' => 'required|array', 'order_ids.*' => 'string', ]); if ($validator->fails()) { return response()->json([ 'error' => 'Validation failed', 'messages' => $validator->errors(), ], 422); } $orders = Order::whereIn('order_id', $request->order_ids) ->where('user_id', $user->id) ->get() ->keyBy('order_id'); $response = []; foreach ($request->order_ids as $orderId) { if (isset($orders[$orderId])) { $response[$orderId] = new OrderResource($orders[$orderId]); } else { $response[$orderId] = ['error' => 'Order not found']; } } return response()->json($response); } /** * Create API key for user */ public function createApiKey(Request $request) { $user = auth()->user(); $validator = Validator::make($request->all(), [ 'name' => 'required|string|max:255', 'permissions' => 'required|array', 'permissions.*' => 'in:read,write', 'ip_whitelist' => 'nullable|array', 'ip_whitelist.*' => 'ip', 'expires_at' => 'nullable|date|after:now', ]); if ($validator->fails()) { return response()->json([ 'error' => 'Validation failed', 'messages' => $validator->errors(), ], 422); } $apiKey = $user->apiKeys()->create([ 'name' => $request->name, 'key' => $this->generateApiKey(), 'secret' => $this->generateApiSecret(), 'permissions' => $request->permissions, 'ip_whitelist' => $request->ip_whitelist, 'expires_at' => $request->expires_at, 'status' => 'active', ]); return response()->json([ 'status' => 'success', 'api_key' => [ 'id' => $apiKey->id, 'name' => $apiKey->name, 'key' => $apiKey->key, 'secret' => $apiKey->secret, 'permissions' => $apiKey->permissions, 'ip_whitelist' => $apiKey->ip_whitelist, 'expires_at' => $apiKey->expires_at?->toIso8601String(), ], ]); } /** * Generate unique API key */ protected function generateApiKey(): string { do { $key = 'RGSMM-' . strtoupper(bin2hex(random_bytes(16))); } while (ApiKey::where('key', $key)->exists()); return $key; } /** * Generate API secret */ protected function generateApiSecret(): string { return bin2hex(random_bytes(32)); } }