Covers all questions related to inventory management, order fulfillment, and shipping.
Hello, I am using the ShopifyAPI python library in its version 12.3.0 (the latest at this time).
My code has been working perfectly for two weeks (with daily execution). But since last week, the same code without any changes become unable to fulfill orders. This is the function I use:
def fulfillOrder(self, order, tracking_number) -> bool:
fulfillment = shopify.Fulfillment({
'order_id': order.id,
'line_items': [line_item for line_item in order.line_items if line_item.fulfillment_status != 'fulfilled'],
'location_id': self.location
})
fulfillment.tracking_number = tracking_number
fulfillment.notify_customer = True
response = fulfillment.save()
return response
The error I am getting is in the fulfillment.save() line, and the error is:
Exception has occurred: ResourceNotFound
Not Found: https://MY_STORE.myshopify.com/admin/orders/ORDER_ID/fulfillments.json
urllib.error.HTTPError: HTTP Error 404: Not Found
During handling of the above exception, another exception occurred:
File "C:\path\of\my\project\ShopifyConnector.py", line 104, in fulfillOrder
response = fulfillment.save()
^^^^^^^^^^^^^^^^^^
File "C:\path\of\my\project\TrackingBot.py", line 75, in <module>
success = sc.fulfillOrder(order, tracking)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pyactiveresource.connection.ResourceNotFound: Not Found: https://MY_STORE.myshopify.com/admin/orders/ORDER_ID/fulfillments.json
(I have redacted MY_STORE and ORDER_ID, but the are both valid)
However, if I enter in that URL that is suposedly returning a 404 in a web browser, I get a valid JSON response:
{"fulfillments":[]}
Also, other jobs of my code are working properly, like getting all the unfulfilled orders from the last N days. So it is not an athentication issue. Moreover, the right permissions are granted, so it is not an authorization issue.
This is happening not with one specific order, but with all of them.
Does anyone have any idea on how to address this issue?
Thanks in advance
Solved! Go to the solution
This is an accepted solution.
Well, after making some research and receiving confirmation by @Liam. It was clear that my issue is due to a recent endpoints deprecation in the Shopify API.
Since I couldn't wait for the ShopifyAPI Python library to be updated, I reimplemented my fulfillOrder() method for not to use the library and perform the requests to API directly.
If you are facing a similar issue and when you are reading this and the library is still not updated... here you have my code to serve as inspiration 😅.
def fulfillOrder(self, order, tracking_number) -> object:
# First get the FulfillmentOrder to create the Fulfillment in it
# https://shopify.dev/docs/api/admin-rest/2023-07/resources/fulfillmentorder#get-orders-order-id-fulfillment-orders
endpoint = 'https://' + self.SHOP_NAME + '.myshopify.com/admin/api/' + self.API_VERSION + '/orders/' + str(order.id) + '/fulfillment_orders.json'
response = requests.get(endpoint, headers={'X-Shopify-Access-Token':str(self.API_TOKEN)})
fulfillment_orders = response.json()['fulfillment_orders']
# Find all the 'open' FulfillmentOrders to work with them and fulfill the entire order
fulfillment_order_items = []
for fulfillment_order in fulfillment_orders:
if fulfillment_order['status'] == 'open' and fulfillment_order['delivery_method']['method_type'] == 'shipping':
fulfillment_order_items.append( {'fulfillment_order_id': fulfillment_order['id']} )
if len(fulfillment_order_items) == 0:
return None
# Create the Fulfillment data to save
# https://shopify.dev/docs/api/admin-rest/2023-07/resources/fulfillment#post-fulfillments
data = {
'fulfillment': {
'line_items_by_fulfillment_order': fulfillment_order_items,
'tracking_info': {
'number': tracking_number
},
'notify_customer': True
}
}
# Save the Fulfillment
endpoint = 'https://' + self.SHOP_NAME + '.myshopify.com/admin/api/' + self.API_VERSION + '/fulfillments.json'
response = requests.post(endpoint, json=data, headers={'X-Shopify-Access-Token':str(self.API_TOKEN), 'Content-Type': 'application/json'})
return response
Note that my specific project requirements could not match with yours, as this method fulfills all the pending shippable items in the order.
Important documentation articles consulted to code this method:
In order to be able to use the endpoints, your app needs to have these permissions granted:
Hope this is helpful for someone, hope the python library is updated soon and hope Shopify take some years to deprecate this endpoints 😂
Happy coding!
Hi Albe89albe,
Is it possible that your app is using some endpoints that have been deprecated recently - which could be causing this 404 if the requested resource is no longer available?
There were recent deprecations on some endpoint deprecations on the Fulfillment API - can you confirm you're not making calls to any of these endpoints?
Liam | Developer Advocate @ 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 Shopify.dev or the Shopify Web Design and Development Blog
Hi Liam, thanks for your response.
Indeed, the issue is due to the deprecated endpoints. The major problem here is that, as can be seen in my former code, I wasn't making any request directly, but just using the ShopifyAPI Python library, which is still pointing to the deprecated endpoints.
I supposed that, since the library author is Shopify, every update to the API will be synchronized with an update to the library... but it seems that there is some delay on that.
I couldn't wait for a library update and I've already solve this problem by not using the library and making the requests directly to the endpoints explained in the 2023-07 API documentation.
I will now share my solution because I think that everyone using the library is having this same issue right now.
Use shopify.FulfillmentV2(), rather than shopify.Fulfillment().
The new one uses the new endpoint, the old one is trying to create a Fulfilment against the order rather than the FulfillmentOrder.
This is an accepted solution.
Well, after making some research and receiving confirmation by @Liam. It was clear that my issue is due to a recent endpoints deprecation in the Shopify API.
Since I couldn't wait for the ShopifyAPI Python library to be updated, I reimplemented my fulfillOrder() method for not to use the library and perform the requests to API directly.
If you are facing a similar issue and when you are reading this and the library is still not updated... here you have my code to serve as inspiration 😅.
def fulfillOrder(self, order, tracking_number) -> object:
# First get the FulfillmentOrder to create the Fulfillment in it
# https://shopify.dev/docs/api/admin-rest/2023-07/resources/fulfillmentorder#get-orders-order-id-fulfillment-orders
endpoint = 'https://' + self.SHOP_NAME + '.myshopify.com/admin/api/' + self.API_VERSION + '/orders/' + str(order.id) + '/fulfillment_orders.json'
response = requests.get(endpoint, headers={'X-Shopify-Access-Token':str(self.API_TOKEN)})
fulfillment_orders = response.json()['fulfillment_orders']
# Find all the 'open' FulfillmentOrders to work with them and fulfill the entire order
fulfillment_order_items = []
for fulfillment_order in fulfillment_orders:
if fulfillment_order['status'] == 'open' and fulfillment_order['delivery_method']['method_type'] == 'shipping':
fulfillment_order_items.append( {'fulfillment_order_id': fulfillment_order['id']} )
if len(fulfillment_order_items) == 0:
return None
# Create the Fulfillment data to save
# https://shopify.dev/docs/api/admin-rest/2023-07/resources/fulfillment#post-fulfillments
data = {
'fulfillment': {
'line_items_by_fulfillment_order': fulfillment_order_items,
'tracking_info': {
'number': tracking_number
},
'notify_customer': True
}
}
# Save the Fulfillment
endpoint = 'https://' + self.SHOP_NAME + '.myshopify.com/admin/api/' + self.API_VERSION + '/fulfillments.json'
response = requests.post(endpoint, json=data, headers={'X-Shopify-Access-Token':str(self.API_TOKEN), 'Content-Type': 'application/json'})
return response
Note that my specific project requirements could not match with yours, as this method fulfills all the pending shippable items in the order.
Important documentation articles consulted to code this method:
In order to be able to use the endpoints, your app needs to have these permissions granted:
Hope this is helpful for someone, hope the python library is updated soon and hope Shopify take some years to deprecate this endpoints 😂
Happy coding!
Hi @albe89albe really appreciate you posting your solution. I have the same problem and I will use your function until the shopify library is updated.
Cheers,
Vinh
Hello
who to grant this permission
Hello @jagdish_0106
You should grant those permissions to the app that will perform the fulfillments.
Maybe "permissions" is not the best choice of word here, because I think it is actually called "API access scopes".
Here you have the reference: https://shopify.dev/docs/api/usage/access-scopes