robinnlmn
robinnlmn

Reputation: 31

Stripe Construct Event: No signatures found matching the expected signature for payload. Javascript, Express

I get an error whenever I try to construct the stripe webhook event:

No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing

Cannot figure out how to solve this, already lot of json parsing methods but no one worked.

Here's my code:

app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
    const signature = req.headers['stripe-signature'];
    console.log(signature);
    const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;

    let event;

    try {
        event = stripe.webhooks.constructEvent(req.body, signature, endpointSecret);
    } catch (err) {
        res.status(400).send(`Webhook Error: ${err.message}`);
        console.log(`Webhook Error: ${err.message}`);
        return;
    }

    switch (event.type) {
        case 'payment_intent.succeeded':
            const paymentIntent = event.data.object;
            console.log(paymentIntent);
            break;
        case 'payment_intent.payment_failed':
            console.log('Payment Failed');
    }

    res.status(200);

});

and these are my express uses:

app.use((req, res, next) => {
    if (req.originalUrl === '/webhook') {
        next();
    } else {
        express.json()(req, res, next);
    }
});
app.use(express.urlencoded({ extended: false }));

Upvotes: 0

Views: 2147

Answers (1)

LeadDreamer
LeadDreamer

Reputation: 3499

The issue here is almost always not using the RAW BODY in the constructEvent. Stripe doesn't encode the "signature" in the JSON; they use "steganography" to encode the matching signature in the non-coding part of the JSON payload: extra spaces, line breaks, and other characters that are ignored by a JSON parser. The resulting payload can be parsed as JSON for the webhook object, but the "signature" part needs the raw body before any parser has removed the non-coding steganography.

specifically:

event = stripe.webhooks.constructEvent(req.rawbody, signature, endpointSecret)

Upvotes: 2

Related Questions