I’m receiving webhooks from Razorpay in a Bubble backend workflow and validating them with HMAC-SHA256, as their docs require: hash the raw request body with the webhook secret and compare against the X-Razorpay-Signature header.
Verification works for some events but consistently fails for others. I’ve narrowed down the cause:
Razorpay signs a JSON body with escaped forward slashes, e.g.![]()
"product_id":"gid:\/\/shopify\/Product\/1234567891234"
But Request Data's raw body text in my backend workflow gives me:
"product_id":"gid://shopify/Product/1234567891234"
So Bubble appears to decode the \/ escape sequences before exposing the “raw” body — the bytes I hash are not the bytes Razorpay signed, and the signature can never match. Events whose payloads contain no slashes verify fine, which is why it looked intermittent at first.
I confirmed this outside Bubble: pointing the same webhook at a small FastAPI server that hashes the true wire bytes, every event (including the previously failing ones) validates with the same secret. So the secret and the Razorpay side are fine.
Questions:
- Is there any way in Bubble to access the true, unmodified raw bytes of an incoming request body in a backend workflow? Or is
raw body textalways post-processed? - Has anyone solved HMAC webhook verification on Bubble for providers that escape slashes (Razorpay, and I believe some PHP-based APIs do the same)? Did you find a reliable workaround inside Bubble itself?