63 lines
1.8 KiB
PHP
63 lines
1.8 KiB
PHP
<?php
|
||
/**
|
||
* Webhook-Endpunkt fuer PayPal-v2.
|
||
*
|
||
* Dient als verlaessliche Quelle des Zahlstatus (server-zu-server), unabhaengig
|
||
* davon, ob der Kunde nach der Zahlung tatsaechlich zum Shop zurueckkehrt.
|
||
*
|
||
* PayPal-Dashboard: Webhook auf diese URL anlegen, mindestens Event
|
||
* PAYMENT.CAPTURE.COMPLETED
|
||
* abonnieren und die entstehende Webhook-ID in die Config eintragen.
|
||
*/
|
||
declare(strict_types=1);
|
||
|
||
require __DIR__ . '/bootstrap.php';
|
||
|
||
use PaypalV2\Webhook;
|
||
use PaypalV2\Gateway;
|
||
|
||
$rawBody = (string) \file_get_contents('php://input');
|
||
|
||
// Header einsammeln (lowercase Keys)
|
||
$headers = [];
|
||
foreach ($_SERVER as $key => $value) {
|
||
if (\strncmp($key, 'HTTP_', 5) === 0) {
|
||
$name = \strtolower(\str_replace('_', '-', \substr($key, 5)));
|
||
$headers[$name] = (string) $value;
|
||
}
|
||
}
|
||
|
||
// Signatur verifizieren – sonst sofort ablehnen
|
||
try {
|
||
if (!(new Webhook())->verify($headers, $rawBody)) {
|
||
\http_response_code(400);
|
||
echo 'invalid signature';
|
||
exit;
|
||
}
|
||
} catch (\Throwable $e) {
|
||
\error_log('PayPal v2 webhook verify: ' . $e->getMessage());
|
||
\http_response_code(500);
|
||
exit;
|
||
}
|
||
|
||
$event = \json_decode($rawBody, true);
|
||
$type = \is_array($event) ? (string) ($event['event_type'] ?? '') : '';
|
||
|
||
try {
|
||
if ($type === 'PAYMENT.CAPTURE.COMPLETED') {
|
||
$resource = $event['resource'] ?? [];
|
||
if (\is_array($resource)) {
|
||
(new Gateway($base_object))->confirmFromWebhookCapture($resource);
|
||
}
|
||
}
|
||
// Weitere Event-Typen (Refund/Denied) koennen hier ergaenzt werden.
|
||
} catch (\Throwable $e) {
|
||
\error_log('PayPal v2 webhook handle (' . $type . '): ' . $e->getMessage());
|
||
\http_response_code(500);
|
||
exit;
|
||
}
|
||
|
||
// PayPal erwartet 2xx, sonst wird das Event erneut zugestellt.
|
||
\http_response_code(200);
|
||
echo 'ok';
|