Reputation: 1971
Set-up
I have a Shopify store with an unfulfilled order and have access to the store's REST API.
The order has been shipped and I have its tracking_number
, tracking_url
and the transport_company
.
I want to use the REST API to set the order to fulfilled and send the tracking_number
, tracking_url
and transport_company
info to the customer.
Code
I have the order's id in Shopify, the order_id
, such that I can get the order's fulfillment_orders
item and from there the fulfillment_id
and location_id
like so,
fulfillment_orders = requests.get(shop_url + '/orders/'+ order_id +'/fulfillment_orders.json').json()
fulfillment_id = str(fulfillment_orders['fulfillment_orders'][0]['id'])
location_id = requests.get(shop_url + '/locations.json').json()['locations'][0]['id']
where shop_url
is the url needed to connect to the store.
So far the code works.
Then, I set up the payload,
payload = {
"fulfillment":
{
"notify_customer": 'false',
"location_id": location_id,
"tracking_info":{
"tracking_url": tracking_url,
"tracking_company": transport_company,
"tracking_number": tracking_number,
}
}
}
where location_id
is an integer and the other variables are strings.
When I subsequently run the following request to insert the information into the order,
r = requests.post(shop_url + '/fulfillments/' + fulfillment_id + '/update_tracking.json',
json=payload,headers=headers)
I get a <Response [400]>
.
Question
What am I doing wrong?
Upvotes: 1
Views: 4978
Reputation: 1781
For me it was a mix of solutions the accepted answer sadly didnt work straight away for me.
First of all you need the fulfillments of a given order - this is the endpoint:
GET https://<<YOUR-SHOP>>/admin/api/2022-04/orders/<<ORDER-ID>>/fulfillment_orders.json?status=open
Be aware there can be more than one fulfillment per order. I recommend to use the status=open flag. Otherwise you also get previously closed fulfillments like e.g. if you fulfilled it earlier and set it back to unfulfilled. Since they are closed I wouldn't request them. Funfact you can't open this endpoint via Firefox use chrome or a real api platform instead.
GET https://<<YOUR-SHOP>>/admin/api/2022-04/locations.json
You get the Location ID from this endpoint.
Here comes the next pitfal. For me it was not enough to simply call api/orders/fulfillments.json
. I had to provide the ORDER-ID
again like in the first call.
POST https://<<YOUR-SHOP>>/admin/api/2022-04/orders/<<ORDER-ID>>/fulfillments.json
This is the payload:
{
"fulfillment": {
"line_items_by_fulfillment_order": [
{
"fulfillment_order_id": "5859341008918",
"fulfillment_order_line_items": [
{
"id": "12675478814742",
"quantity": "3"
}
]
}
],
"tracking_info": {
"number": "1234",
"url": "www.usps.com",
"company": "Fake Company"
},
"notify_customer": false,
"origin_address": null,
"message": "test message"
}
}
Upvotes: 1
Reputation: 1971
The correct way to do it is discussed here.
Assuming you have the shopify order id order_id
and the shop_url
, the following code will set an order as fulfilled,
# get order fulfillment id
fulfillment_orders = requests.get(shop_url + '/orders/'+ order_id +'/fulfillment_orders.json').json()
fulfillment_id = fulfillment_orders['fulfillment_orders'][0]['id']
location_id = requests.get(shop_url + '/locations.json').json()['locations'][0]['id']
# get orders fulfillment line items
# note: if you want to fulfill only certain products in the order with the tracking code,
# here's where you select these products. Right now, the code isn't doing this
fulfillment_order_line_items = []
for item in fulfillment_orders['fulfillment_orders'][0]['line_items']:
fulfillment_order_line_items.append(
{
'id': item['id'],
'quantity': item['quantity'],
}
)
# set up payload
payload = {
"fulfillment":
{
"notify_customer": 'false',
"location_id": location_id,
"tracking_info":
{
"url": tracking_url,
"company": transport_company,
"number": tracking_number,
},
"line_items_by_fulfillment_order": [
{
"fulfillment_order_id": fulfillment_id,
"fulfillment_order_line_items": fulfillment_order_line_items
}
]
}
}
# parse tracking info
r = requests.post(shop_url + '/fulfillments.json',
json=payload,headers=headers)
Upvotes: 4