info('🚀 Starting PayPal Plans Setup...'); $this->newLine(); $paypal = new PayPalService(); // Test authentication first $this->info('Testing PayPal authentication...'); try { $token = $paypal->getAccessToken(); $this->info('✅ PayPal authentication successful!'); $this->newLine(); } catch (\Exception $e) { $this->error('❌ PayPal authentication failed: ' . $e->getMessage()); return 1; } // Get plans that don't have PayPal plan IDs yet $plans = Plan::where('is_active', true) ->where('is_free', false) ->get(); if ($plans->isEmpty()) { $this->warn('No paid plans found in database.'); return 0; } $this->info("Found {$plans->count()} paid plan(s) to setup in PayPal:"); $this->newLine(); foreach ($plans as $plan) { $this->info("📦 Processing: {$plan->name}"); // Check if already has PayPal plan ID if ($plan->paypal_plan_id) { $this->warn(" Already has PayPal Plan ID: {$plan->paypal_plan_id}"); $this->line(" Skipping..."); $this->newLine(); continue; } try { // Step 1: Create Product in PayPal $this->line(" Creating product in PayPal..."); $product = $this->createProduct($paypal, $plan); $this->info(" ✅ Product created: {$product['id']}"); // Step 2: Create Billing Plan in PayPal $this->line(" Creating billing plan in PayPal..."); $billingPlan = $this->createBillingPlan($paypal, $plan, $product['id']); $this->info(" ✅ Billing Plan created: {$billingPlan['id']}"); // Step 3: Save PayPal Plan ID to database $plan->paypal_plan_id = $billingPlan['id']; $plan->save(); $this->info(" ✅ Saved to database!"); $this->newLine(); } catch (\Exception $e) { $this->error(" ❌ Error: " . $e->getMessage()); $this->newLine(); } } $this->info('🎉 PayPal Plans Setup completed!'); $this->newLine(); // Show summary $this->table( ['Plan', 'Price', 'Billing', 'PayPal Plan ID'], Plan::where('is_free', false)->get()->map(function ($p) { return [ $p->name, '€' . number_format($p->price, 2), $p->billing_period, $p->paypal_plan_id ?? 'Not set' ]; }) ); return 0; } private function createProduct(PayPalService $paypal, Plan $plan): array { $baseUrl = config('services.paypal.mode') === 'sandbox' ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com'; $response = \Illuminate\Support\Facades\Http::withToken($paypal->getAccessToken()) ->post("{$baseUrl}/v1/catalogs/products", [ 'name' => "WEBMoney - {$plan->name}", 'description' => $plan->description ?? "Subscription plan for WEBMoney", 'type' => 'SERVICE', 'category' => 'SOFTWARE', 'home_url' => config('app.url'), ]); if (!$response->successful()) { throw new \Exception('Failed to create product: ' . $response->body()); } return $response->json(); } private function createBillingPlan(PayPalService $paypal, Plan $plan, string $productId): array { $baseUrl = config('services.paypal.mode') === 'sandbox' ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com'; $billingCycles = []; // Add trial period if plan has trial if ($plan->trial_days > 0) { $billingCycles[] = [ 'frequency' => [ 'interval_unit' => 'DAY', 'interval_count' => $plan->trial_days, ], 'tenure_type' => 'TRIAL', 'sequence' => 1, 'total_cycles' => 1, 'pricing_scheme' => [ 'fixed_price' => [ 'value' => '0', 'currency_code' => $plan->currency, ], ], ]; } // Regular billing cycle $billingCycles[] = [ 'frequency' => [ 'interval_unit' => $plan->billing_period === 'annual' ? 'YEAR' : 'MONTH', 'interval_count' => 1, ], 'tenure_type' => 'REGULAR', 'sequence' => $plan->trial_days > 0 ? 2 : 1, 'total_cycles' => 0, // Infinite 'pricing_scheme' => [ 'fixed_price' => [ 'value' => number_format($plan->price, 2, '.', ''), 'currency_code' => $plan->currency, ], ], ]; $response = \Illuminate\Support\Facades\Http::withToken($paypal->getAccessToken()) ->post("{$baseUrl}/v1/billing/plans", [ 'product_id' => $productId, 'name' => $plan->name, 'description' => $plan->description ?? "WEBMoney {$plan->name} subscription", 'status' => 'ACTIVE', 'billing_cycles' => $billingCycles, 'payment_preferences' => [ 'auto_bill_outstanding' => true, 'setup_fee_failure_action' => 'CONTINUE', 'payment_failure_threshold' => 3, ], ]); if (!$response->successful()) { throw new \Exception('Failed to create billing plan: ' . $response->body()); } return $response->json(); } }