Add PayPal webhook handling
This commit is contained in:
62
app/Services/PayPal/PayPalWebhookVerifier.php
Normal file
62
app/Services/PayPal/PayPalWebhookVerifier.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\PayPal;
|
||||
|
||||
use App\Services\PayPal\Exceptions\PayPalException;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class PayPalWebhookVerifier
|
||||
{
|
||||
public function __construct(private readonly PayPalClient $client) {}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $payload
|
||||
*/
|
||||
public function verify(Request $request, array $payload): bool
|
||||
{
|
||||
$webhookId = config('services.paypal.webhook_id');
|
||||
|
||||
if (! is_string($webhookId) || $webhookId === '') {
|
||||
if (app()->environment('production')) {
|
||||
Log::warning('PayPal webhook verification skipped: webhook id missing.');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$signature = (string) $request->headers->get('PAYPAL-TRANSMISSION-SIG', '');
|
||||
|
||||
if ($signature === '') {
|
||||
Log::warning('PayPal webhook missing signature header.', [
|
||||
'header' => 'PAYPAL-TRANSMISSION-SIG',
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$payload = array_filter([
|
||||
'auth_algo' => $request->headers->get('PAYPAL-AUTH-ALGO'),
|
||||
'cert_url' => $request->headers->get('PAYPAL-CERT-URL'),
|
||||
'transmission_id' => $request->headers->get('PAYPAL-TRANSMISSION-ID'),
|
||||
'transmission_sig' => $signature,
|
||||
'transmission_time' => $request->headers->get('PAYPAL-TRANSMISSION-TIME'),
|
||||
'webhook_id' => $webhookId,
|
||||
'webhook_event' => $payload,
|
||||
], static fn ($value) => $value !== null && $value !== '');
|
||||
|
||||
try {
|
||||
$response = $this->client->post('/v1/notifications/verify-webhook-signature', $payload);
|
||||
} catch (PayPalException $exception) {
|
||||
Log::warning('PayPal webhook verification failed', [
|
||||
'message' => $exception->getMessage(),
|
||||
'status' => $exception->status(),
|
||||
'context' => $exception->context(),
|
||||
]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return strtoupper((string) ($response['verification_status'] ?? '')) === 'SUCCESS';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user