I am only seeing this error in my production account (not either of my sandbox accounts). When I try to validate the payment.created and payment.updated events, the hash I produce on my end does not match the signature received from the headers.
Note, I did see some successful calls in my logs for these two endpoints, however it only seems to fail when the data itself has multiple nested objects ( Example: the data.object.payment object has deeply nested objects such as data.object.payment.card_details.card)
Additional information:
My app ID is sq0idp-NLJQVmndw8XyEYi27ygs-g
I’m receiving the webhooks via AWS SQS, which then gets processed by my NodeJS application. Not sure if this would cause any issues in itself, but I have not had any issues up to this point with it.
Is there any word on this? I just noticed the same behavior on payment.created/payment.updated webhooks in my staging environment (sandbox app ID sandbox-sq0idb-sOKs0XyV7WiLz6_kQdSKug). However for some reason or another everything seems to be validating correctly in my dev environment (sandbox app ID sandbox-sq0idb-kK3X_6CjO00oyDWtTS3a3A). All three environments are currently utilizing version 2021-08-18 of the Square API
Thanks for your patience on this. The team believe that the problem is key ordering and recommends that apps use the raw bytes from the request rather than converting the object representation in your language back to bytes for signature validation.
For those who just ran into this problem like I did, I have an observation to share and a recommendation to Square. Hopefully these will save others from spending 3+ hours on troubleshooting this like I did:
To calculate an HMAC-SHA256 hash that matches that of Square, the JSON string read from the HTTP request body must have no spaces or carriage returns between the elements. In other words, the input to the HMAC function needs to be one long line of string with no space (except if there is a space in any JSON value, then you’d keep it.)
Log entries provided by Square via this Web page:
developer . squareup . com /apps/{your_app_id}/webhooks/events
is VERY misleading.
Some of the attributes Square sent to my Webhook does not show up in this Web log. For example, I tested the payment.updated webhook. The actual calls includes a created_at attribute, but the log shown on the Web doesn’t have it.
The order of attributes shown in the Web log and in the actual call are different. I understand that order of JSON attributes are not guaranteed. But when it comes to hashing, the order matters. So when I tried to manually calculate the HMAC using the payload from the Web log entries, it does not work. I recommend that Square shows the log on the Web that matches the actual payload sent, or warn people on that page itself that they can’t use it to troubleshoot their HMAC problem.