diff --git a/app/Http/Controllers/PluginPurchaseController.php b/app/Http/Controllers/PluginPurchaseController.php deleted file mode 100644 index 28c399ed..00000000 --- a/app/Http/Controllers/PluginPurchaseController.php +++ /dev/null @@ -1,136 +0,0 @@ -isFree()) { - return to_route('plugins.show', $plugin); - } - - $user = $request->user(); - $bestPrice = $plugin->getBestPriceForUser($user); - - if (! $bestPrice) { - return to_route('plugins.show', $plugin) - ->with('error', 'This plugin is not available for purchase.'); - } - - $discountPercent = $this->grandfatheringService->getApplicableDiscount($user, $plugin->is_official); - $discountedAmount = $bestPrice->getDiscountedAmount($discountPercent); - - return view('plugins.purchase', [ - 'plugin' => $plugin, - 'price' => $bestPrice, - 'discountPercent' => $discountPercent, - 'discountedAmount' => $discountedAmount, - 'originalAmount' => $bestPrice->amount, - ]); - } - - public function checkout(Request $request, Plugin $plugin): RedirectResponse - { - $user = $request->user(); - - if ($plugin->isFree()) { - return to_route('plugins.show', $plugin); - } - - if (! $plugin->getBestPriceForUser($user)) { - return to_route('plugins.show', $plugin) - ->with('error', 'This plugin is not available for purchase.'); - } - - // Add plugin to cart and redirect to cart checkout - $cart = $this->cartService->getCart($user); - - try { - $this->cartService->addPlugin($cart, $plugin); - } catch (\InvalidArgumentException $e) { - return to_route('plugins.show', $plugin) - ->with('error', $e->getMessage()); - } - - return to_route('cart.checkout'); - } - - public function success(Request $request, Plugin $plugin): View|RedirectResponse - { - $sessionId = $request->query('session_id'); - - // Validate session ID exists and looks like a real Stripe session ID - if (! $sessionId || ! str_starts_with($sessionId, 'cs_')) { - return to_route('plugins.show', $plugin) - ->with('error', 'Invalid checkout session. Please try again.'); - } - - return view('plugins.purchase-success', [ - 'plugin' => $plugin, - 'sessionId' => $sessionId, - ]); - } - - public function status(Request $request, Plugin $plugin, string $sessionId): JsonResponse - { - $user = $request->user(); - - // Retrieve the checkout session to get the invoice ID - try { - $session = Cashier::stripe()->checkout->sessions->retrieve($sessionId); - $invoiceId = $session->invoice; - } catch (\Exception $e) { - return response()->json([ - 'status' => 'error', - 'message' => 'Unable to verify purchase status.', - ], 400); - } - - if (! $invoiceId) { - return response()->json([ - 'status' => 'pending', - 'message' => 'Processing your purchase...', - ]); - } - - // Check if license exists for this invoice and plugin - $license = $user->pluginLicenses() - ->where('stripe_invoice_id', $invoiceId) - ->where('plugin_id', $plugin->id) - ->first(); - - if (! $license) { - return response()->json([ - 'status' => 'pending', - 'message' => 'Processing your purchase...', - ]); - } - - return response()->json([ - 'status' => 'complete', - 'message' => 'Purchase complete!', - 'plugin_name' => $plugin->name, - ]); - } - - public function cancel(Request $request, Plugin $plugin): RedirectResponse - { - return to_route('plugins.show', $plugin) - ->with('message', 'Purchase cancelled.'); - } -} diff --git a/resources/views/plugins/purchase-success.blade.php b/resources/views/plugins/purchase-success.blade.php deleted file mode 100644 index 187b0fc8..00000000 --- a/resources/views/plugins/purchase-success.blade.php +++ /dev/null @@ -1,154 +0,0 @@ - -
-
- {{-- Loading State --}} - - - {{-- Success State --}} - - - {{-- Timeout/Error State --}} - -
-
-
diff --git a/resources/views/plugins/purchase.blade.php b/resources/views/plugins/purchase.blade.php deleted file mode 100644 index ec474435..00000000 --- a/resources/views/plugins/purchase.blade.php +++ /dev/null @@ -1,143 +0,0 @@ - -
-
- {{-- Blurred circle - Decorative --}} - - - {{-- Back button --}} -
- - -
- - {{-- Plugin icon and title --}} -
-
- -
-
-

- Purchase {{ $plugin->name }} -

- @if ($plugin->description) -

- {{ $plugin->description }} -

- @endif -
-
-
- - - - {{-- Session Messages --}} - @if (session('error')) -
-

{{ session('error') }}

-
- @endif - - {{-- Purchase Card --}} -
-

Order Summary

- -
- {{-- Plugin Info --}} -
-
-

{{ $plugin->name }}

-

Lifetime access

-
-
- @if ($hasDiscount && $regularPrice) -

- ${{ number_format($regularPrice->amount / 100, 2) }} -

- @endif -

- ${{ number_format($price->amount / 100, 2) }} -

-
-
- - {{-- Discount Badge --}} - @if ($hasDiscount) -
-
- - - -

- {{ $price->tier->label() }} pricing applied -

-
-
- @endif - - {{-- Divider --}} -
-
-

Total

-

- ${{ number_format($price->amount / 100, 2) }} -

-
-
-
- - {{-- Purchase Button --}} -
-
- @csrf - -
-
- - {{-- Payment Info --}} -
- - - - Secure payment via Stripe -
-
- - {{-- What You Get --}} -
-

What's Included

-
    -
  • - - - - Lifetime access to plugin updates -
  • -
  • - - - - Install via Composer from plugins.nativephp.com -
  • -
  • - - - - Access to source code -
  • -
-
-
-
diff --git a/routes/web.php b/routes/web.php index b1dcf071..0cbb98e8 100644 --- a/routes/web.php +++ b/routes/web.php @@ -15,7 +15,6 @@ use App\Http\Controllers\LicenseRenewalController; use App\Http\Controllers\OpenCollectiveWebhookController; use App\Http\Controllers\PluginDirectoryController; -use App\Http\Controllers\PluginPurchaseController; use App\Http\Controllers\PluginWebhookController; use App\Http\Controllers\ProductController; use App\Http\Controllers\ShowBlogController; @@ -379,15 +378,6 @@ Route::post('webhooks/plugins/{secret}', PluginWebhookController::class)->name('webhooks.plugins'); -// Plugin purchase routes -Route::middleware(['auth', EnsureFeaturesAreActive::using(ShowAuthButtons::class), EnsureFeaturesAreActive::using(ShowPlugins::class)])->group(function (): void { - Route::get('plugins/{vendor}/{package}/purchase', [PluginPurchaseController::class, 'show'])->name('plugins.purchase.show'); - Route::post('plugins/{vendor}/{package}/purchase', [PluginPurchaseController::class, 'checkout'])->name('plugins.purchase.checkout'); - Route::get('plugins/{vendor}/{package}/purchase/success', [PluginPurchaseController::class, 'success'])->name('plugins.purchase.success'); - Route::get('plugins/{vendor}/{package}/purchase/status/{sessionId}', [PluginPurchaseController::class, 'status'])->name('plugins.purchase.status'); - Route::get('plugins/{vendor}/{package}/purchase/cancel', [PluginPurchaseController::class, 'cancel'])->name('plugins.purchase.cancel'); -}); - // Bundle routes (public) Route::middleware(EnsureFeaturesAreActive::using(ShowPlugins::class))->group(function (): void { Route::get('bundles/{bundle:slug}', [BundleController::class, 'show'])->name('bundles.show');