Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jordis92's avatar

TokenMismatchException webhook issue

For a website I'm using the Mollie API for handling payments, and I just can't figure out what I'm doing wrong trying to work around the CSRF verification. I'm using Laravel 5.1.

My VerifyCsrfToken class:

protected $except = [
        'foo/bar',
    ];

My route file:

Route::post('foo/bar', 'PaymentController@webhook');

I keep getting the TokenMismatchException error whenever the webhook is called. Anyone know what I'm missing?

0 likes
4 replies
Rygu's avatar

Hello, I work at Mollie. The webhookUrl is requested directly from one of our payment platform's server. The request won't have the same session state, nor does it know which CSRF token to post in the request. So you should consider the webhook request to be naive and stateless.

The easiest way to resolve this is to disable CSRF verification for the webhook controller. In case that's not an option then include the correct CSRF token in the "webhookUrl" as a GET parameter when you create the payment. Be careful if you do that, make sure the CSRF token is reusable and will not expire, as the webhook could be requested at a (much) later time.

I do recommend against CSRF verification for webhooks, as long as you verify the posted payment "id" is an actual payment that your system knows before acting upon the webhook.

Rick

robertarissen's avatar

@Rygu

I work together with Jordi. This error do we have now.

[2015-12-15 10:42:25] local.ERROR: exception 'Illuminate\Session\TokenMismatchException' in /opt/bitnami/apache2/htdocs/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php:53
Stack trace:
#0 [internal function]: Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure))
#1 /opt/bitnami/apache2/htdocs/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array)
#2 /opt/bitnami/apache2/htdocs/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#3 [internal function]: Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#4 /opt/bitnami/apache2/htdocs/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array)
#5 /opt/bitnami/apache2/htdocs/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(62): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#6 [internal function]: Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#7 /opt/bitnami/apache2/htdocs/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(124): call_user_func_array(Array, Array)

The route file:

Route::match(['post'], 'molliepayments/webhook', [
    'as' => 'mollie.webhook', 'uses' => 'PaymentController@webhook'
]);

And the VerifyCsrfToken file:

protected $except = [
        '/molliepayments/webhook',
        'molliepayments/webhook',
        'molliepayments/*',
    ];

What do we wrong?

harryg's avatar
harryg
Best Answer
Level 5

There are 2 ways I know of to disable middleware on a particular route/action:

  1. Extend the class and define some urls for which to skip csrf checks on. See this answer https://laracasts.com/discuss/channels/general-discussion/l5-disable-csrf-middleware-on-certain-routes

  2. In the case of route middleware you can define the middleware on a particular controller action. By default the CSRF middleware is global so will apply to all routes. To use this option you should move it from the $middleware array to the $routeMiddleware array in app/http/Kernal.php along with a key to reference the middleware with. You can then define where it applies in your controller.

In your PaymentController put something like the following in the constructor:

class PaymentController extends Controller
{   
     public function __construct()
     {
         $this->middleware('csrf', ['except' => ['webhook']]);
     }
}

See http://laravel.com/docs/5.1/controllers#controller-middleware

Please or to participate in this conversation.