How to fulfill orders using REST API?

JianXiongWu
Tourist
10 0 1

I need to fulfill orders using the REST API given the order_id. I started to retrieve the fulfillments associated with the order_id where order_id is 2185365291143

 

https://.../admin/api/2020-04/orders/2185365291143/fulfillments.json

I receive status code 200, and but the json body response is empty. I have verified that the order is unfullfilled.

{'fulfillments': []}

In the attached image, I have visualized what I really want to achieve (basically fulfill all the line items in an order)Capture.PNGCapture2.PNG

Replies 19 (19)
hassain
Shopify Staff (Retired)
Shopify Staff (Retired)
624 104 171

Hi @JianXiongWu ,

 

If you are using API version 2020-01 and higher, you can fulfill an order using the FulfillmentOrder and Fulfillment resources. Follow this document for more information on how to do this: https://shopify.dev/tutorials/manage-fulfillments-with-fulfillment-and-fulfillmentorder-resources 

 

If you are using API version 2019-10 and below, you can fulfill an order using the Fulfillment and the Location resources. You can follow this guide: https://shopify.dev/tutorials/manage-fulfillments-with-fulfillment-and-fulfillmentservice-resources

 

(Note these documents use GraphQL for its examples, but everything listed here you can do in REST as well)

 

Hassain | Developer Support Specialist @ Shopify
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Click Accept as Solution 

hoggar
New Member
2 0 3

Here how you can Fulfill one complete order:

https://shopify.dev/docs/admin-api/rest/reference/shipping-and-fulfillment/fulfillment#create-2021-0...

Fulfill all line items from 1 location:

POST /admin/api/2021-01/orders/{order_id}/fulfillments.json
{"fulfillment": { "location_id": 123456789 }}

 

This is the simplest way, you can also add various other options like tracking numbers. urls. etc ...

gsosa2703
New Member
1 0 0

Hi,

Thanks for the answer, i have a doubt, the location_id is a mandatory field?

irook
New Member
3 0 0

Does this work for you?  I've been trying this exact request to fulfill all items on an order, and I always get a blank response.  Other actions work, just not this one.

 

I've also tried to get a list of fulfillments, and it always comes up

 

{"fulfillment_orders":[]}

 

I think I need to create a fulfillment_order for the order first, but I cannot find out how to do this.

Any advice on how to create a fulfillment_order for an order? 

jmz
Shopify Partner
1 0 0

@irook 

I was looking for the same thing and finally figured it out. You need to query the fulfillment_orders endpoint [GET] for the order.

myshopify.com/admin/api/2021-07/orders/{order_id}/fulfillment_orders.json

{
    "fulfillment_orders": [
        {
            "id"null,
            "shop_id"null,
            "order_id"null,
            "assigned_location_id"null,
            "request_status""unsubmitted",
            "status""open",
            "supported_actions": [
                "create_fulfillment"
            ],
            "destination": {
                "id"null,
                "address1""null",
                "address2""",
                "city""null",
                "company""null",
                "country""null",
                "email""null",
                "first_name""null",
                "last_name""null",
                "phone""null",
                "province""null",
                "zip""null"
            },
            "line_items": [
                {
                    "id"null,
                    "shop_id"null,
                    "fulfillment_order_id"null,
                    "quantity"null,
                    "line_item_id"null,
                    "inventory_item_id"null,
                    "fulfillable_quantity"null,
                    "variant_id"null
                }
            ],
            "fulfill_at"null,
            "international_duties"null,
            "delivery_method"null,
            "assigned_location": {
                "address1""null",
                "address2"null,
                "city""null",
                "country_code""null",
                "location_id"null,
                "name""null",
                "phone""",
                "province""null",
                "zip""null"
            },
            "merchant_requests": []
        }
    ]

 

Though, seemingly counter-intuitive, the FulfillmentOrder appears to already exist, with just the presence of an unfulfilled order.

 

 

note: nulled out values for obvious reasons

unepetitemousse
New Member
1 0 1

Please note that you must have the `read_merchant_managed_fulfillment_orders` permission to see the FulfillmentOrders.

vboost
Tourist
4 0 1

I still don't get how to actually fulfill the fulfillment order. 

In the documentation, I only found an option to send a fulfillment request to a third service party.

Could someone elaborate on which requests to make once you have the fulfillment order id?

Webship
Shopify Partner
6 0 3

We're also stuck on this. I feel like the documentation could do with a tutorial when it comes to order fulfillment and/or provide an easier alternative for apps that don't necessarily care about every aspect of the fulfillment process.

 

What we've been able to achieve so far:

  1. A customer orders goods from a Shopify store
  2. Shopify notifies our WMS (warehouse management system) about the new order and we check if it satisfies our requirements (having been paid, type of goods, ...)
  3. We look up the fulfillment orders for the order (/orders/450789469/fulfillment_orders.json)
  4. We use the acquired fulfillment order id's to send fulfillment requests as well as fulfillment accepts for these fulfillment order ids.
  5. This is where we are stuck. Shopify does not come by to ask for tracking numbers (on our fulfillment service callback url) nor do we have a way to indicate that the goods have actually been shipped, mark the order as fulfilled or update tracking numbers. Because we don't want to have to rewrite our code again in a couple of months we've shyed away from the deprecated fulfillment API, where updating tracking numbers seems to be possible.

We're also under the impression that the API documentation is in some kind of transition at the moment. Broken links, half written pages, links to the graphQL documentation from the REST documentation... Up until recently the migration guide to fulfillment orders API (away from the fulfillment API) page just returned a 404.

In other places we read comments about how we should be using REST and GraphQL together to get where we need to be, which I would like to avoid. That's like asking people to buy 2 cars if they also want to be able to drive uphill. We've been using the Shopify REST API for a couple of years now and would like to just expand our integration with Shopify to also include marking orders as fulfilled and updating tracking numbers on the orders. I figured that was going to be an quick and easy task. I couldn't have been more wrong.

Webship
Shopify Partner
6 0 3

@vboost Were you able to figure out a way to fulfill orders in the end?

marianobotti
New Member
1 0 0

Hi everybody!

 

Had the same issue with the official documentation and REST APIs examples. Found a solution to the generation of a fulfillment via API in the following way:
- Do a POST to /admin/api/2022-01/orders/{{order_id}}/fulfillments.json.
- Body params like: 

{
    "fulfillment": {
      "notifyCustomer": false,
      "location_id": 48685121239,
      "tracking_company": "DHL",
      "tracking_number": "123123",
      "tracking_url": "trackingdhl.com/tracking/123123"
    }
}

- "location_id" is a required field.

- If the line items in the fulfillment order are not specified, all items in the order will we fulfilled in the same way.


Hope this helps and everyone here can move forward with the shipping generation!

Regards

kunalwf
Shopify Partner
10 0 3

Awesome, thanks for finding that!

 

I had better luck using "notify_customer" rather than "notifyCustomer" here.

Webship
Shopify Partner
6 0 3

This helped us out a great deal!

We've also discovered that this only works with manually created locations (such as the location created when first creating the store). Fulfillment Service locations will not mark the order as fulfilled.

It pains me to have to use something deprecated but hey...

vboost
Tourist
4 0 1

Yes, I indeed found the same solution as @marianobotti. I am only passing the location_id parameter currently. 

The next step which I am trying to figure out is to only fulfill certain items within an order. Haven't been able to find a solution for that yet. 

dj_gerbil
New Member
8 0 0

Could you share how you've managed to acquire the fulfillment and accept it please? I've managed to get the list of fulfillment ID's, but if I try to just accept them it tells me they must be of API type and if I follow the Shopify guide of creating my own fulfillment service and then try to move the order to it I get told that the location doesn't stock these items?

Webship
Shopify Partner
6 0 3

@dj_gerbil
It seems that Shopify has two fulfillment mechanisms:
- an old one, which is documented on https://shopify.dev/api/admin-rest/2022-04/resources/fulfillment#top. This is the one we ended up using, at least for now. About half of the documentation of this api was missing until about a week ago, which was quite confusing to say the least.
- a new one, which is documented on https://shopify.dev/api/admin-rest/2022-04/resources/fulfillmentorder#top. We were unable to mark an order as "fulfilled" in the Shopify backend using this api endpoint however, we will have to come back to it later.
If you get the message "must be of API type" then I suppose you are trying to use the newer fulfillmentOrder mechanism. In that case you indeed need to create a fulfillment service using the api (as documented on https://shopify.dev/api/admin-rest/2022-04/resources/fulfillmentservice#post-fulfillment-services).
Note that each _fulfillment service_ automatically has a _location_ attached to it. This happens when you create the fulfillment service through the Shopify api.
Now, if you want to fulfill an order from a _fulfillment service_, and the products are **not** stocked at the location of your fulfillment service, you need to automatically _relocate_ the products. To do so, try to include the following keys in your api request:

{
relocate_if_necessary: true,
disconnect_if_necessary: true,

}


For example, to update the inventory at Shopify for a given product, do a POST to https://my-shop.myshopify.com/admin/api/2022-04/inventory_levels/set.json (as documented on https://shopify.dev/api/admin-rest/2022-04/resources/inventorylevel#post-inventory-levels-set) with the object:

{
relocate_if_necessary: true,
disconnect_if_necessary: true,
location_id: id_of_a_shopify_location, // get this from your fulfillment service object
inventory_item_id: inventoryItemId, // see https://shopify.dev/api/admin-rest/2022-04/resources/inventoryitem#top
available: qty
}


Hope this helps. Good luck 🙂

dj_gerbil
New Member
8 0 0

Hi, thanks for that. You're right, I'm trying to use the newer one as, like you, I can't see the point in writting code for a system they're discontinuing soon. 

 

So, I just want to check I'm understaning you correctly, do I essentially need to send an inventory update to every product to add the relocate_if_necessary and disconnect_if_necessary keys?

 

Thanks

Webship
Shopify Partner
6 0 3
So, I just want to check I'm understanding you correctly, do I essentially need to send an inventory update to every product to add the relocate_if_necessary and disconnect_if_necessary keys?

I'm sorry for the confusion, my last example was not related to a fulfillment api call. I meant to say that, whenever you try to update a fulfillmentOrder, you might try to add those two records to your request body:

relocate_if_necessary: true,
disconnect_if_necessary: true,


If that does not work then we will not be able to assist further at this time - as I mentioned, we use the old fulfillment system for the time being.

dj_gerbil
New Member
8 0 0

No problem, it's confusing enough as they seem to make it as hard as possible to do. 

 

Okay, so with the info you gave me and a lot of playing around I've managed to accept an order for fulfillment. 

The :

relocate_if_necessary: true,
disconnect_if_necessary: true,

actually have to be done within an inventory update, so in my case I just wrote a script that got all the products from the API and just set them to the same amount but with the 2 parameters:

$set_variant = array(
    "location_id" => wholesale_Location_ID,
    "inventory_item_id" => $variant['inventory_item_id'],
    "available" => $variant['inventory_quantity'],
    "relocate_if_necessary"     => true,
    "disconnect_if_necessary"   => true
);

Once I'd done that, I was able move the order to the Fulfillment service I'd created. 

Then I had to do a call to:

api/2022-04/fulfillment_orders/".$fulillment_id."/fulfillment_request.json

and finally a call to:

api/2022-04/fulfillment_orders/".$fulillment_id."/fulfillment_request/accept.json

Now the only problem is I can't find anything anywhere in the documents to mark it as fulfilled.

I know you said you're using the old system for now, so I thought I'd share this here in the hope it helps yourselves or someone else to get to a similar point 🙂

sarvo
New Member
1 0 0

How to retrieve the location id if we have multiple locations for a store.