Draft API Error - URL not ready

Excursionist
32 0 7

Hello, one thing our app does is POST a draft order to Shopify and then take the invoice_url in the response to the POST and redirect the customer to this URL.  For the first time we had an error (see below) that said "the invoice is not available yet, please try again later."  Reload the page after a few seconds shows the proper checkout page/invoice.

 

Is this expected behavior - for Shopify to send a 200 response and an invoice_url even though the invoice isn't ready yet?  If this is expected behavior then what is a safe amount of time to wait before redirecting the user to the url?

 

The store is a Shopify Plus store if that makes a difference.  Thanks!

 

Screen Shot 2019-09-23 at 4.31.54 PM.png

0 Likes
Shopify Staff
Shopify Staff
1118 78 155

Hey @Matt_Goodwin , 

 

Would it be safe to assume that this was a one-off situation, or have you seen it again since this occurrence?

 

I would expect the 200 response and invoice_url if the draft order was successfully generated, but if there happened to be a a temporary outage or slowdown on our end while this was going on it would definitely be possible for something like this to happen. 

 

If this is something that starts to happen often, please let us know! But if this isn't something that has happened again since I wouldn't want you to worry too much about it, there could be any number of issues that could have caused this to happen temporarily that waiting a few seconds may not even help to avoid. 

 

If you have a shop ID and timeframe or a draft order ID, I could check our logs for you to help bring some peace of mind! 

0 Likes
Highlighted
New Member
1 0 1

We are getting reports of this happening from several merchants on a regular basis. When their customers refresh the invoice, it appears. But there is no indication to us from the DraftOrder API that the invoice is not ready, and so we redirect them to the url.

 

The API response should include a field that says the invoice is not ready. This will probably be a straightforward change for your developers as it's just one field.

 

Otherwise this will lead to abandoned carts which isn't good for anyone.

 

I imagine there are logs on your end as to how many of these responses "this invoice is not available yet" have been sent to users, and that should indicate how many potentially abandoned carts it's causing.

 

Thanks for your time.

1 Like
Shopify Staff
Shopify Staff
1118 78 155

Before making a request for an additional field such as 'ready' or something along those lines, I do have a question for the two of you on this thread so far. 

 

After you create a draft order, do you poll the location header's value to see if you get a 200OK response back? Or just link directly to the draft order invoice_url right away? 

 

After I create a draft order I'm seeing a location header that points to the draft order's admin URL, I would expect if that URL returned a 200OK response to a GET request the invoice should be available. If there are events where that is not the case though I would definitely be willing to request an extra field for more visibility into whether or not a draft order is ready for purchase. 

0 Likes
Excursionist
32 0 7

Thanks @Josh.  We are making the call with a promise:

 

 axios.post('https://'+ shopDomain +'/admin/draft_orders.json', draftOrder, headers)
.then ((res)=> {
  //... url should be valid here, correct?
})
.catch((err)=>{
  //...if it wasn't a 200 OK response this section should run
})

If for some reason you think the promise could resolve as true even though the url wasn't ready then it sounds like an additional field is needed to make sure the url sent in a successful response will work.

 

Let me know if you need anything else.  Thanks!

0 Likes
Shopify Staff
Shopify Staff
1118 78 155

Hey @Matt_Goodwin , 

 

How would that code block behave if the response was a 202? I assume it would still interpret that as a success?

 

If a draft order isn't ready, normally we'd respond with a 202 and include 'Retry-After' and 'Location' headers to let you know the interval in seconds (Retry-After header) in which you should send follow-up polling requests to the value of the 'Location' header. 

 

Do you happen to log these headers so you're able to tell when these errors occur what the response status code and header values were? 

0 Likes
Excursionist
32 0 7

Hi @Josh, sorry for the delay!  We were getting really busy with the holidays coming up.  I did some digging and the response headers contain the following values:

 

status: 202,
...
'retry-after': '1',
location:'https://xxxxxx.myshopify.com/admin/draft_orders/531409567819',
...

 

So that would make sense based on your above reply that the 202 means we should retry.   We can write in a function that looks for a 202 and then retries getting the link until we get a 200 response.

 

A few follow-up questions for you:

- Is the 'retry-after' value in seconds?

- If we do get a 202 saying the link was not ready would we then try to GET the draft order by id?  Then if the link still wasn't ready we would receive the same 202 response, correct?  Just not sure if a GET to the draft API would still return a 202 if the link wasn't ready.

- Of the thousands of stores running our app this is only happening on one shop.  It is a Shopify Plus store, could this have something to do with it?  We don't have many Plus merchants using our app at the moment.

 

Thanks so much for your help!

0 Likes
Shopify Partner
78 0 18

Hi @Matt_Goodwin ,

 

For what it's worth, we add a 500ms delay before we redirect to the link on the frontend.

It's not a solution I'm proud of, but it avoids breaking high-traffic merchant's checkout.

 

I've requested Shopify to provide a test endpoint that would always return a header indicating the invoice is not ready for a limited time.

That would allow us to test our implementation for retrying and solve this properly on the backend.

 

Regards,

Bart

Bart Coppens | Limoni Apps | Building apps for Shopify since 2016
0 Likes