A webhook must return before it does the work

A webhook is a notification with a sender that has a timeout and a retry policy you do not control.

public function handle(Request $request): Response
{
    $this->verifySignature($request);      // fast, and first

    ReceivedWebhook::create([
        'provider' => 'payments',
        'payload'  => $request->getContent(),
    ]);

    ProcessWebhook::dispatch($id);

    return response()->noContent();        // under 100ms
}

Doing the work inline means the provider’s timeout becomes your latency budget, and exceeding it triggers a retry that arrives while the first is still running. Persisting the raw payload before processing is what makes the event recoverable when the handler has a bug — the work can be replayed from the stored body without asking the provider to resend. Returning 200 for anything you have durably stored, including a payload you cannot parse, is correct: a parse error is your problem, not a reason for the provider to retry.