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 /**
* @Anonymous {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.