Possible bug in Shopify Function Discount API

DevAOC
Shopify Partner
4 0 5

Hello,

I have run into what I think is a Shopify Cart API bug in Shopify Functions (Product Discount). I am trying to write a function that discounts items depending on a matching zip code and product variant sku. I have noticed that my function works as expected when viewing the cart, however, once I continue to the checkout page my discounts are no longer applied to the cart.

I have noticed a few things here. When I view the logs for the function run while on the cart page, the cart.deliveryGroups has values in the array. Once I navigate to the checkout, the array is empty. This is where I think the bug lies.

My input.graphql code is as follows:
```

query Input {
  cart {
    cost {
      subtotalAmount {
        amount
      }
      totalAmount {
        amount
      }
    }
    deliveryGroups {
      deliveryAddress {
        zip
      }
    }
    lines {
      quantity
      merchandise {
        __typename
        ... on ProductVariant {
          id
          sku
        }
      }
      cost {
        subtotalAmount {
          amount
        }
        totalAmount {
          amount
        }
        amountPerQuantity {
          amount
        }
        compareAtAmountPerQuantity {
          amount
        }
      }
    }
  }
  discountNode {
    metafield(namespace: "postalCodes", key: "codes") {
      value
    }
  }
}
```

My function code is as follows:

```

// @TS-check
import { DiscountApplicationStrategy } from "../generated/api";

/**
* @typedef {import("../generated/api").InputQuery} InputQuery
* @typedef {import("../generated/api").FunctionResult} FunctionResult
* @typedef {import("../generated/api").Target} Target
* @typedef {import("../generated/api").ProductVariant} ProductVariant
*/

/**
* @type {FunctionResult}
*/
const EMPTY_DISCOUNT = {
  discountApplicationStrategy: DiscountApplicationStrategy.Maximum,
  discounts: [],
};

export default /**
* @param {InputQuery} input
* @returns {FunctionResult}
*/
(input) => {
/**
* @type {[{
* code: string
* skuDiscountPairs: {[key: string]: number}
* }]}
*/
const postalCodes = JSON.parse(input?.discountNode?.metafield?.value ?? "{}");

if (!postalCodes) {
  return EMPTY_DISCOUNT;
}

if (!input.cart.deliveryGroups[0]) {
  return EMPTY_DISCOUNT;
}

const cartPostalCode = input.cart.deliveryGroups[0].deliveryAddress?.zip;
let found;

for (const postalCode of postalCodes) {
  if (postalCode.code === cartPostalCode) {
    found = postalCode;
    break;
  }
}

if (!found) {
  return EMPTY_DISCOUNT;
}

const discounts = input.cart.lines
.filter((line) => {
  if (line.merchandise.__typename == "ProductVariant") {
    const variant = /** @type {ProductVariant} */ (line.merchandise);
    if (variant.sku && found.skuDiscountPairs[variant.sku]) {
      return true;
    } else {
      return false;
    }
  }
})
.map((line) => {
  const variant = /** @type {ProductVariant} */ (line.merchandise);
  return {
    targets: [
      {
        productVariant: {
          id: variant.id,
        },
      },
    ],
    value: {
      percentage: {
        // @TS-ignore
        value: found.skuDiscountPairs[variant.sku].toString(),
      },
    },
  };
});

console.log(discounts, "DISCOUNTS");

if (!discounts.length) {
  console.error("No cart lines qualify for volume discount.");
  return EMPTY_DISCOUNT;
}

return {
  discounts,
  discountApplicationStrategy: DiscountApplicationStrategy.Maximum,
  };
};

```
Here is the deliverGroups array and function output while on the cart page:

"deliveryGroups": [      {
        "deliveryAddress": {          "zip": "K4P 0E4"
        }
      }
    ],
{  "discounts": [    {
      "targets": [        {
          "productVariant": {            "id": "gid://shopify/ProductVariant/45022386159917"
          }
        }
      ],
      "value": {        "percentage": {          "value": "10"
        }
      }
    }
  ],
  "discountApplicationStrategy": "MAXIMUM"
}
Here are the deliveryGroups array and output on the checkout page:
"deliveryGroups": [],
{  "discountApplicationStrategy": "MAXIMUM",  "discounts": []}

Please let me know if you have any questions about this bug report.

 

Replies 7 (7)

ijam
Shopify Partner
6 0 1

Hi, I was wondering if you found a solution, because I have a similar issue.

I am calculating my discount based on cart attributes. These attributes are passed just fine to function's Input on cart page. Once I proceed to checkout page, the function is called 3 times, and in the last two calls, attributes on cart are all null, which removes the discount.

I am using the typescript template for product discount 

DevAOC
Shopify Partner
4 0 5
Hey, I have been in contact with support and they have made a ticket to fix
this bug. The delivery groups should definitely be a part of the checkout
page
Andrew-W
Shopify Partner
27 3 14

Did you get a reply about this issue? I'm having a similar thing where I'm trying to create a product discount based on country code but `deliveryGroups` is always empty.

DevAOC
Shopify Partner
4 0 5
I unfortunately have not gotten any information after submitting a bug
report. They said they would look into it but no news yet!
Andrew-W
Shopify Partner
27 3 14

Thanks for the reply! I've submitted a similar post with my issue too. Nearly three months without a reply doesn't look promising though. 😓

adoshi
Shopify Partner
1 0 0

@DevAOC just curious what your postalCodes metafield definition looks like.

DevAOC
Shopify Partner
4 0 5
Its an object with objects in it.