146 lines
5.0 KiB
PHP
146 lines
5.0 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
|
||
/**
|
||
* Zahlungsart "PayPal Checkout (Orders v2 / REST)".
|
||
*
|
||
* Neues, eigenstaendiges Modul – laeuft parallel zum Legacy-NVP-Modul
|
||
* (PaypalPaymentMethod) und teilt sich mit ihm KEINEN Code.
|
||
*
|
||
* Aktivierung ueber einen eigenen Eintrag in `payment_methods` mit
|
||
* module = 'paypalrest'. Der Cashdesk instanziiert dann automatisch diese
|
||
* Klasse (ucfirst('paypalrest').'PaymentMethod' => PaypalrestPaymentMethod).
|
||
*
|
||
* Flow: after_order() legt die PayPal-Order an und leitet den Kunden zur
|
||
* Approve-URL weiter. Der Rueckweg laeuft NICHT ueber den Cashdesk (der ist auf
|
||
* das Legacy-Modul verdrahtet), sondern ueber /core/paypal_v2/return.php.
|
||
*/
|
||
|
||
require_once __DIR__ . '/../paypal_v2/Config.php';
|
||
require_once __DIR__ . '/../paypal_v2/PayPalClient.php';
|
||
require_once __DIR__ . '/../paypal_v2/Orders.php';
|
||
require_once __DIR__ . '/../paypal_v2/Gateway.php';
|
||
|
||
class PaypalrestPaymentMethod
|
||
{
|
||
private $base_object;
|
||
private $layout_object;
|
||
|
||
private $customer_data;
|
||
private $shipping_address;
|
||
private $billing_address;
|
||
private $shoppingcart;
|
||
private $payment_method;
|
||
private $shipping_method;
|
||
private $gift_certificate;
|
||
private $order_id;
|
||
|
||
public function __construct($base_object, $layout_object)
|
||
{
|
||
$this->base_object = $base_object;
|
||
$this->layout_object = $layout_object;
|
||
|
||
$this->customer_data = false;
|
||
$this->shipping_address = false;
|
||
$this->billing_address = false;
|
||
$this->shoppingcart = false;
|
||
$this->payment_method = false;
|
||
$this->shipping_method = false;
|
||
$this->gift_certificate = false;
|
||
$this->order_id = false;
|
||
}
|
||
|
||
public function set_data($customer, $shipping, $billing, $shoppingcart, $delivery, $payment, $order_id = false)
|
||
{
|
||
$this->customer_data = $customer;
|
||
$this->shipping_address = $shipping;
|
||
$this->billing_address = $billing;
|
||
$this->shoppingcart = $shoppingcart;
|
||
$this->payment_method = $delivery;
|
||
$this->shipping_method = $payment;
|
||
$this->order_id = $order_id;
|
||
}
|
||
|
||
public function set_gift_certificate($gift_certificate)
|
||
{
|
||
$this->gift_certificate = $gift_certificate;
|
||
}
|
||
|
||
public function set_order_id($order_id)
|
||
{
|
||
$this->order_id = $order_id;
|
||
}
|
||
|
||
/** Vom Cashdesk vor dem Speichern aufgerufen. Kein Fehler => leere Rueckgabe. */
|
||
public function before_order($argument = null)
|
||
{
|
||
return '';
|
||
}
|
||
|
||
public function during_order($argument = null)
|
||
{
|
||
return '';
|
||
}
|
||
|
||
/**
|
||
* Nach dem Speichern des Auftrags: PayPal-Order anlegen und weiterleiten.
|
||
*
|
||
* @param float|false $order_total Bruttosumme des Auftrags
|
||
* @return string HTML-Fallback (nur, wenn keine Weiterleitung moeglich war)
|
||
*/
|
||
public function after_order($order_total = false)
|
||
{
|
||
$charged = (float) $order_total;
|
||
|
||
// Gutschein wie im Legacy-Modul vom zu zahlenden Betrag abziehen
|
||
if ($this->gift_certificate && isset($this->gift_certificate->with_vat)) {
|
||
$charged -= (float) $this->gift_certificate->with_vat;
|
||
}
|
||
|
||
try {
|
||
$gateway = new \PaypalV2\Gateway($this->base_object);
|
||
$order_number = $this->resolve_order_number((int) $this->order_id);
|
||
$approve_url = $gateway->createOrderAndGetApprovalUrl((int) $this->order_id, $charged, $order_number);
|
||
} catch (\Throwable $e) {
|
||
\error_log('PayPal v2 after_order: ' . $e->getMessage());
|
||
return $this->render_error('Beim Initialisieren von PayPal ist ein Fehler aufgetreten.');
|
||
}
|
||
|
||
// Bevorzugt harte Weiterleitung (an dieser Stelle sind noch keine Header gesendet).
|
||
if (!\headers_sent()) {
|
||
\header('Location: ' . $approve_url);
|
||
exit;
|
||
}
|
||
|
||
// Fallback: Button/Meta-Refresh im Template
|
||
$this->layout_object->assign('call', 'payment_open');
|
||
$this->layout_object->assign('paypal_link', $approve_url);
|
||
return $this->layout_object->_fetch('content_cash_desk/paypalrest.tpl');
|
||
}
|
||
|
||
/** Wird vom Cashdesk fuer dieses Modul NICHT aufgerufen (Return laeuft ueber return.php). */
|
||
public function change_order()
|
||
{
|
||
return '';
|
||
}
|
||
|
||
// ---------------------------------------------------------------- intern
|
||
|
||
private function resolve_order_number(int $order_id): string
|
||
{
|
||
$db = $this->base_object->db;
|
||
$res = $db->query('SELECT order_number FROM orders WHERE id=' . $order_id . ' LIMIT 1');
|
||
if ($res && $res->num_rows > 0) {
|
||
return (string) $res->fetch_object()->order_number;
|
||
}
|
||
return (string) $order_id;
|
||
}
|
||
|
||
private function render_error(string $message): string
|
||
{
|
||
$this->layout_object->assign('call', 'payment_error');
|
||
$this->layout_object->assign('message', $message);
|
||
return $this->layout_object->_fetch('content_cash_desk/paypalrest.tpl');
|
||
}
|
||
}
|