feat(payments): Express-Kauf aus dem Warenkorb (PayPal v2): Start ohne Bestellung, Adresse von PayPal, Kasse vorbelegt, Capture ohne zweiten Besuch
This commit is contained in:
@@ -80,6 +80,17 @@ class website_cashdesk {
|
||||
return $this->payment_provider_return();
|
||||
}
|
||||
|
||||
// 14.09.2026 -- Express aus dem Warenkorb ("Direkt mit PayPal bezahlen").
|
||||
// Start: Vorgang beim Anbieter ohne Bestellung, Kunde geht hin und gibt frei.
|
||||
// Rueckkehr: Adresse/E-Mail vom Anbieter in die Session, weiter in die Gast-Kasse,
|
||||
// dort ist alles vorbelegt -- ein Klick auf "zahlungspflichtig bestellen" zieht ein.
|
||||
if (isset($_GET['payment_express_start'])) {
|
||||
return $this->payment_express_start();
|
||||
}
|
||||
if (isset($_GET['payment_express'])) {
|
||||
return $this->payment_express_return();
|
||||
}
|
||||
|
||||
// 24.08.2026 -- Zielseite des Post/Redirect/Get aus PaypalPaymentMethod::after_order().
|
||||
// Reines GET: hier steht der Link zu PayPal, ein Reload laedt nur noch ihn neu und
|
||||
// legt keine zweite Bestellung mehr an.
|
||||
@@ -109,6 +120,7 @@ class website_cashdesk {
|
||||
$this->base_object->customer->customer_id = $this->base_object->config->shopConfiguration['guest_order_customer_id'];
|
||||
$this->layout_object->assign('guest_order', 1);
|
||||
}
|
||||
$this->payment_express_prefill();
|
||||
$action = '';
|
||||
|
||||
if ($this->base_object->customer->customer_id) {
|
||||
@@ -361,6 +373,119 @@ class website_cashdesk {
|
||||
|
||||
// end run
|
||||
|
||||
// ------------------------------------------------------------ Express
|
||||
|
||||
/** Start aus dem Warenkorb: /Kasse/?payment_express_start=<modul> */
|
||||
private function payment_express_start() {
|
||||
$module = strtolower(trim((string)$_GET['payment_express_start']));
|
||||
$provider = $this->payment_provider($module);
|
||||
if (!$provider || !$provider->supportsExpress()) {
|
||||
header('Location: /Warenkorb/');
|
||||
exit;
|
||||
}
|
||||
$shoppingcart_object = new Shoppingcart($this->base_object);
|
||||
$cart = $shoppingcart_object->get_data();
|
||||
if (empty($cart['items']) || (float)$cart['price_sum_gross'] <= 0) {
|
||||
header('Location: /Warenkorb/');
|
||||
exit;
|
||||
}
|
||||
try {
|
||||
$url = $provider->startExpress(round((float)$cart['price_sum_gross'], 2));
|
||||
} catch (Throwable $e) {
|
||||
error_log('Payments express start '.$module.': '.$e->getMessage());
|
||||
$this->layout_object->assign('call', 'payment_error');
|
||||
$this->layout_object->assign('provider_label', $provider->label());
|
||||
$this->layout_object->assign('message', $provider->label().' konnte nicht gestartet werden. Ihr Warenkorb ist noch da – bitte gehen Sie normal zur Kasse.');
|
||||
return $this->layout_object->_fetch('content_cash_desk/payment_result.tpl');
|
||||
}
|
||||
header('Location: '.$url);
|
||||
exit;
|
||||
}
|
||||
|
||||
/** Rueckkehr im Express-Weg: /Kasse/?payment_express=<modul>&token=... */
|
||||
private function payment_express_return() {
|
||||
$module = strtolower(trim((string)$_GET['payment_express']));
|
||||
$provider = $this->payment_provider($module);
|
||||
$data = null;
|
||||
if ($provider && $provider->supportsExpress()) {
|
||||
try {
|
||||
$data = $provider->onExpressReturn($_GET);
|
||||
} catch (Throwable $e) {
|
||||
error_log('Payments express return '.$module.': '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
if (!$data) {
|
||||
$this->layout_object->assign('call', 'payment_error');
|
||||
$this->layout_object->assign('provider_label', $provider ? $provider->label() : 'Zahlung');
|
||||
$this->layout_object->assign('message', 'Der Express-Vorgang konnte nicht übernommen werden. Ihr Warenkorb ist noch da – bitte gehen Sie normal zur Kasse.');
|
||||
return $this->layout_object->_fetch('content_cash_desk/payment_result.tpl');
|
||||
}
|
||||
$country_id = $provider->countryIdByIso((string)$data['country_iso']);
|
||||
if ($country_id <= 0) {
|
||||
$this->layout_object->assign('call', 'payment_error');
|
||||
$this->layout_object->assign('provider_label', $provider->label());
|
||||
$this->layout_object->assign('message', 'In das bei '.$provider->label().' hinterlegte Land ('.htmlspecialchars((string)$data['country_iso']).') liefern wir leider nicht. Bitte gehen Sie normal zur Kasse und wählen Sie eine Lieferadresse.');
|
||||
return $this->layout_object->_fetch('content_cash_desk/payment_result.tpl');
|
||||
}
|
||||
$data['module'] = $module;
|
||||
$data['country_id'] = $country_id;
|
||||
$data['time'] = time();
|
||||
$_SESSION['easyshop']['payment_express'] = $data;
|
||||
|
||||
// Eingeloggter Kunde: eigene Kasse mit eigenen Adressen, nur Zahlart vorbelegt.
|
||||
$logged_in = $this->base_object->customer->customer_id
|
||||
&& (int)$this->base_object->customer->customer_id !== (int)$this->base_object->config->shopConfiguration['guest_order_customer_id'];
|
||||
header('Location: /Kasse/'.($logged_in ? '' : '?guest_order=1'));
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kasse mit den Express-Daten vorbelegen (Gast: Adresse + E-Mail + Zahlart,
|
||||
* eingeloggt: nur Zahlart). Nur beim reinen Anzeigen -- ein POST des Kunden gewinnt.
|
||||
*/
|
||||
private function payment_express_prefill() {
|
||||
$e = isset($_SESSION['easyshop']['payment_express']) ? $_SESSION['easyshop']['payment_express'] : null;
|
||||
if (!is_array($e) || empty($e['module']) || empty($e['reference'])) {
|
||||
return;
|
||||
}
|
||||
if ((time() - (int)$e['time']) > 3600) {
|
||||
unset($_SESSION['easyshop']['payment_express']);
|
||||
return;
|
||||
}
|
||||
$pm_id = 0;
|
||||
$res = $this->base_object->db->query("SELECT id FROM payment_methods WHERE module='".$this->base_object->db->real_escape_string($e['module'])."' AND active=1 LIMIT 1");
|
||||
if ($res && ($r = $res->fetch_object())) {
|
||||
$pm_id = (int)$r->id;
|
||||
}
|
||||
$this->layout_object->assign('express_active', 1);
|
||||
$this->layout_object->assign('express_label', ucfirst(str_replace('_', ' ', $e['module'])));
|
||||
|
||||
if (isset($_POST['cashdesk_action']) || isset($_POST['save_address'])) {
|
||||
return; // Kunde hat das Formular selbst abgeschickt
|
||||
}
|
||||
if ($pm_id) {
|
||||
$_POST['payment_method'] = $pm_id;
|
||||
}
|
||||
$is_guest = isset($_GET['guest_order']) && $_GET['guest_order'] == 1;
|
||||
if (!$is_guest) {
|
||||
return;
|
||||
}
|
||||
$addr = array(
|
||||
'honorific' => '',
|
||||
'company' => (string)$e['company'],
|
||||
'firstname' => (string)$e['firstname'],
|
||||
'surname' => (string)$e['surname'],
|
||||
'street' => (string)$e['street'],
|
||||
'house_number' => (string)$e['house_number'],
|
||||
'zip_code' => (string)$e['zip_code'],
|
||||
'city' => (string)$e['city'],
|
||||
'country' => (int)$e['country_id'],
|
||||
);
|
||||
$_POST['billing'] = $addr + array('email' => (string)$e['email'], 'address' => '', 'billing_address' => '');
|
||||
$_POST['shipping'] = $addr + array('address' => -1); // -1 = wie Rechnungsadresse
|
||||
$this->personal_data = $_POST;
|
||||
}
|
||||
|
||||
/**
|
||||
* 13.09.2026 -- Zahlungsanbieter aus core/payments.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user