›
›
›
  1. docs
  2. ›
  3. byrcsc/laravel-payrex
1.x
Browse documentationOpenClose

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Client and resources
  • Data objects and enums
  • Errors and retries
  • Pagination

Accepting payments

  • Payment intents
  • Checkout sessions
  • Setup intents
  • Payments and refunds

Customers and billing

  • Customers
  • Eloquent customers
  • Billing statements
  • Payouts

Webhooks

  • Receiving webhooks
  • Events and listeners
  • Managing endpoints

Advanced usage

  • Testing
  • Security and operations
  • Troubleshooting

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Client and resources
  • Data objects and enums
  • Errors and retries
  • Pagination

Accepting payments

  • Payment intents
  • Checkout sessions
  • Setup intents
  • Payments and refunds

Customers and billing

  • Customers
  • Eloquent customers
  • Billing statements
  • Payouts

Webhooks

  • Receiving webhooks
  • Events and listeners
  • Managing endpoints

Advanced usage

  • Testing
  • Security and operations
  • Troubleshooting

byrcsc/laravel-payrex · 1.x

Receiving webhooks.

Verify PayRex webhook requests before dispatching Laravel events.

Laravel PayRex registers:

POST /payrex/webhook

The route is named payrex.webhook, so route('payrex.webhook') gives you the absolute URL to register with PayRex. Point 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-Signature

The 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.

The signature header

Payrex-Signature looks like t=1700000000,te=<hex>,li=<hex>: a Unix timestamp, then the test-mode and live-mode signatures. Exactly one of the two is populated, depending on which set of keys produced the event, and each is HMAC-SHA256("{timestamp}.{payload}", secret) in lowercase hex. The package checks both slots against the configured secret, so a test-mode secret can never verify a live delivery. Mismatched modes are the usual cause of a 400 on an otherwise correct endpoint.

Signature freshness

The default tolerance is 300 seconds. A signed delivery whose timestamp is older than the tolerance is rejected; a timestamp in the future is not. Keep the server clock synchronized.

Set the value to 0 only when you intentionally want to disable timestamp freshness checking:

PAYREX_WEBHOOK_TOLERANCE=0

Freshness 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=false

Then 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.

What to read next

  • Events and listeners to handle typed webhook events.
  • Managing endpoints to register the route with PayRex.
  • Testing to send signed webhook requests in application tests.
PreviousPayoutsNextEvents and listeners

Laravel PayRex is an unofficial community SDK and is not affiliated with PayRex.

View source

On this page

  1. Configure the route
  2. Add middleware
  3. The signature header
  4. Signature freshness
  5. Delivery failures
  6. Use a custom route
  7. Respond quickly
  8. What to read next