loadInbox = Closure::fromCallable($loadInbox); $this->createInbox = Closure::fromCallable($createInbox); $this->reloadInbox = Closure::fromCallable($reloadInbox); $this->process = Closure::fromCallable($process); $this->markFailed = Closure::fromCallable($markFailed); $this->isDuplicateKey = Closure::fromCallable($isDuplicateKey); } /** @param array $payload @return array */ public function handle(array $payload): array { $eventId = trim((string) ($payload['event_id'] ?? '')); if ($eventId === '') { return ['http_status' => 422, 'message' => 'event_id is required', 'duplicate' => false]; } $inbox = ($this->loadInbox)($eventId); if (is_array($inbox) && strtoupper((string) ($inbox['process_status'] ?? '')) === 'PROCESSED') { return ['http_status' => 200, 'message' => 'ok', 'duplicate' => true]; } if (!is_array($inbox)) { try { $inbox = ($this->createInbox)($payload); } catch (Throwable $exception) { if (!(bool) ($this->isDuplicateKey)($exception)) { return ['http_status' => 500, 'message' => $exception->getMessage(), 'duplicate' => false]; } $inbox = ($this->reloadInbox)($eventId); if (!is_array($inbox)) { return ['http_status' => 500, 'message' => 'callback inbox race could not be reloaded', 'duplicate' => false]; } if (strtoupper((string) ($inbox['process_status'] ?? '')) === 'PROCESSED') { return ['http_status' => 200, 'message' => 'ok', 'duplicate' => true]; } } } try { ($this->process)($inbox, $payload); return ['http_status' => 200, 'message' => 'ok', 'duplicate' => false]; } catch (EjPharmacyCallbackRetryException $exception) { ($this->markFailed)($inbox, $exception->getMessage()); return ['http_status' => 503, 'message' => $exception->getMessage(), 'duplicate' => false]; } catch (InvalidArgumentException|DomainException $exception) { ($this->markFailed)($inbox, $exception->getMessage()); return ['http_status' => 422, 'message' => $exception->getMessage(), 'duplicate' => false]; } catch (Throwable $exception) { ($this->markFailed)($inbox, $exception->getMessage()); return ['http_status' => 500, 'message' => $exception->getMessage(), 'duplicate' => false]; } } }