feat(payments): Anbieter-Gerüst core/payments mit PayPal Orders v2

- ProviderInterface/AbstractProvider: Vorgang mit Uhrzeit+Session (payment_transactions),
  Mail und Warenkorb erst nach Zahlung, idempotentes markPaid, Betragsabgleich,
  shop_event + PG payment_log
- Secrets verschluesselt (libsodium) in MySQL, Schluessel ausserhalb Docroot
- Cashdesk: ?payment_return/?payment_cancel, Pending-Riegel, zahlung_erst_spaeter()
- Backend Zahlart-Editor: Einstellungen speichern (war ohne Empfaenger), Secret-Felder
- payment_webhook.php (Standalone), cli.php (init-key, secret, reconcile, status)
- PayPal-v2-Blaupause vom Juli entfernt
This commit is contained in:
Thomas Bartelt
2026-09-13 19:51:52 +02:00
parent af81e8f63a
commit 397fb5944a
30 changed files with 2002 additions and 1104 deletions
@@ -35,11 +35,36 @@
<input style="position:relative;left:185px;width: 200px;" type="submit" name="submit" id="submit" value="Zahlungsart speichern" />
</form>
</div>
{if $config_data}
{if $config_data || $provider_secrets}
<div title="Einstellungen" id="einstellungen">
<form class="edit" method="POST">
<input type="hidden" name="modul" value="admin_country_editor" />
<input type="hidden" id="id" name="id" value="{$form_data->configuration_group_id}" />
<input type="hidden" name="payment_config_save" value="1" />
<input type="hidden" name="id" value="{$form_data->id}" />
{if $provider_secrets}
<div class="edit_title">Zugangsdaten {$provider_label|escape} (verschl&uuml;sselt gespeichert)</div>
{if !$provider_key_ok}
<div class="edit_element_1_1" style="color:#b00;">
Schl&uuml;sseldatei fehlt: {$provider_key_path|escape}<br>
Anlegen per SSH: <code>/opt/plesk/php/8.2/bin/php core/payments/cli.php init-key</code>
</div>
<div class="edit_endline"></div>
{/if}
{foreach from=$provider_secrets item=sec}
<div class="edit_element_2_5">
<label>{$sec.label|escape}</label>
<input name="secret_field[{$sec.name}]" value="" type="password" autocomplete="new-password" placeholder="{if $sec.since}hinterlegt, leer lassen = unver&auml;ndert{else}noch nicht hinterlegt{/if}" {if !$provider_key_ok}disabled{/if} />
</div>
<div class="edit_element_3_5">
<br>{if $sec.since}hinterlegt seit {$sec.since|escape}{else}<span style="color:#b00;">fehlt</span>{/if}
</div>
<div class="edit_endline"></div>
{/foreach}
<div class="edit_element_1_1">
<br>Webhook-URL f&uuml;r das PayPal-Dashboard: <code>{$provider_webhook_url|escape}</code>
</div>
<div class="edit_endline"></div>
<div class="edit_title">Einstellungen</div>
{/if}
{foreach from=$config_data item=form_element}
{if $form_element->text == 'multi'}
<div class="edit_element_1_1" style="height:200px;">