20-02-2026

This commit is contained in:
Kevin Adametz 2026-02-20 17:55:06 +01:00
parent a8b395e20d
commit a00c42e770
252 changed files with 28785 additions and 8907 deletions

View file

@ -11,7 +11,6 @@ use App\Models\ShoppingUser;
use App\Repositories\CheckoutRepository;
use App\Services\AboHelper;
use App\Services\CustomerPriority;
use App\Services\OrderPaymentService;
use App\Services\Payment;
use App\Services\Shop;
use App\Services\Util;
@ -24,6 +23,7 @@ use Yard;
class CheckoutController extends Controller
{
private $checkoutRepo;
private $instance = 'checkout';
/**
@ -38,18 +38,18 @@ class CheckoutController extends Controller
/**
* Zeigt die Checkout-Seite an
*
*
* @return \Illuminate\View\View
*/
public function checkout()
{
/*
@if(Auth::guard('customers')->check())
<a href="{{ route('portal.logout') }}" class="btn btn-sm btn-default mt-3"><i class="fa fa-power-off"></i> {{ __('navigation.logout') }} </a>
@else
<a href="{{ Util::getMyMivitaPortalUrl() }}" class="btn btn-primary btn-block mt-3 faa-parent animated-hover"><i class="fa fa-sign-in"></i> {{ __('website.to_customer_portal') }} </a>
@endif
@if(Auth::guard('user')->check())
<a href="{{ route('portal.logout') }}" class="btn btn-sm btn-default mt-3"><i class="fa fa-power-off"></i> {{ __('navigation.logout') }} </a>
@else
<a href="{{ Util::getMyMivitaPortalUrl() }}" class="btn btn-primary btn-block mt-3 faa-parent animated-hover"><i class="fa fa-sign-in"></i> {{ __('website.to_customer_portal') }} </a>
@endif
@if(Auth::guard('user')->check())
*/
$shopping_data = Yard::instance($this->instance)->getYardExtra('shopping_data');
$is_from = $shopping_data['is_from'] ?? 'shopping';
@ -97,28 +97,26 @@ class CheckoutController extends Controller
'is_checkout' => true,
'yard_instance' => $this->instance,
];
return view('web.templates.checkout', $data);
}
/**
* Bereitet die ShoppingUser-Daten vor
*
* @param ShoppingUser $shopping_user
*
* @return void
*/
private function prepareShoppingUserData(ShoppingUser $shopping_user)
{
if ($shopping_user->same_as_billing === NULL) {
if ($shopping_user->same_as_billing === null) {
$shopping_user->same_as_billing = false;
}
if (!$shopping_user->billing_country_id) {
if (! $shopping_user->billing_country_id) {
$shopping_user->billing_country_id = Yard::instance($this->instance)->getUserCountryId();
// Die Zeile unten entfernen, da die Relation automatisch geladen wird
// $shopping_user->billing_country = Yard::instance($this->instance)->getUserCountry();
}
if (!$shopping_user->shipping_country_id) {
if (! $shopping_user->shipping_country_id) {
$shopping_user->shipping_country_id = Yard::instance($this->instance)->getUserCountryId();
// Die Zeile unten entfernen, da die Relation automatisch geladen wird
// $shopping_user->shipping_country = Yard::instance($this->instance)->getUserCountry();
@ -135,7 +133,7 @@ class CheckoutController extends Controller
/**
* Verarbeitet den Checkout-Prozess
*
*
* @return \Illuminate\Http\RedirectResponse
*/
public function checkoutFinal()
@ -180,13 +178,13 @@ class CheckoutController extends Controller
/**
* Verarbeitet den Länderwechsel
*
* @param array $data
*
* @param array $data
* @return \Illuminate\Http\RedirectResponse
*/
private function handleCountryChange($data)
{
if (!Request::get('same_as_billing')) {
if (! Request::get('same_as_billing')) {
Yard::instance($this->instance)->setShippingCountryWithPrice($data['billing_state'], $data['is_for']);
} else {
Yard::instance($this->instance)->setShippingCountryWithPrice($data['shipping_state'], $data['is_for']);
@ -197,7 +195,7 @@ class CheckoutController extends Controller
/**
* Validiert die Checkout-Daten
*
*
* @return \Illuminate\Validation\Validator
*/
private function validateCheckoutData()
@ -220,7 +218,7 @@ class CheckoutController extends Controller
'shipping_address' => 'required',
'shipping_zipcode' => 'required',
'shipping_city' => 'required',
'shipping_salutation' => 'required'
'shipping_salutation' => 'required',
]);
}
@ -229,10 +227,10 @@ class CheckoutController extends Controller
/**
* Verarbeitet die Zahlungsmethode
*
* @param array $data
* @param ShoppingUser $shopping_user
* @param ShoppingOrder $shopping_order
*
* @param array $data
* @param ShoppingUser $shopping_user
* @param ShoppingOrder $shopping_order
* @return mixed
*/
private function processPaymentMethod($data, $shopping_user, $shopping_order)
@ -243,7 +241,7 @@ class CheckoutController extends Controller
// Kreditkarte prüfen
if ($payment_method === 'cc') {
$result = $this->checkCreditCard($data, $shopping_user, $shopping_order);
if (!is_array($result) || !isset($result['returnstatus']) || $result['returnstatus'] !== 'VALID') {
if (! is_array($result) || ! isset($result['returnstatus']) || $result['returnstatus'] !== 'VALID') {
return $result;
}
}
@ -251,13 +249,13 @@ class CheckoutController extends Controller
// SEPA prüfen
if ($payment_method === 'elv') {
$result = $this->checkSepaAccount($data, $shopping_user, $shopping_order);
if (!is_array($result) || !isset($result['returnstatus']) || $result['returnstatus'] !== 'VALID') {
if (! is_array($result) || ! isset($result['returnstatus']) || $result['returnstatus'] !== 'VALID') {
return $result;
}
}
// Zahlung vorbereiten
$pay = new PayoneController();
$pay = new PayoneController;
$pay->init($shopping_user, $shopping_order);
$amount = Yard::instance($this->instance)->totalWithShipping(2, '.', '') * 100;
$reference = $pay->setPrePayment($payment_method, $amount, 'EUR', $result);
@ -269,15 +267,15 @@ class CheckoutController extends Controller
/**
* Prüft die Kreditkartendaten
*
* @param array $data
* @param ShoppingUser $shopping_user
* @param ShoppingOrder $shopping_order
*
* @param array $data
* @param ShoppingUser $shopping_user
* @param ShoppingOrder $shopping_order
* @return bool|\Illuminate\Http\RedirectResponse
*/
private function checkCreditCard($data, $shopping_user, $shopping_order)
{
$pay = new PayoneController();
$pay = new PayoneController;
$pay->init($shopping_user, $shopping_order);
$ret['cc'] = $pay->checkCreditCard($data);
@ -285,24 +283,26 @@ class CheckoutController extends Controller
Session::flash('cc-error', 1);
Session::flash('errormessage', $ret['cc']['errormessage']);
Session::flash('customermessage', $ret['cc']['customermessage']);
return redirect(route('checkout.checkout_card'))->withInput(Request::all());
}
$ret['returnstatus'] = 'VALID';
return $ret;
}
/**
* Prüft die SEPA-Kontodaten
*
* @param array $data
* @param ShoppingUser $shopping_user
* @param ShoppingOrder $shopping_order
*
* @param array $data
* @param ShoppingUser $shopping_user
* @param ShoppingOrder $shopping_order
* @return bool|\Illuminate\Http\RedirectResponse
*/
private function checkSepaAccount($data, $shopping_user, $shopping_order)
{
if (is_null(Request::get('mandate_identification'))) {
$pay = new PayoneController();
$pay = new PayoneController;
$pay->init($shopping_user, $shopping_order);
$amount = Yard::instance($this->instance)->totalWithShipping(2, '.', '') * 100;
$ret['elv'] = $pay->checkBankAccount($data, $amount, 'EUR', $shopping_user);
@ -311,14 +311,16 @@ class CheckoutController extends Controller
Session::flash('elv-error', 1);
Session::flash('errormessage', $ret['elv']['errormessage']);
Session::flash('customermessage', $ret['elv']['customermessage']);
return redirect(route('checkout.checkout_card'))->withInput(Request::all());
}
if ($ret['elv']['status'] === 'APPROVED' && $ret['elv']['mandate_status'] !== "active") {
if ($ret['elv']['status'] === 'APPROVED' && $ret['elv']['mandate_status'] !== 'active') {
Session::flash('elv-managemandate', 1);
Session::flash('elv-mandate_identification', $ret['elv']['mandate_identification']);
Session::flash('elv-mandate_text', $ret['elv']['mandate_text']);
Session::flash('elv-creditor_identifier', $ret['elv']['creditor_identifier']);
return redirect(route('checkout.checkout_card'))->withInput(Request::all());
}
@ -329,18 +331,19 @@ class CheckoutController extends Controller
'creditor_identifier' => Request::get('creditor_identifier'),
'iban' => $data['elv_iban'],
'bic' => $data['elv_bic'],
'bankaccountholder' => $data['elv_bankaccountholder']
'bankaccountholder' => $data['elv_bankaccountholder'],
];
$this->storeUserPaymentsData($shopping_user, $ret);
}
$ret['returnstatus'] = 'VALID';
return $ret;
}
/**
* Leitet zur Abschlussseite weiter
*
*
* @return \Illuminate\View\View
*/
public function redirectToIsFinal()
@ -354,53 +357,105 @@ class CheckoutController extends Controller
return view('web.templates.checkout-is-final', $data);
}
/**
* Verarbeitet den Transaktionsstatus (POST-Anfragen)
* Einige Zahlungsanbieter senden POST-Anfragen zurück
*
* @param string $status
* @param string $reference
* @return \Illuminate\View\View|\Illuminate\Http\RedirectResponse
*/
public function transactionStatusPost($status, $reference)
{
return $this->transactionStatus($status, $reference);
}
/**
* Verarbeitet den Transaktionsstatus
*
* @param string $status
* @param string $reference
*
* @param string $status
* @param string $reference
* @return \Illuminate\View\View|\Illuminate\Http\RedirectResponse
*/
public function transactionStatus($status, $reference)
{
$shopping_order_id = $this->checkoutRepo->getSessionPayments('shopping_order_id');
$ShoppingPayment = ShoppingPayment::where('shopping_order_id', $shopping_order_id)
->where('reference', $reference)
->first();
// Suche ShoppingPayment nur über reference (nicht Session-abhängig)
// Dies ist wichtig, da die Session bei Redirect-Zahlungen verloren gehen kann
$ShoppingPayment = ShoppingPayment::where('reference', $reference)->first();
if (!$ShoppingPayment) {
if (! $ShoppingPayment) {
Util::setUserHistoryValue(['status' => 21]);
Session::flash('checkout-error', 'Der Zahlungsvorgang konnte nicht abgeschlossen werden, die Zahlung wurde nicht gefunden: ' . $reference);
return redirect(route('checkout.checkout_card'));
\Log::warning('CheckoutController::transactionStatus - ShoppingPayment nicht gefunden', [
'reference' => $reference,
'status' => $status,
]);
// Zeige eine dedizierte Fehlerseite anstatt zur Hauptseite weiterzuleiten
return $this->showTransactionError(
__('payment.payment_not_found'),
__('payment.payment_not_found_description', ['reference' => $reference])
);
}
$ShoppingPayment->status = $status;
$ShoppingPayment->save();
if ($status === "success") {
if ($status === 'success') {
return $this->handleSuccessfulTransaction($ShoppingPayment, $reference);
}
if ($status === "cancel") {
if ($status === 'cancel') {
Util::setUserHistoryValue(['status' => 22]);
Util::setInstanceStatus(5); // link_canceled
Session::flash('checkout-error', 'Der Zahlungsvorgang wurde abgebrochen, die Bestellung konnte nicht ausgeführt werden.');
return redirect(route('checkout.checkout_card'));
Util::setInstanceStatusByPayment($ShoppingPayment, 6); // link_canceled
return $this->showTransactionError(
__('payment.payment_canceled'),
__('payment.payment_canceled_description')
);
}
if ($status === "error") {
if ($status === 'error') {
Util::setUserHistoryValue(['status' => 23]);
Util::setInstanceStatus(6); // link_failed
Session::flash('checkout-error', 'Der Zahlungsvorgang wurde abgebrochen, die Bestellung konnte nicht ausgeführt werden.');
return redirect(route('checkout.checkout_card'));
Util::setInstanceStatusByPayment($ShoppingPayment, 5); // link_failed
return $this->showTransactionError(
__('payment.payment_error'),
__('payment.payment_error_description')
);
}
// Fallback für unbekannte Status
return $this->showTransactionError(
__('payment.payment_unknown_status'),
__('payment.payment_unknown_status_description')
);
}
/**
* Zeigt eine Transaktionsfehlerseite an
*
* @param string $title
* @param string $message
* @return \Illuminate\View\View
*/
private function showTransactionError($title, $message)
{
$data = [
'user_shop' => Util::getUserShop(),
'is_checkout' => true,
'yard_instance' => $this->instance,
'error_title' => $title,
'error_message' => $message,
];
return view('web.templates.checkout-error', $data);
}
/**
* Verarbeitet eine erfolgreiche Transaktion
*
* @param ShoppingPayment $ShoppingPayment
* @param string $reference
*
* @param ShoppingPayment $ShoppingPayment
* @param string $reference
* @return \Illuminate\View\View
*/
private function handleSuccessfulTransaction($ShoppingPayment, $reference)
@ -428,9 +483,9 @@ class CheckoutController extends Controller
/**
* Verarbeitet eine genehmigte Transaktion
*
* @param int $transactionId
* @param string $reference
*
* @param int $transactionId
* @param string $reference
* @return \Illuminate\View\View
*/
public function transactionApproved($transactionId, $reference)
@ -466,9 +521,9 @@ class CheckoutController extends Controller
/**
* Speichert die Zahlungsdaten des Benutzers
*
* @param ShoppingUser $shopping_user
* @param array $ret
*
* @param ShoppingUser $shopping_user
* @param array $ret
* @return void
*/
private function storeUserPaymentsData($shopping_user, $ret)
@ -486,8 +541,7 @@ class CheckoutController extends Controller
/**
* Verarbeitet den direkten Zahlungsstatus (Rechnung MIV)
*
* @param PaymentTransaction $payt
*
* @return void
*/
private function directPaymentStatus(PaymentTransaction $payt)
@ -517,34 +571,36 @@ class CheckoutController extends Controller
/**
* Initialisiert oder ruft einen Shopping-Benutzer ab
*
* @param string|null $is_from = shopping | user_order | user_order_ot | user_order_abo | user_order_abo_ot | user_order_ot_customer | user_order_abo_ot_customer
* @param string|null $is_for = me | ot | abo-me | abo-ot | ot-customer | abo-ot-customer
* @param array|null $shopping_data
* @param int|null $homeparty_id
* @param string|null $is_from = shopping | user_order | user_order_ot | user_order_abo | user_order_abo_ot | user_order_ot_customer | user_order_abo_ot_customer
* @param string|null $is_for = me | ot | abo-me | abo-ot | ot-customer | abo-ot-customer
* @param array|null $shopping_data
* @param int|null $homeparty_id
* @return \App\Models\ShoppingUser
*/
private function initializeShoppingUserSession($is_from, $is_for, $shopping_data = null, $homeparty_id = null)
{
//check if shopping_user_id is set - der user ist bereits angelegt
// check if shopping_user_id is set - der user ist bereits angelegt
if ($this->checkoutRepo->getSessionPayments('shopping_user_id')) {
return $this->getExistingShoppingUser();
}
//kommt vom Salescenter
// kommt vom Salescenter
if ($shopping_data && $is_from !== 'shopping') {
$shopping_user = $this->checkoutRepo->shoppingUserAuthData($is_from, $is_for, $shopping_data);
$shopping_user->save();
$this->checkoutRepo->putSessionPayments('shopping_user_id', $shopping_user->id);
return $shopping_user;
}
//kommt aus dem Salescenter mit bestelllink oder aus dem Webshop
// kommt aus dem Salescenter mit bestelllink oder aus dem Webshop
if ($is_from === 'shopping') {
//Bestelllink
// Bestelllink
if ($is_for === 'ot-customer' || $is_for === 'abo-ot-customer') {
//customer shop mit den Daten aus dem Salescenter shopping_data
// customer shop mit den Daten aus dem Salescenter shopping_data
return $this->checkoutRepo->makeCustomerShoppingUser($shopping_data, $is_for, $is_from);
}
//Webshop
// Webshop
return $this->checkoutRepo->initShoppingUser($is_for, $is_from, $homeparty_id);
}
@ -553,7 +609,7 @@ class CheckoutController extends Controller
/**
* Holt den existierenden ShoppingUser und bereitet ihn vor
*
*
* @return ShoppingUser
*/
private function getExistingShoppingUser()