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:
Thomas Bartelt
2026-09-13 21:44:46 +02:00
parent e4b3f5a1ea
commit f33533b411
9 changed files with 438 additions and 4 deletions
+52
View File
@@ -426,4 +426,56 @@ abstract class AbstractProvider implements ProviderInterface
{
return [];
}
// ------------------------------------------------------- Express-Defaults
public function supportsExpress(): bool
{
return false;
}
public function startExpress(float $amount): string
{
throw new \RuntimeException($this->label() . ': kein Express-Weg');
}
public function onExpressReturn(array $query): ?array
{
return null;
}
public function finishExpress(int $orderId, float $amount, string $reference): string
{
throw new \RuntimeException($this->label() . ': kein Express-Weg');
}
/** Express-Rueckkehr laeuft ueber den Cashdesk, ohne Bestellung. */
protected function expressReturnUrl(): string
{
return $this->shopBaseUrl() . '/Kasse/?payment_express=' . $this->module();
}
protected function expressCancelUrl(): string
{
return $this->shopBaseUrl() . '/Warenkorb/?payment_express_cancel=' . $this->module();
}
/** countries.id zu einem ISO-3166-Alpha-2-Code, 0 wenn das Land im Shop nicht lieferbar ist. */
public function countryIdByIso(string $iso): int
{
$iso = $this->db->real_escape_string(\strtoupper($iso));
$res = $this->db->query("SELECT id FROM countries WHERE iso_code_2='$iso' ORDER BY rang DESC, id LIMIT 1");
$r = $res ? $res->fetch_object() : null;
return $r ? (int) $r->id : 0;
}
/** "Neuer Weg 5a" -> ["Neuer Weg", "5a"]; ohne erkennbare Nummer bleibt alles Strasse. */
public static function splitStreet(string $line): array
{
$line = \trim($line);
if (\preg_match('/^(.*?)[\s,]+(\d+[\s\-\/]?[a-zA-Z0-9\-\/]*)$/u', $line, $m)) {
return [\trim($m[1]), \trim($m[2])];
}
return [$line, ''];
}
}