Django-ninja Webhook Server - Signature Error/Bad Request

I am working on a Django application where I have to develop a webhook server using Django-ninja. The webhook app receives a new order notification as described here: https://developer.wolt.com/docs/marketplace-integrations/restaurant-advanced#webhook-server

My code below:

@api.post("/v1/wolt-new-order")
def wolt_new_order(request: HttpRequest):

    received_signature = request.headers.get('wolt-signature')
    if not received_signature:
        print("Missing signature")
        return HttpResponse('Missing signature', status=400)


    payload = request.body


    expected_signature = hmac.new(
        CLIENT_SECRET.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    
    print(f"Received: {received_signature}")
    print(f"Expected: {expected_signature}")


    if not hmac.compare_digest(received_signature, expected_signature):
        return HttpResponse('Invalid signature', status=400)

    print(payload)

    return HttpResponse('Webhook received', status=200)

For some reason this always returns 'error code 400, bad request syntax' and the two signatures are always different.

I am importing the CLIENT_SECRET correctly and I have all the necessary libraries properly installed.

Funny enough when I do the same on a test Flask app, I receive the webhook notification correctly without issues.

Flask code below:

import hmac
import hashlib
from flask import Flask, request, abort

app = Flask(__name__)

@app.route('/api/v1/wolt-new-order', methods=['POST'])
def webhook():
    # Extract the wolt-signature header
    received_signature = request.headers.get('wolt-signature')
    
    print(received_signature)

    # Extract the request payload
    payload = request.get_data()
    
    print(payload)

    # Compute the expected signature
    expected_signature = hmac.new(
        CLIENT_SECRET.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    
    print(expected_signature)

    # Compare signatures
    if not hmac.compare_digest(received_signature, expected_signature):
        abort(400, 'Invalid signature')

    
    print(payload)

    return 'Webhook received', 200

if __name__ == '__main__':
    app.run(port=8000)

My webhook server is behind ngrok. Any ideas?

What am I doing wrong here? Any suggestions?

Back to Top