validate([ 'plan_id' => 'required|exists:plans,id', 'provider' => 'nullable|string|in:stripe,lemon_squeezy,polar,oxapay,crypto,activation_key', 'options' => 'nullable|array', ]); $user = $request->user(); $plan = Plan::findOrFail($validated['plan_id']); $provider = $validated['provider'] ?? null; $options = $validated['options'] ?? []; $result = $this->orchestrator->createCheckoutSession($user, $plan, $provider, $options); return response()->json([ 'success' => true, 'data' => $result, ]); } catch (ValidationException $e) { return response()->json([ 'success' => false, 'errors' => $e->errors(), ], 422); } catch (\Exception $e) { return response()->json([ 'success' => false, 'error' => $e->getMessage(), ], 500); } } /** * Create a new subscription */ public function createSubscription(Request $request): JsonResponse { try { $validated = $request->validate([ 'plan_id' => 'required|exists:plans,id', 'provider' => 'nullable|string|in:stripe,lemon_squeezy,polar', 'options' => 'nullable|array', ]); $user = $request->user(); $plan = Plan::findOrFail($validated['plan_id']); $provider = $validated['provider'] ?? null; $options = $validated['options'] ?? []; // Only recurring providers can create subscriptions if (! $plan->monthly_billing) { return response()->json([ 'success' => false, 'error' => 'This plan does not support recurring subscriptions. Use checkout instead.', ], 400); } $result = $this->orchestrator->createSubscription($user, $plan, $provider, $options); return response()->json([ 'success' => true, 'data' => $result, ]); } catch (ValidationException $e) { return response()->json([ 'success' => false, 'errors' => $e->errors(), ], 422); } catch (\Exception $e) { return response()->json([ 'success' => false, 'error' => $e->getMessage(), ], 500); } } /** * Get available payment methods for a plan */ public function getPaymentMethods(Request $request): JsonResponse { try { $validated = $request->validate([ 'plan_id' => 'required|exists:plans,id', ]); $plan = Plan::findOrFail($validated['plan_id']); $providers = $this->orchestrator->getActiveProvidersForPlan($plan); $methods = $providers->map(function ($provider) use ($plan) { return [ 'provider' => $provider->getName(), 'name' => $provider->getName(), 'supports_recurring' => $provider->supportsRecurring(), 'supports_one_time' => $provider->supportsOneTime(), 'supported_currencies' => $provider->getSupportedCurrencies(), 'fees' => $provider->calculateFees($plan->price), 'active' => $provider->isActive(), ]; })->values()->toArray(); return response()->json([ 'success' => true, 'data' => [ 'plan' => [ 'id' => $plan->id, 'name' => $plan->name, 'price' => $plan->price, 'monthly_billing' => $plan->monthly_billing, ], 'payment_methods' => $methods, ], ]); } catch (ValidationException $e) { return response()->json([ 'success' => false, 'errors' => $e->errors(), ], 422); } catch (\Exception $e) { return response()->json([ 'success' => false, 'error' => $e->getMessage(), ], 500); } } /** * Get user's payment/subscription history */ public function getHistory(Request $request): JsonResponse { try { $validated = $request->validate([ 'limit' => 'nullable|integer|min:1|max:100', 'offset' => 'nullable|integer|min:0', 'filters' => 'nullable|array', ]); $user = $request->user(); $limit = $validated['limit'] ?? 20; $filters = $validated['filters'] ?? []; $history = $this->orchestrator->getTransactionHistory($user, $filters); // Apply pagination $offset = $validated['offset'] ?? 0; $paginatedHistory = array_slice($history, $offset, $limit); return response()->json([ 'success' => true, 'data' => [ 'transactions' => $paginatedHistory, 'pagination' => [ 'total' => count($history), 'limit' => $limit, 'offset' => $offset, 'has_more' => $offset + $limit < count($history), ], ], ]); } catch (ValidationException $e) { return response()->json([ 'success' => false, 'errors' => $e->errors(), ], 422); } catch (\Exception $e) { return response()->json([ 'success' => false, 'error' => $e->getMessage(), ], 500); } } /** * Handle successful payment redirect */ public function success(Request $request): JsonResponse { return response()->json([ 'status' => 'success', 'message' => 'Payment completed successfully', ]); } /** * Handle cancelled payment redirect */ public function cancel(Request $request): JsonResponse { return response()->json([ 'status' => 'cancelled', 'message' => 'Payment was cancelled', ]); } /** * Handle payment provider webhooks */ public function webhook(Request $request, string $provider): JsonResponse { try { $result = $this->orchestrator->processWebhook($provider, $request); return response()->json([ 'status' => 'processed', 'result' => $result, ]); } catch (\Exception $e) { return response()->json([ 'status' => 'error', 'message' => $e->getMessage(), ], 400); } } }