Calculate sum of metafield for all line items using Shopify Flow

Topic summary

A user wants to automatically select shipping box sizes in Shopify Flow based on product dimensions. The approach involves assigning each product a ‘size score’ metafield, then calculating the total score across all line items in an order to determine which of three box sizes to add.

Core Challenge:
Shopify Flow doesn’t natively provide easy access to metafield data per line item or built-in summation across items.

Proposed Solutions:

  • Manual approach: Loop over line items to retrieve metafield values by product_id or variant_id, then use a code step to sum the scores. Limited by Flow’s constraint of one step per loop.

  • Third-party solution (Flow Companion app): Use the ‘Execute GraphQL request’ action to query all line items (up to 250) and their size_score metafields in one step. A code step then calculates the total score (accounting for quantities) and returns the appropriate box variant ID. Finally, add the selected shipping box as a line item to the order.

A complete workflow example with GraphQL query and JavaScript code was provided for the third-party approach. The discussion remains open for questions.

Summarized with AI on October 26. AI used: claude-sonnet-4-5-20250929.

We want to use Shopify Flow to decide which shipping box size is needed for a specific order. We would add to each of our physical products a metafieldsize score’ where we store the size score each product*. For each order we then want to sum up the total size score and based on this, decide which shipping box should be used for the order. We would then add the right shipping box as a line item to the order.

The main question here now is: how can we calculate in Shopify Flow the total of all the ‘size scores’ accross all line items for an order? I currently don’t see a way of accessing the metafield data per line item, but perhaps I am missing something?

Any help is greatly appreciated!

* We only have a limited number of product sizes & a size score of 1 reflects the size of our most common packaging size. All sizes are therefore scaled to this most common product. We only have three shipping box sizes, meaning we don’t need very complex algorithms or apps like Boxify to make this work.

2 Likes

You might be able to loop over line items and then retreive a metafield value for the associated product_id or variant_id. I think you can only do one step under a for loop though - but then I think you might be able to pass all of that into a code step to sum them up.

If you don’t mind using a third-party app, Flow Companion provides the Execute GraphQL request action, which allows you to perform arbitrary GraphQL queries and return the result into the workflow for use in subsequent steps.

Below is an example of what this workflow might look like. In the example, I used a product size_score metafield with the Integer type.

  1. In the Execute GraphQL request step, we retrieve the size_score value for each line item and the currentQuantity of ordered products. The maximum number of line items retrieved is 250. If your orders might contain more line items, let me know the maximum number you expect, and I’ll adjust the workflow accordingly. Currently, the workflow will fail if an order exceeds 250 line items.

     query suggestedRefund($id: ID!) {
       order(id: $id) {
         lineItems(first: 250) {
           nodes {
             product {
               title
               metafield(namespace: "custom", key: "size_score") {
                 value
               }
             }
             currentQuantity
           }
           pageInfo {
             hasNextPage
           }
         }
       }
     }
    

    Data example:

    {
          "order": {
            "lineItems": {
              "nodes": [
                {
                  "product": {
                    "title": "Title",
                    "metafield": {
                      "value": "1"
                    }
                  },
                  "currentQuantity": 1
                },
                {
                  "product": {
                    "title": "Title",
                    "metafield": null
                  },
                  "currentQuantity": 1
                }
              ],
              "pageInfo": {
                "hasNextPage": false
              }
            }
          }
        }
    

    {
      "id": "{{order.id}}"
    }
    
  2. In the Run code step, we calculate the total size_score for the order and determine the shipping box variant ID based on the result. You can modify this logic as needed.

     export default function main(input) {
       const data = JSON.parse(input.executeGraphqlRequest.data);
       
       let totalScore = 0;
       for (const line of data.order.lineItems.nodes) {
         const productScore = Number(line.product.metafield?.value ?? "0");
         totalScore = totalScore + (productScore * line.currentQuantity);
       }
     
       const partialResult = data.pageInfo.hasNextPage;
       
       if (totalScore > 10){
         return {productVariantId: "gid://shopify/ProductVariant/49407709479260", partialResult}
       } else if (totalScore > 5) {
         return {productVariantId: "gid://shopify/ProductVariant/49407709479260", partialResult}
       } else {
         return {productVariantId: "gid://shopify/ProductVariant/49407709479260", partialResult}
       }
     }
    
  3. In the Add order line item step, we add the shipping box to the order using the ID determined earlier.

I hope this helps. If you have any questions, feel free to ask here or contact Flow Companion support.