Solved

Webhook get called multiple times

Ufi
Shopify Partner
11 0 0

Hi,

 

I have an app that uses API to create Webhook for order/paid event. I use Azure function as an end point to receive the webhook. This function adds the message to Service Bus Queue for later processing and returns OK 200.

The problem is, that the same webhook gets called multiple times even if it receives 200 response!

Because of this I get a lot of 429 rate limit exceptions in my Queue processing Azure function.

Why is the same webhook called multiple times when the response is 200?

Accepted Solutions (2)
Josh
Shopify Staff
1134 84 233

This is an accepted solution.

Hey again, 

 

Webhooks won't concern themselves with any URL params to decide when they will be fired or not, only the webhook topic and events that occur on a shop. So if your app and 3 others have all subscribed to orders/paid webhooks, every time an order is paid then a webhook will be sent to each app regardless of the webhook URL. 

 

For your webhook to only be called once, you should remove all of your current webhooks and then replace them with a single webhook subscription. 

 

In terms of tracking the draft/order relation, I'm not seeing a great way to accomplish that unfortunately. You may want to consider adding either a note or a tag to draft orders that you create, those will carry over to the order when it is generated. However, the downside is that they're easily removed by a merchant if they choose to.

 

 

Josh | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

View solution in original post

Josh
Shopify Staff
1134 84 233

This is an accepted solution.

Hey again, 

 

Happy to help! And consider it done, that request makes sense to me provided that the same information carries over to the order when it is generated as well. I'll log a feature request for this right now. 

Josh | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

View solution in original post

Replies 9 (9)

Josh
Shopify Staff
1134 84 233

Hey there, 

 

This typically occurs when we're either not actually receiving your 200OK responses, or they're not being sent fast enough. 

 

Would you be able to provide an example order ID that you received multiple webhooks for?

Josh | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

Ufi
Shopify Partner
11 0 0

Hi,

 

response is fast enough, average around 200ms.

This is draftOrderId, that was send to webhook end point and got called 3 times,

draftOrderId: 233336176693

Azure Function response to webhook:

 

Webhook.png

List of 3 identical request to webhook end point with same draftOrderId. Response is 429 because processing of webhook exceeds rate limit, But data is added to Queue and processed by separate function.

 

Webhook1.png

 

My functions always returns 200
https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.okresult?view=aspnetcore-2.2 

 

Here you can see trace of calls for webhook. It is clear that function "OrderPaid" is executed with response before processing of Queue Worker starts

Webhook2.png

Josh
Shopify Staff
1134 84 233

Hey again, 

 

The draft order ID that you linked to is a saved draft order, and hasn't been turned into an order and marked as paid yet - so it won't trigger an orders/paid webhook. Orders/paid webhooks will only fire when an order resource is paid for, or a draft order is marked as paid which turns it into an order.

 

I also noticed that you have 59 orders/paid webhooks registered on this shop with different URLs, which would cause several webhooks to be sent. This means that for every order marked as paid on your shop, there would be 59 webhooks being triggered.

 

In good news, there don't seem to be any errors on our end and we're successfully receiving 200OK responses, but normally you would only register a single orders/paid webhook and send them all to one URL that processes them. If you were to remove all of your webhook subscriptions from this shop and then add one of them back again, I think you'll notice that this stops happening.

Josh | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

Ufi
Shopify Partner
11 0 0

Hey,

 

thanks for your reply. The flow is like this:

 

  1. When user uses our app to buy something, we create a draft order to apply discount to products provided in our app.
  2. Every time user adds products to cart trough our app, new draft order is created with new webhook.
  3. Webhook receives 2 parameters for userId and for draftOrderId
  4. When order is paid, webhook is triggered. When processing the request we use the draftOrderId that is sent in webhook params to check if this order was created by DraftOrder created by our App.
  5. Webhook "Order/Paid" request body does not hold any information about draftOrder or how it was created, so we cannot verify if it was created by our app. That is way new webhook is created for each order.

Question is: why are all webhooks triggered at once if they have different url params? We though that with different params only the right Webhook is gonna be called? 

How can we change this so webhook gets called only once and we can verify the draftOrder and order relation?

 

Thank you

Josh
Shopify Staff
1134 84 233

This is an accepted solution.

Hey again, 

 

Webhooks won't concern themselves with any URL params to decide when they will be fired or not, only the webhook topic and events that occur on a shop. So if your app and 3 others have all subscribed to orders/paid webhooks, every time an order is paid then a webhook will be sent to each app regardless of the webhook URL. 

 

For your webhook to only be called once, you should remove all of your current webhooks and then replace them with a single webhook subscription. 

 

In terms of tracking the draft/order relation, I'm not seeing a great way to accomplish that unfortunately. You may want to consider adding either a note or a tag to draft orders that you create, those will carry over to the order when it is generated. However, the downside is that they're easily removed by a merchant if they choose to.

 

 

Josh | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

Ufi
Shopify Partner
11 0 0

Hi,

thanks for all the help.

We will change the code, so only 1 webhook is created per shop.

I have a favor/request:

could you add data to draftorder.json who created the draft order. Because if I check draft order in shopify admin dashboard at the bottom of the page there is information how the draft order was created. I guess adding information to webhook request body should not be that hard?

 

draft.png

 

draft1.png

Josh
Shopify Staff
1134 84 233

This is an accepted solution.

Hey again, 

 

Happy to help! And consider it done, that request makes sense to me provided that the same information carries over to the order when it is generated as well. I'll log a feature request for this right now. 

Josh | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

Josh
Shopify Staff
1134 84 233

@Ufi I had one more thought I wanted to share that might be helpful, but it would also require you to store a history of IDs of draft orders that you've created in the past. 

 

You can tie a draft order to its resulting order once it has been paid for, it's just doing the reverse that is more difficult. Draft orders have an order_id field, so as long as you're storing a history of draft order IDs so you know you have created them, you can at least find out which orders are associated with them (and then store that as well if you want to). Not a perfect fix I know, but I thought it might be useful. 

 

The only way I see to tie an order to its associated draft order is to use the Event API to read the messages from the order timeline such as "You created this order from draft order <a href="https://shop-name.myshopify.com/admin/draft_orders/132504846392">#D288</a>." 

Josh | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

Ufi
Shopify Partner
11 0 0

Hey,

 

I used the "tag" to reference draft-order and order. I also store the draftOrderId in DB, this is why I was sending draftOrderId trough webhook param to check if it was ours draft-order.

Since the code was change no more 429 errors occur and every thing works as it should.

Great that your will add reference to draftorder and order how both where created.

 

Thanks for all the help!

Cheers