byrcsc/laravel-payrex · 1.x
Receiving webhooks.
Receive PayRex webhooks through the package route, verify signatures and timestamps, or build a verified custom route.
Laravel PayRex registers:
POST /payrex/webhookPoint a PayRex webhook endpoint at that URL and put its signing secret in the application environment:
PAYREX_WEBHOOK_SECRET=whsk_test_...The package verifies the signature against the untouched request body, parses the event, dispatches Laravel events, and returns:
{ "received": true, "id": "evt_..." }Configure the route
The webhook options live under webhooks in config/payrex.php:
'webhooks' => [
'enabled' => true,
'path' => 'payrex/webhook',
'tolerance' => 300,
'header' => 'Payrex-Signature',
'middleware' => [],
'events' => [
// event type => Laravel event class
],
],The matching environment variables are:
PAYREX_WEBHOOKS_ENABLED=true
PAYREX_WEBHOOK_PATH=payrex/webhook
PAYREX_WEBHOOK_TOLERANCE=300
PAYREX_WEBHOOK_HEADER=Payrex-SignatureThe route is deliberately outside Laravel's web and CSRF middleware. A
machine callback has no browser session; its signature authenticates it
instead.
Add middleware
Add rate limiting or application-specific middleware without removing signature verification:
'webhooks' => [
// ...
'middleware' => [
'throttle:60,1',
],
],The package always prepends VerifyPayrexSignature.
Signature freshness
The default tolerance is 300 seconds. A signed delivery whose timestamp is older than the tolerance is rejected. Keep the server clock synchronized.
Set the value to 0 only when you intentionally want to disable timestamp
freshness checking:
PAYREX_WEBHOOK_TOLERANCE=0Freshness is not replay protection. An attacker cannot change a signed body, but a valid delivery can still be replayed within the window. PayRex also retries real deliveries. Deduplicate completed work using the event ID.
Delivery failures
An absent, malformed, invalid, or stale signature raises
SignatureVerificationException and returns HTTP 400. A signed body that is
not a valid PayRex event raises InvalidPayloadException and also returns 400.
Monitor bursts of signature failures. They can indicate a wrong secret, clock drift, a proxy changing the raw body, or unsolicited traffic.
Use a custom route
Disable the package route:
PAYREX_WEBHOOKS_ENABLED=falseThen verify and decode with parseEvent():
use ByRcsc\LaravelPayrex\Facades\Payrex;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::post('/webhooks/payrex', function (Request $request) {
$event = Payrex::parseEvent(
payload: $request->getContent(),
header: $request->header('Payrex-Signature'),
);
// Dispatch or process the verified event.
return response()->json([
'received' => true,
'id' => $event->id,
]);
});Call getContent() before anything rewrites the body. parseEvent() uses the
configured signing secret and tolerance and returns a typed WebhookEvent.
When you own the route, you also own event dispatching, response timing,
middleware, and exception behavior.
Respond quickly
Keep the HTTP path short. The package dispatches events synchronously, so make
your listeners implement ShouldQueue. A slow or failed delivery can be
retried by PayRex for up to three days with exponential backoff.