Securing webhook request

EelcoEelco Member Posts: 8
Hi all,

We are using the Lightspeed webhooks a lot, and want to validate them now. We work in PHP.

"The header "X-Signature" should be available and is a md5 hash of the incoming payload . app_secret of the .env file"

Now when we retrieve a webhook, we get the data of it via $request->all(). I can also retrieve the X-Signature via $request->header('X-Signature')

However, when I do md5($request->all() . app_secret), this does not match the md5 hash in $request->header('X-Signature').

Anyone knows what I'm doing wrong?

Kind regards,


  • JaivyDaamJaivyDaam Lightspeed Staff Posts: 29 Lightspeed
    Hi @Eelco,

    this is a difficult one, it seems that the Hash process on the server doesn't match the one you are using. I will have to go over this with the Dev team to see if I can get a straight answer. 

    I will get back to you as soon as I've received an update. Thank you!
  • jamesratcliffejamesratcliffe Administrator, Lightspeed Staff Posts: 160 moderator
    @Eelco What's the output of $request->all()? This will usually give the request input as an array, so I don't think this is what you want.

    I would try $request->getBody().
    James Ratcliffe
    Lightspeed HQ
  • ZakaZaka Member Posts: 1
    edited November 2020

    Hi all,

    This is indeed an issue and this is both related to Lightspeed and your own PHP environment. Validating an X-Signature goes like this:

    md5(json_encode($request->all()) . $apiSecret);

    However IF the outcome of this is still mismatching your X-Signature , that means the problem is related to your PHP settings.

    In your php.ini, there is an option called serialize_precision. You will have to make sure that this is set to -1

    Another way to solve this issue is temporarily use a ini_set before you do the comparison calculation:

    if (version_compare(phpversion(), '7.1', '>=')) {
        ini_set( 'serialize_precision', -1 );

    What does this do??? Lightspeed sends 14 decimal prices. Their X-Signatures are calculated in 2 decimals only. But without the -1 option, your will calculate the 14 decimal prices instead of 2 decimals, which as result is a different hash.

    This happens pretty often when a legacy production server which was running PHP 5.x and upgraded to PHP 7.x. Some DevOps are blindly inheriting the old php.ini.

    I hope this helps and you are welcome!!!


    Zaka Masters

Sign In or Register to comment.