566 lines
No EOL
21 KiB
PHP
Executable file
566 lines
No EOL
21 KiB
PHP
Executable file
<?php
|
|
|
|
namespace App\Http\Controllers\Web;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Controllers\Pay\PayoneController;
|
|
use App\Models\PaymentTransaction;
|
|
use App\Models\ShoppingOrder;
|
|
use App\Models\ShoppingPayment;
|
|
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;
|
|
use App\User;
|
|
use Illuminate\Support\Facades\Session;
|
|
use Request;
|
|
use Validator;
|
|
use Yard;
|
|
|
|
class CheckoutController extends Controller
|
|
{
|
|
private $checkoutRepo;
|
|
private $instance = 'checkout';
|
|
|
|
/**
|
|
* Create a new controller instance.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function __construct(CheckoutRepository $checkoutRepository)
|
|
{
|
|
$this->checkoutRepo = $checkoutRepository;
|
|
}
|
|
|
|
/**
|
|
* 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())
|
|
*/
|
|
$shopping_data = Yard::instance($this->instance)->getYardExtra('shopping_data');
|
|
$is_from = $shopping_data['is_from'] ?? 'shopping';
|
|
$is_for = $shopping_data['is_for'] ?? false;
|
|
$is_abo = isset($shopping_data['is_abo']) ? (bool) $shopping_data['is_abo'] : false;
|
|
$abo_interval = $shopping_data['abo_interval'] ?? 0;
|
|
$homeparty_id = $shopping_data['homeparty_id'] ?? null;
|
|
$shopping_user = null;
|
|
|
|
if ($is_for === 'ot-customer' || $is_for === 'abo-ot-customer') {
|
|
$is_from = 'shopping';
|
|
}
|
|
Util::setInstanceStatus(1, true); // link_check
|
|
if ($is_abo) {
|
|
$instance_status = Util::getInstanceStatus();
|
|
if ($instance_status === 'link_paid') {
|
|
return $this->redirectToIsFinal($instance_status);
|
|
}
|
|
}
|
|
if (Session::has('new_session')) {
|
|
$this->checkoutRepo->sessionDestroy();
|
|
Session::forget('new_session');
|
|
}
|
|
$shopping_user = $this->initializeShoppingUserSession($is_from, $is_for, $shopping_data, $homeparty_id);
|
|
|
|
$this->prepareShoppingUserData($shopping_user);
|
|
$payment_methods = $this->checkoutRepo->getPaymentsMethods($is_from, $is_abo);
|
|
|
|
$data = [
|
|
'is_from' => $is_from,
|
|
'is_for' => $is_for,
|
|
'is_abo' => $is_abo,
|
|
'abo_interval' => $abo_interval,
|
|
'shopping_data' => $shopping_data,
|
|
'user_shop' => Util::getUserShop(),
|
|
'shopping_user' => $shopping_user,
|
|
'shopping_mode' => Util::getUserShoppingMode(),
|
|
'payment_methods' => $payment_methods['default'],
|
|
'payment_methods_active' => $payment_methods['active'],
|
|
'payment_data' => $payment_methods['data'],
|
|
'instance_status' => $instance_status ?? false,
|
|
'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) {
|
|
$shopping_user->same_as_billing = false;
|
|
}
|
|
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) {
|
|
$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();
|
|
}
|
|
if (old('selected_country') && old('selected_country') === 'change') {
|
|
Session::forget('_old_input.selected_country');
|
|
$shopping_user->billing_state = old('billing_state');
|
|
$shopping_user->shipping_state = old('shipping_state');
|
|
} else {
|
|
$shopping_user->billing_state = Yard::instance($this->instance)->getShippingCountryId();
|
|
$shopping_user->shipping_state = Yard::instance($this->instance)->getShippingCountryId();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Verarbeitet den Checkout-Prozess
|
|
*
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
*/
|
|
public function checkoutFinal()
|
|
{
|
|
$data = Request::all();
|
|
|
|
if (isset($data['payment_method'])) {
|
|
$this->checkoutRepo->isPaymentsMethodsActive($data['payment_method'], $data['is_from'], $data['is_abo']);
|
|
}
|
|
|
|
Util::setInstanceStatus(2, true); // link_check
|
|
|
|
// Länderwechsel verarbeiten
|
|
if (isset($data['selected_country']) && $data['selected_country'] === 'change') {
|
|
return $this->handleCountryChange($data);
|
|
}
|
|
|
|
// Validierung
|
|
$validator = $this->validateCheckoutData();
|
|
if ($validator->fails()) {
|
|
return back()->withErrors($validator)->withInput(Request::all());
|
|
}
|
|
|
|
// Benutzer und Bestellung erstellen
|
|
$shopping_user = $this->checkoutRepo->makeShoppingUser($data);
|
|
$shopping_order = $this->checkoutRepo->makeShoppingOrder($shopping_user, $data);
|
|
|
|
// CustomerPriority prüfen
|
|
if ($shopping_user->is_from === 'shopping') {
|
|
CustomerPriority::checkOne(ShoppingUser::find($shopping_user->id), true);
|
|
}
|
|
|
|
Util::setUserHistoryValue(['status' => 2, 'shopping_order_id' => $shopping_order->id]);
|
|
|
|
// Zahlungsmethode verarbeiten
|
|
if (Request::get('payment_method')) {
|
|
return $this->processPaymentMethod($data, $shopping_user, $shopping_order);
|
|
}
|
|
|
|
return redirect()->back();
|
|
}
|
|
|
|
/**
|
|
* Verarbeitet den Länderwechsel
|
|
*
|
|
* @param array $data
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
*/
|
|
private function handleCountryChange($data)
|
|
{
|
|
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']);
|
|
}
|
|
|
|
return back()->withInput(Request::all());
|
|
}
|
|
|
|
/**
|
|
* Validiert die Checkout-Daten
|
|
*
|
|
* @return \Illuminate\Validation\Validator
|
|
*/
|
|
private function validateCheckoutData()
|
|
{
|
|
$rules = [
|
|
'billing_salutation' => 'required',
|
|
'billing_firstname' => 'required',
|
|
'billing_lastname' => 'required',
|
|
'billing_email' => 'required|email',
|
|
'billing_address' => 'required',
|
|
'billing_zipcode' => 'required',
|
|
'billing_city' => 'required',
|
|
'accepted_data_checkbox' => 'accepted',
|
|
];
|
|
|
|
if (Request::get('same_as_billing')) {
|
|
$rules = array_merge($rules, [
|
|
'shipping_firstname' => 'required',
|
|
'shipping_lastname' => 'required',
|
|
'shipping_address' => 'required',
|
|
'shipping_zipcode' => 'required',
|
|
'shipping_city' => 'required',
|
|
'shipping_salutation' => 'required'
|
|
]);
|
|
}
|
|
|
|
return Validator::make(Request::all(), $rules);
|
|
}
|
|
|
|
/**
|
|
* Verarbeitet die Zahlungsmethode
|
|
*
|
|
* @param array $data
|
|
* @param ShoppingUser $shopping_user
|
|
* @param ShoppingOrder $shopping_order
|
|
* @return mixed
|
|
*/
|
|
private function processPaymentMethod($data, $shopping_user, $shopping_order)
|
|
{
|
|
$result = [];
|
|
$payment_method = Request::get('payment_method');
|
|
|
|
// Kreditkarte prüfen
|
|
if ($payment_method === 'cc') {
|
|
$result = $this->checkCreditCard($data, $shopping_user, $shopping_order);
|
|
if (!isset($result['returnstatus']) || $result['returnstatus'] !== 'VALID') {
|
|
return $result;
|
|
}
|
|
}
|
|
|
|
// SEPA prüfen
|
|
if ($payment_method === 'elv') {
|
|
$result = $this->checkSepaAccount($data, $shopping_user, $shopping_order);
|
|
if (!isset($result['returnstatus']) || $result['returnstatus'] !== 'VALID') {
|
|
return $result;
|
|
}
|
|
}
|
|
|
|
// Zahlung vorbereiten
|
|
$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);
|
|
$this->checkoutRepo->putSessionPayments('payment_reference', $reference);
|
|
$pay->setPersonalData();
|
|
|
|
return $pay->ResponseData();
|
|
}
|
|
|
|
/**
|
|
* Prüft die Kreditkartendaten
|
|
*
|
|
* @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->init($shopping_user, $shopping_order);
|
|
$ret['cc'] = $pay->checkCreditCard($data);
|
|
|
|
if ($ret['cc']['status'] === 'ERROR' || $ret['cc']['status'] === 'INVALID') {
|
|
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
|
|
* @return bool|\Illuminate\Http\RedirectResponse
|
|
*/
|
|
private function checkSepaAccount($data, $shopping_user, $shopping_order)
|
|
{
|
|
if (is_null(Request::get('mandate_identification'))) {
|
|
$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);
|
|
|
|
if ($ret['elv']['status'] === 'ERROR' || $ret['elv']['status'] === 'INVALID') {
|
|
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") {
|
|
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());
|
|
}
|
|
|
|
$ret['elv']['bankaccountholder'] = $data['elv_bankaccountholder'];
|
|
} else {
|
|
$ret['elv'] = [
|
|
'mandate_identification' => Request::get('mandate_identification'),
|
|
'creditor_identifier' => Request::get('creditor_identifier'),
|
|
'iban' => $data['elv_iban'],
|
|
'bic' => $data['elv_bic'],
|
|
'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()
|
|
{
|
|
$data = [
|
|
'user_shop' => Util::getUserShop(),
|
|
'is_checkout' => true,
|
|
'yard_instance' => $this->instance,
|
|
];
|
|
|
|
return view('web.templates.checkout-is-final', $data);
|
|
}
|
|
|
|
/**
|
|
* Verarbeitet den Transaktionsstatus
|
|
*
|
|
* @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();
|
|
|
|
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'));
|
|
}
|
|
|
|
$ShoppingPayment->status = $status;
|
|
$ShoppingPayment->save();
|
|
|
|
if ($status === "success") {
|
|
return $this->handleSuccessfulTransaction($ShoppingPayment, $reference);
|
|
}
|
|
|
|
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'));
|
|
}
|
|
|
|
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'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Verarbeitet eine erfolgreiche Transaktion
|
|
*
|
|
* @param ShoppingPayment $ShoppingPayment
|
|
* @param string $reference
|
|
* @return \Illuminate\View\View
|
|
*/
|
|
private function handleSuccessfulTransaction($ShoppingPayment, $reference)
|
|
{
|
|
Yard::instance($this->instance)->destroy();
|
|
$this->checkoutRepo->sessionDestroy(true);
|
|
Util::setInstanceStatus(3, true); // link_pending
|
|
|
|
// Abo erstellen, falls nötig
|
|
if ($ShoppingPayment->shopping_order->is_abo) {
|
|
AboHelper::createNewAbo($ShoppingPayment);
|
|
}
|
|
|
|
$payt = $ShoppingPayment->payment_transactions->last();
|
|
$data = [
|
|
'user_shop' => Util::getUserShop(),
|
|
'order_reference' => $reference,
|
|
'pay_trans' => $payt,
|
|
'is_checkout' => true,
|
|
'yard_instance' => $this->instance,
|
|
];
|
|
|
|
return view('web.templates.checkout-final', $data);
|
|
}
|
|
|
|
/**
|
|
* Verarbeitet eine genehmigte Transaktion
|
|
*
|
|
* @param int $transactionId
|
|
* @param string $reference
|
|
* @return \Illuminate\View\View
|
|
*/
|
|
public function transactionApproved($transactionId, $reference)
|
|
{
|
|
$payt = PaymentTransaction::findOrFail($transactionId);
|
|
if ($payt->shopping_payment->reference != $reference) {
|
|
abort(404);
|
|
}
|
|
Yard::instance($this->instance)->destroy();
|
|
$this->checkoutRepo->sessionDestroy(true);
|
|
Util::setInstanceStatus(3, true); // link_pending
|
|
|
|
// Abo erstellen, falls nötig
|
|
if ($payt->shopping_payment->shopping_order->is_abo) {
|
|
AboHelper::createNewAbo($payt->shopping_payment);
|
|
}
|
|
|
|
// Rechnung MIV
|
|
if ($payt->status === 'FNCMIV') {
|
|
$this->directPaymentStatus($payt);
|
|
}
|
|
|
|
$data = [
|
|
'user_shop' => Util::getUserShop(),
|
|
'order_reference' => $payt->shopping_payment->reference,
|
|
'pay_trans' => $payt,
|
|
'is_checkout' => true,
|
|
'yard_instance' => $this->instance,
|
|
];
|
|
|
|
return view('web.templates.checkout-final', $data);
|
|
}
|
|
|
|
/**
|
|
* Speichert die Zahlungsdaten des Benutzers
|
|
*
|
|
* @param ShoppingUser $shopping_user
|
|
* @param array $ret
|
|
* @return void
|
|
*/
|
|
private function storeUserPaymentsData($shopping_user, $ret)
|
|
{
|
|
if ($shopping_user->auth_user_id) {
|
|
$user = User::find($shopping_user->auth_user_id);
|
|
if ($user && $user->account) {
|
|
if (isset($ret['elv']) && is_array($ret['elv'])) {
|
|
$user->account->payment_data = $ret['elv'];
|
|
$user->account->save();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Verarbeitet den direkten Zahlungsstatus (Rechnung MIV)
|
|
*
|
|
* @param PaymentTransaction $payt
|
|
* @return void
|
|
*/
|
|
private function directPaymentStatus(PaymentTransaction $payt)
|
|
{
|
|
if (isset($payt->transmitted_data['param'])) {
|
|
$shopping_order = ShoppingOrder::find($payt->transmitted_data['param']);
|
|
$shopping_order->txaction = 'invoice_open';
|
|
$shopping_order->save();
|
|
|
|
$shopping_payment = ShoppingPayment::where('reference', $payt->transmitted_data['reference'])->first();
|
|
if ($shopping_payment) {
|
|
$shopping_payment->txaction = 'invoice_open';
|
|
$shopping_payment->save();
|
|
}
|
|
|
|
$send_link = Payment::paymentStatusPaidAction($shopping_order, false, $shopping_payment);
|
|
$data = [
|
|
'mode' => $payt->transmitted_data['mode'],
|
|
'txaction' => $payt->txaction,
|
|
'send_link' => $send_link,
|
|
];
|
|
|
|
Payment::paymentStatusSendMail($shopping_order, $shopping_payment, $data);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* @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
|
|
if ($this->checkoutRepo->getSessionPayments('shopping_user_id')) {
|
|
return $this->getExistingShoppingUser();
|
|
}
|
|
//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
|
|
if ($is_from === 'shopping') {
|
|
//Bestelllink
|
|
if ($is_for === 'ot-customer' || $is_for === 'abo-ot-customer') {
|
|
//customer shop mit den Daten aus dem Salescenter shopping_data
|
|
return $this->checkoutRepo->makeCustomerShoppingUser($shopping_data, $is_for, $is_from);
|
|
}
|
|
//Webshop
|
|
return $this->checkoutRepo->initShoppingUser($is_for, $is_from, $homeparty_id);
|
|
}
|
|
|
|
return $this->getExistingShoppingUser();
|
|
}
|
|
|
|
/**
|
|
* Holt den existierenden ShoppingUser und bereitet ihn vor
|
|
*
|
|
* @return ShoppingUser
|
|
*/
|
|
private function getExistingShoppingUser()
|
|
{
|
|
$shopping_user = ShoppingUser::findOrFail($this->checkoutRepo->getSessionPayments('shopping_user_id'));
|
|
$shopping_user->billing_state = Shop::getCountryShippingCountryId($shopping_user->billing_country_id);
|
|
$shopping_user->shipping_state = Shop::getCountryShippingCountryId($shopping_user->shipping_country_id);
|
|
$shopping_user->same_as_billing = $shopping_user->same_as_billing ? false : true; // reinvert
|
|
|
|
return $shopping_user;
|
|
}
|
|
|
|
} |