Deploy to Production (witstore.wende.it) / deploy (push) Successful in 7s
- PayPal: Checkout-Integration via srmklive/paypal, Weiterleitung zu PayPal, Bestellung wird nach Capture automatisch auf payment_received gesetzt - Stripe: Payment Elements im Checkout, Intent-API, Zahlung direkt bestätigt - CSV-Export: Admin → Bestellungen → CSV exportieren (UTF-8 BOM für Excel) - PayPal/Stripe nur sichtbar wenn Keys in .env gesetzt - .env.example um PAYPAL_* und STRIPE_* Keys erweitert Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
105 lines
3.6 KiB
PHP
105 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Shop;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Services\CartService;
|
|
use App\Services\OrderService;
|
|
use App\Models\Coupon;
|
|
use App\Models\Order;
|
|
use App\Models\ShippingRate;
|
|
use Illuminate\Http\Request;
|
|
use Srmklive\PayPal\Services\PayPal as PayPalClient;
|
|
|
|
class PayPalController extends Controller
|
|
{
|
|
public function __construct(private CartService $cart, private OrderService $orderService) {}
|
|
|
|
public function redirect(Request $request)
|
|
{
|
|
$checkoutData = session('checkout_data');
|
|
if (!$checkoutData || $this->cart->count() === 0) {
|
|
return redirect()->route('checkout.index');
|
|
}
|
|
|
|
$subtotal = $this->cart->subtotal();
|
|
$country = $checkoutData['shipping']['country'] ?? $checkoutData['billing']['country'] ?? 'DE';
|
|
$shippingRate = ShippingRate::forCart($subtotal, $country);
|
|
$shippingCost = $shippingRate ? $shippingRate->getCostForTotal($subtotal) : 0;
|
|
$discount = 0;
|
|
if ($code = session('coupon_code')) {
|
|
$coupon = Coupon::findValid($code);
|
|
if ($coupon) $discount = $coupon->calcDiscount($subtotal);
|
|
}
|
|
$total = max(0, $subtotal - $discount) + $shippingCost;
|
|
|
|
$provider = new PayPalClient;
|
|
$provider->setApiCredentials(config('paypal'));
|
|
$provider->getAccessToken();
|
|
|
|
$order = $provider->createOrder([
|
|
'intent' => 'CAPTURE',
|
|
'purchase_units' => [[
|
|
'amount' => [
|
|
'currency_code' => 'EUR',
|
|
'value' => number_format($total, 2, '.', ''),
|
|
],
|
|
'description' => config('app.name') . ' Bestellung',
|
|
]],
|
|
'application_context' => [
|
|
'return_url' => route('paypal.success'),
|
|
'cancel_url' => route('checkout.confirm'),
|
|
],
|
|
]);
|
|
|
|
if (isset($order['id'])) {
|
|
session(['paypal_order_id' => $order['id']]);
|
|
foreach ($order['links'] as $link) {
|
|
if ($link['rel'] === 'approve') {
|
|
return redirect($link['href']);
|
|
}
|
|
}
|
|
}
|
|
|
|
return redirect()->route('checkout.confirm')->with('error', 'PayPal-Verbindung fehlgeschlagen. Bitte versuchen Sie es erneut.');
|
|
}
|
|
|
|
public function success(Request $request)
|
|
{
|
|
$checkoutData = session('checkout_data');
|
|
$paypalOrderId = session('paypal_order_id');
|
|
|
|
if (!$checkoutData || !$paypalOrderId) {
|
|
return redirect()->route('checkout.index');
|
|
}
|
|
|
|
$provider = new PayPalClient;
|
|
$provider->setApiCredentials(config('paypal'));
|
|
$provider->getAccessToken();
|
|
|
|
$result = $provider->capturePaymentOrder($paypalOrderId);
|
|
|
|
if (($result['status'] ?? '') !== 'COMPLETED') {
|
|
return redirect()->route('checkout.confirm')->with('error', 'PayPal-Zahlung nicht abgeschlossen.');
|
|
}
|
|
|
|
$checkoutData['payment_method'] = 'paypal';
|
|
$order = $this->orderService->createFromSession($checkoutData, 'paypal');
|
|
$order->update([
|
|
'payment_id' => $paypalOrderId,
|
|
'status' => 'payment_received',
|
|
'paid_at' => now(),
|
|
]);
|
|
|
|
session()->forget(['checkout_data', 'checkout_country', 'paypal_order_id']);
|
|
|
|
return redirect()->route('checkout.thankyou', $order->order_number);
|
|
}
|
|
|
|
public function cancel()
|
|
{
|
|
session()->forget('paypal_order_id');
|
|
return redirect()->route('checkout.confirm')->with('error', 'PayPal-Zahlung abgebrochen.');
|
|
}
|
|
}
|