webseite funktioniert, pay sdk, blog backend funktioniert
This commit is contained in:
@@ -10,15 +10,14 @@ use Stripe\Stripe;
|
||||
use Stripe\Checkout\Session;
|
||||
use Stripe\StripeClient;
|
||||
use Exception;
|
||||
use PayPal\Api\Amount;
|
||||
use PayPal\Api\Payer;
|
||||
use PayPal\Api\Payment;
|
||||
use PayPal\Api\RedirectUrls;
|
||||
use PayPal\Api\Transaction;
|
||||
use PayPal\Rest\ApiContext;
|
||||
use PayPal\Auth\OAuthTokenCredential;
|
||||
use PayPal\PayPalHttp\Client;
|
||||
use PayPal\PayPalHttp\HttpException;
|
||||
use PayPal\Checkout\Orders\OrdersCreateRequest;
|
||||
use PayPal\Checkout\Orders\OrdersCaptureRequest;
|
||||
use PayPal\Checkout\Orders\OrdersGetRequest;
|
||||
use PayPal\Checkout\Orders\Order;
|
||||
use App\Models\Tenant;
|
||||
use App\Models\EventPurchase;
|
||||
use App\Models\BlogPost;
|
||||
use App\Models\Package;
|
||||
use App\Models\TenantPackage;
|
||||
use App\Models\PackagePurchase;
|
||||
@@ -107,6 +106,10 @@ class MarketingController extends Controller
|
||||
return redirect('/admin')->with('success', __('marketing.packages.free_assigned'));
|
||||
}
|
||||
|
||||
if ($package->type === 'reseller') {
|
||||
return $this->stripeSubscription($request, $packageId);
|
||||
}
|
||||
|
||||
if ($request->input('provider') === 'paypal') {
|
||||
return $this->paypalCheckout($request, $packageId);
|
||||
}
|
||||
@@ -151,7 +154,7 @@ class MarketingController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* PayPal checkout with auth metadata.
|
||||
* PayPal checkout with v2 Orders API (one-time payment).
|
||||
*/
|
||||
public function paypalCheckout(Request $request, $packageId)
|
||||
{
|
||||
@@ -159,78 +162,228 @@ class MarketingController extends Controller
|
||||
$user = Auth::user();
|
||||
$tenant = $user->tenant;
|
||||
|
||||
$apiContext = new ApiContext(
|
||||
new OAuthTokenCredential(
|
||||
config('services.paypal.client_id'),
|
||||
config('services.paypal.secret')
|
||||
)
|
||||
);
|
||||
$client = Client::create([
|
||||
'clientId' => config('services.paypal.client_id'),
|
||||
'clientSecret' => config('services.paypal.secret'),
|
||||
'environment' => config('services.paypal.sandbox', true) ? 'sandbox' : 'live',
|
||||
]);
|
||||
|
||||
$payment = new Payment();
|
||||
$payer = new Payer();
|
||||
$payer->setPaymentMethod('paypal');
|
||||
$ordersController = $client->orders();
|
||||
|
||||
$amountObj = new Amount();
|
||||
$amountObj->setCurrency('EUR');
|
||||
$amountObj->setTotal($package->price);
|
||||
|
||||
$transaction = new Transaction();
|
||||
$transaction->setAmount($amountObj);
|
||||
|
||||
$redirectUrls = new RedirectUrls();
|
||||
$redirectUrls->setReturnUrl(route('marketing.success', $packageId));
|
||||
$redirectUrls->setCancelUrl(route('packages'));
|
||||
|
||||
$customData = json_encode([
|
||||
$metadata = json_encode([
|
||||
'user_id' => $user->id,
|
||||
'tenant_id' => $tenant->id,
|
||||
'package_id' => $package->id,
|
||||
'type' => $package->type,
|
||||
]);
|
||||
|
||||
$payment->setIntent('sale')
|
||||
->setPayer($payer)
|
||||
->setTransactions([$transaction])
|
||||
->setRedirectUrls($redirectUrls)
|
||||
->setNoteToPayer('Package: ' . $package->name)
|
||||
->setCustom($customData);
|
||||
$createRequest = new OrdersCreateRequest();
|
||||
$createRequest->prefer('return=representation');
|
||||
$createRequest->body = [
|
||||
"intent" => "CAPTURE",
|
||||
"purchase_units" => [[
|
||||
"amount" => [
|
||||
"currency_code" => "EUR",
|
||||
"value" => number_format($package->price, 2, '.', ''),
|
||||
],
|
||||
"description" => "Package: " . $package->name,
|
||||
"custom_id" => $metadata,
|
||||
]],
|
||||
"application_context" => [
|
||||
"return_url" => route('marketing.success', $packageId),
|
||||
"cancel_url" => route('packages'),
|
||||
],
|
||||
];
|
||||
|
||||
try {
|
||||
$payment->create($apiContext);
|
||||
$response = $ordersController->createOrder($createRequest);
|
||||
$order = $response->result;
|
||||
|
||||
session(['paypal_payment_id' => $payment->getId()]);
|
||||
session(['paypal_order_id' => $order->id]);
|
||||
|
||||
return redirect($payment->getApprovalLink());
|
||||
foreach ($order->links as $link) {
|
||||
if ($link->rel === 'approve') {
|
||||
return redirect($link->href);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception('No approve link found');
|
||||
} catch (HttpException $e) {
|
||||
Log::error('PayPal Orders API error: ' . $e->getMessage());
|
||||
return back()->with('error', 'Zahlung fehlgeschlagen');
|
||||
} catch (\Exception $e) {
|
||||
Log::error('PayPal checkout error: ' . $e->getMessage());
|
||||
return back()->with('error', 'Zahlung fehlgeschlagen');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stripe subscription checkout for reseller packages.
|
||||
*/
|
||||
public function stripeSubscription(Request $request, $packageId)
|
||||
{
|
||||
$package = Package::findOrFail($packageId);
|
||||
$user = Auth::user();
|
||||
$tenant = $user->tenant;
|
||||
|
||||
$stripe = new StripeClient(config('services.stripe.secret'));
|
||||
$session = $stripe->checkout->sessions->create([
|
||||
'payment_method_types' => ['card'],
|
||||
'line_items' => [[
|
||||
'price_data' => [
|
||||
'currency' => 'eur',
|
||||
'product_data' => [
|
||||
'name' => $package->name . ' (Annual Subscription)',
|
||||
],
|
||||
'unit_amount' => $package->price * 100,
|
||||
'recurring' => [
|
||||
'interval' => 'year',
|
||||
'interval_count' => 1,
|
||||
],
|
||||
],
|
||||
'quantity' => 1,
|
||||
]],
|
||||
'mode' => 'subscription',
|
||||
'success_url' => route('marketing.success', $packageId),
|
||||
'cancel_url' => route('packages'),
|
||||
'metadata' => [
|
||||
'user_id' => $user->id,
|
||||
'tenant_id' => $tenant->id,
|
||||
'package_id' => $package->id,
|
||||
'type' => $package->type,
|
||||
'subscription' => 'true',
|
||||
],
|
||||
]);
|
||||
|
||||
return redirect($session->url, 303);
|
||||
}
|
||||
|
||||
public function stripeCheckout($sessionId)
|
||||
{
|
||||
// Handle Stripe success
|
||||
return view('marketing.success', ['provider' => 'Stripe']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle success after payment (capture PayPal, redirect if verified).
|
||||
*/
|
||||
public function success(Request $request, $packageId = null)
|
||||
{
|
||||
if (session('paypal_order_id')) {
|
||||
$orderId = session('paypal_order_id');
|
||||
$client = Client::create([
|
||||
'clientId' => config('services.paypal.client_id'),
|
||||
'clientSecret' => config('services.paypal.secret'),
|
||||
'environment' => config('services.paypal.sandbox', true) ? 'sandbox' : 'live',
|
||||
]);
|
||||
|
||||
$ordersController = $client->orders();
|
||||
|
||||
$captureRequest = new OrdersCaptureRequest($orderId);
|
||||
$captureRequest->prefer('return=minimal');
|
||||
|
||||
try {
|
||||
$captureResponse = $ordersController->captureOrder($captureRequest);
|
||||
$capture = $captureResponse->result;
|
||||
|
||||
if ($capture->status === 'COMPLETED') {
|
||||
$customId = $capture->purchaseUnits[0]->customId ?? null;
|
||||
if ($customId) {
|
||||
$metadata = json_decode($customId, true);
|
||||
$package = Package::find($metadata['package_id']);
|
||||
$tenant = Tenant::find($metadata['tenant_id']);
|
||||
|
||||
if ($package && $tenant) {
|
||||
TenantPackage::updateOrCreate(
|
||||
[
|
||||
'tenant_id' => $tenant->id,
|
||||
'package_id' => $package->id,
|
||||
],
|
||||
[
|
||||
'active' => true,
|
||||
'purchased_at' => now(),
|
||||
'expires_at' => now()->addYear(), // One-time as annual for reseller too
|
||||
]
|
||||
);
|
||||
|
||||
PackagePurchase::create([
|
||||
'tenant_id' => $tenant->id,
|
||||
'package_id' => $package->id,
|
||||
'provider_id' => 'paypal',
|
||||
'price' => $package->price,
|
||||
'type' => $package->type,
|
||||
'purchased_at' => now(),
|
||||
'refunded' => false,
|
||||
]);
|
||||
|
||||
session()->forget('paypal_order_id');
|
||||
$request->session()->flash('success', __('marketing.packages.purchased_successfully', ['name' => $package->name]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log::error('PayPal capture failed: ' . $capture->status);
|
||||
$request->session()->flash('error', 'Zahlung konnte nicht abgeschlossen werden.');
|
||||
}
|
||||
} catch (HttpException $e) {
|
||||
Log::error('PayPal capture error: ' . $e->getMessage());
|
||||
$request->session()->flash('error', 'Zahlung konnte nicht abgeschlossen werden.');
|
||||
} catch (\Exception $e) {
|
||||
Log::error('PayPal success error: ' . $e->getMessage());
|
||||
$request->session()->flash('error', 'Fehler beim Abschließen der Zahlung.');
|
||||
}
|
||||
}
|
||||
|
||||
// Common logic: Redirect to admin if verified
|
||||
if (Auth::check() && Auth::user()->email_verified_at) {
|
||||
return redirect('/admin')->with('success', __('marketing.success.welcome'));
|
||||
}
|
||||
|
||||
return view('marketing.success', compact('packageId'));
|
||||
}
|
||||
|
||||
public function blogIndex(Request $request)
|
||||
{
|
||||
$locale = $request->get('locale', app()->getLocale());
|
||||
$posts = \Stephenjude\FilamentBlog\Models\Post::query()
|
||||
->where('is_published', true)
|
||||
Log::info('Blog Index Debug - Initial', [
|
||||
'locale' => $locale,
|
||||
'full_url' => $request->fullUrl()
|
||||
]);
|
||||
|
||||
$query = BlogPost::query()
|
||||
->whereHas('category', function ($query) {
|
||||
$query->where('slug', 'blog');
|
||||
});
|
||||
|
||||
$totalWithCategory = $query->count();
|
||||
Log::info('Blog Index Debug - With Category', ['count' => $totalWithCategory]);
|
||||
|
||||
$query->where('is_published', true)
|
||||
->whereNotNull('published_at')
|
||||
->where('published_at', '<=', now())
|
||||
->whereJsonContains("translations->locale->title->{$locale}", true)
|
||||
->orderBy('published_at', 'desc')
|
||||
->where('published_at', '<=', now());
|
||||
|
||||
$totalPublished = $query->count();
|
||||
Log::info('Blog Index Debug - Published', ['count' => $totalPublished]);
|
||||
|
||||
$query->whereJsonContains("translations->locale->title->{$locale}", true);
|
||||
|
||||
$totalWithTranslation = $query->count();
|
||||
Log::info('Blog Index Debug - With Translation', ['count' => $totalWithTranslation, 'locale' => $locale]);
|
||||
|
||||
$posts = $query->orderBy('published_at', 'desc')
|
||||
->paginate(8);
|
||||
|
||||
Log::info('Blog Index Debug - Final Posts', ['count' => $posts->count(), 'total' => $posts->total()]);
|
||||
|
||||
return view('marketing.blog', compact('posts'));
|
||||
}
|
||||
|
||||
public function blogShow($slug)
|
||||
{
|
||||
$locale = app()->getLocale();
|
||||
$post = \Stephenjude\FilamentBlog\Models\Post::query()
|
||||
$post = BlogPost::query()
|
||||
->whereHas('category', function ($query) {
|
||||
$query->where('slug', 'blog');
|
||||
})
|
||||
->where('slug', $slug)
|
||||
->where('is_published', true)
|
||||
->whereNotNull('published_at')
|
||||
@@ -240,4 +393,24 @@ class MarketingController extends Controller
|
||||
|
||||
return view('marketing.blog-show', compact('post'));
|
||||
}
|
||||
|
||||
public function packagesIndex()
|
||||
{
|
||||
|
||||
$endcustomerPackages = Package::where('type', 'endcustomer')->orderBy('price')->get();
|
||||
$resellerPackages = Package::where('type', 'reseller')->orderBy('price')->get();
|
||||
|
||||
return view('marketing.packages', compact('endcustomerPackages', 'resellerPackages'));
|
||||
}
|
||||
|
||||
public function occasionsType($locale, $type)
|
||||
{
|
||||
|
||||
$validTypes = ['weddings', 'birthdays', 'corporate-events', 'family-celebrations'];
|
||||
if (!in_array($type, $validTypes)) {
|
||||
abort(404, 'Invalid occasion type');
|
||||
}
|
||||
|
||||
return view('marketing.occasions', ['type' => $type]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user