enqueue($eventType, (string) wp_json_encode($payload), 5); Logger::info('webhook', "Queued webhook {$eventType}"); } public function processQueue(): int { $repo = new WpWebhookQueueRepository(); $sender = new WebhookSender(); $processed = 0; foreach ($repo->dueItems(50) as $item) { $payload = json_decode($item->payloadJson, true); if (!is_array($payload)) { $repo->markInvalid($item->id, 'Invalid payload JSON'); continue; } // `deliver()`, jamais `send()` : la file compte elle-même ses tentatives. $result = $sender->deliver($item->eventType, $payload); if ($result->sent) { $repo->markSent($item->id); $processed++; continue; } if (!$result->retryable) { $repo->markInvalid($item->id, 'Non relivrable'); continue; } $decision = WebhookRetryPolicy::decide($item->attempts, $item->maxAttempts); if ($decision->abandon) { $repo->markFailed($item->id, $decision->attempts, 'Max attempts reached'); } else { $repo->reschedule($item->id, $decision->attempts, $decision->delayMinutes); } } return $processed; } }