Webhook not working for live events even though test-event works in production environment

Hi,
I created a webhook external application to respond to the subscription.created event.
The square application is in “production mode”.
If I send a test event from the square production environment my external application is triggered and works as intended.
However if a live new subscription is created my external application is NOT triggered.

So, it looks like the square webhook can correctly send test-events from the production environment but still is not active in real live.
Please helpt to fix.

[edit], few hrs later…
I did modify the receiver a bit to get logging also if signature hash fails.
As result now also the test-event fails:

Error
Could not reach Square Connect test notification endpoint. Either Square Connect is not responding to messages, or you have lost connection to the internet.
2021-10-31 14:06:16

If I just hit the web hook receiver via chrome it functions fully ok (although in that case signature verification naturally fails)

application ID: sq0idp-lAzv_Id6M6KZzY8hyHcXvw

Thanks in advance

1 Like

:wave: Looking at the logs I do see successful webhook deliveries. Also we recommend using the raw bytes from the request rather than converting the object representation in your language back to bytes for signature validation. :slightly_smiling_face:

Thanks,
Ok,… at least the test events work again.
I did just send 1st a test event and after that a live event (from doing an actual 1$ test buy).
Indeed in both cases my Webhooks-receiver gets called.
It always returns 200, no matter whether signature verification did pass or fail.

However:

  • in case of test event the signature verification did pass
  • in case of the real event the signature verification did fail.

“recommend using raw bytes”… can you explain a bit deeper?

I am using below php script (I did remove some privacy information)
It works for test events, but apparently not for real events

Thanks

/<?php
$WebHookKey = ‘MY KEY’;
$URLhandler = ‘MY SCRIPT.php’;
$payload = file_get_contents(“php://input”);
$stripped = preg_replace(’/\s/’, ‘’, $payload);

$yourHash = hash_hmac(‘sha1’, $URLhandler.$stripped, $WebHookKey);
$HashBase64 = base64_encode(hex2bin($yourHash));

$Signature = $_SERVER[‘HTTP_X_SQUARE_SIGNATURE’];

if (strcmp($Signature, $HashBase64) == 0)
{
echo ‘Webhook Success!!’;
$message .= “\n\n Square signature OK”;
} else
{
echo ‘Webhook Fail’;
$message .= “\n\n Square signature FAIL”;
}
mail(‘MY EMAIL’, ‘[SQUARE message from subscription script]’, $message);
http_response_code(200);
?>

Is the URL the fully-qualified URL? The URL handler should be the fully-qualified URL.

Hi Bryan,
Thanks for the response.
I don’t know what you mean with “fully qualified UFRL”. The URL points to a php script that is hosted on a subdomain of my website which is hosted by SiteGround.

Having said that, I find it difficult to believe it’s the url that makes the difference.
Code has some reporting included that I left out in the before message for reading clarity.

But…

  • When I send a test-event from the production environment of square (so not even the sandbox)
    → code is executed
    → When logging the $HashBase64 that I calculated I can see it to be equal to the signature square included in the message
  • When I do an actual subscription using a checkout link using real creditcard with real money
    → code is executed
    → When logging the $HashBase64 that I calculated I can see it to be different from the signature square included in the message

[EDIT]
Just updated the receiver:
response 200: Signature validation SUCCEED
response 202: Signature validation FAIL, but merchant_id and message type SUCCEED (match expectation)
response 299: Signature FAIL, merchant_id and/or type FAIL

If your logging can read return payload → I included hash calculation results

Current behaviour:

  • Send test event in production environment → signature validation succeeds, response 200
  • Actual subscription purchase in production environment → signature validation fails but message content is ok, merchant_id ok, type ok → response 202

So… issue remains… hash-calculation succeeds on test event but fails on real purchase

Any idea on how to proceed?

Hi,
Looks like I solved it.
Instructions on Verify and Validate an Event Notification say:

The value of this header is an HMAC-SHA1 signature generated using your webhook signature key, the notification URL, and the body of the request (excluding all whitespace).

However:

  • Body already does not contain whitespace between fields
  • But: Some content fields contain whitespace. In my case of subscription.created: the field “Square Online Store” and “Checkout Link” have whitespace.

Solution was simple: Since the body already does not have whitespace between the fields I removed the “remove whitespace” function and calculated the hash directly from the body.

I would say: error in instruction

I’ll be sure to pass this to the appropriate team. Thanks for sharing your findings! :slightly_smiling_face:

1 Like

Hello! I am having the same issue. I am now in the production mode of my app. When I send a test event for the order.fulfillment.updated event’s webhook, my server receives the POST request to the URL I assigned. Yay.

However, when an actual order.fulfillment.updated event occurs from a partnered seller, the server does not receive the POST request.

My other webhooks work totally fine with the partnered seller.

I’m not sure I understand how OP solved the issue. Is there a known solution?

Do you have an order_id that you didn’t get the event?

1 Like

sure, here is one of the many order_id’s: w9d61lDWw8vLqNbBQzehrZOyQpRZY

EDIT:
Ok, now the test events I am sending for this webhook aren’t being sent either. I get this error:

Could not reach Square Connect test notification endpoint. Either Square Connect is not responding to messages, or you have lost connection to the internet.
2021-12-03 18:32:22

I’m not seeing anything in the logs for webhooks with that order. What’s you applicationId?

1 Like

Sure, prod app ID is: sq0idp-n7Co30IXghyF_BPiBvCnBA

UPDATE:
Test events are working again. Actual events still are not.

Do you have a recent order_id that you aren’t getting the events for?

1 Like

I was troubleshooting and it begun to work once I added the permission: ORDERS_READ for the account! Thank you Bryan!

Ah, that will do it! :slightly_smiling_face:

1 Like