Files
ms1inscription-v5/paypal_advanced/PaypalWebhook.class.php
2026-05-13 09:43:32 -04:00

118 lines
4.2 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/php/inc_start_time.php');
require_once($_SERVER['DOCUMENT_ROOT'].'/php/inc_fonctions.php');
require_once($_SERVER['DOCUMENT_ROOT'].'/paypal_advanced/PaypalCheckout.class.php'); // ta classe existante
class PayPalWebhook
{
private string $clientId;
private string $secret;
private string $apiBase;
private string $webhookId;
private bool $isSandbox;
public function __construct()
{
$this->isSandbox = PAYPAL_SANDBOX;
$this->clientId = PAYPAL_CLIENT_ID;
$this->secret = PAYPAL_CLIENT_SECRET;
$this->apiBase = PAYPAL_BASE_URL;
$this->webhookId = PAYPAL_WEBHOOK_ID;
}
/**
* Vérifie la signature de lévénement envoyé par PayPal.
*/
public function verifySignature(array $headers, string $body): bool
{
$token = $this->getAccessToken();
if (!$token) return false;
$payload = [
'auth_algo' => $headers['paypal-auth-algo'] ?? '',
'cert_url' => $headers['paypal-cert-url'] ?? '',
'transmission_id' => $headers['paypal-transmission-id'] ?? '',
'transmission_sig' => $headers['paypal-transmission-sig'] ?? '',
'transmission_time' => $headers['paypal-transmission-time'] ?? '',
'webhook_id' => $this->webhookId,
'webhook_event' => json_decode($body, true),
];
$ch = curl_init($this->apiBase.'/v1/notifications/verify-webhook-signature');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.$token,
'Content-Type: application/json'
],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$res = curl_exec($ch);
$http= curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http !== 200) return false;
$json = json_decode($res, true);
return ($json['verification_status'] ?? '') === 'SUCCESS';
}
private function getAccessToken(): ?string
{
$ch = curl_init($this->apiBase.'/v1/oauth2/token');
curl_setopt_array($ch, [
CURLOPT_USERPWD => $this->clientId.':'.$this->secret,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => 'grant_type=client_credentials',
CURLOPT_RETURNTRANSFER => true,
]);
$res = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http !== 200) return null;
$json = json_decode($res, true);
return $json['access_token'] ?? null;
}
/**
* Point dentrée du webhook
*/
public function handleEvent(string $body, array $headers)
{
// 1⃣ Vérification signature
if (!$this->verifySignature($headers, $body)) {
http_response_code(400);
echo json_encode(['error' => 'Signature invalide']);
return;
}
// 2⃣ Décodage événement
$event = json_decode($body, true);
$type = $event['event_type'] ?? '';
$resource = $event['resource'] ?? [];
if (in_array($type, ['PAYMENT.CAPTURE.REFUNDED','PAYMENT.REFUND.COMPLETED'])) {
$captureId = null;
foreach ((array)($resource['links'] ?? []) as $lnk) {
if (($lnk['rel'] ?? '') === 'up' && strpos($lnk['href'], '/captures/') !== false) {
$captureId = basename($lnk['href']);
}
}
if ($captureId) {
// 3⃣ Charger les détails avec ta classe PayPalCheckout
$checkout = new PayPalCheckout();
$capture = $checkout->getCaptureDetails($captureId);
$refunds = $checkout->getRefundsForCapture($capture);
// 4⃣ Enregistrer ou mettre à jour la DB
file_put_contents(__DIR__.'/paypal_refund_log.txt', print_r($refunds,true), FILE_APPEND);
}
}
http_response_code(200);
echo json_encode(['status'=>'ok']);
}
}