I’m encountering an issue where the cart displays an incorrect price (zero) immediately after adding a product with a dynamically created variant. However, after reloading the cart a few times, the correct price appears.
Steps to Reproduce:
- Load a product page.
- Execute a script (provided below) to:
- Create a new variant with a custom price.
- Verify that the correct price is retrievable via Admin and Storefront GraphQL APIs.
- Add the product to the cart using the new variant.
- Open the cart in a new tab for inspection.
Expected Behavior:
The cart should display the correct price immediately after adding the product.
Actual Behavior:
The cart initially shows a price of zero, but the correct price appears after reloading.
Additional Information:
- Theme: Dawn Theme
- Customizations: No specific changes to the theme
- Variant Creation: Variants are created dynamically because in our final shop the price is based on complex product configurations and pricing rules.
Script used above:
JavaScript
// Constants for improved security and maintainability
const SHOPIFY_DOMAIN = 'https://xxxxxxxxx.myshopify.com'; // Replace with your actual domain
const SHOPIFY_API_VERSION = '2024-07';
const SHOPIFY_ACCESS_TOKEN = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; // Replace with your actual access token (store securely)
const SHOPIFY_STOREFRONT_ACCESS_TOKEN = 'xxxxxxxxxxxxxxxxxxxxxx' // Replace with your actual access token (store securely)
// Function to execute the GraphQL mutation and update the DOM
async function createProductVariant() {
// Define the fixed product ID and price
const productId = "1234756483";
const price = "10.00";
const compareAtPrice = "18.00";
// Generate a random name
const randomName = 'Variant_' + Math.random().toString(36).substring(2, 15);
// Prepare the GraphQL mutation with the fixed product ID and price
const graphql = JSON.stringify({
query: `
mutation productVariantsBulkCreate(
$productId: ID!,
$variants: [ProductVariantsBulkInput!]!
) {
productVariantsBulkCreate(productId: $productId, variants: $variants) {
product { id }
productVariants {
id
title
price
compareAtPrice
}
userErrors {
field
message
}
}
}
`,
variables: {
productId: `gid://shopify/Product/${productId}`,
variants: [
{
optionValues: {
optionName: "Title",
name: randomName,
},
price: price,
compareAtPrice: compareAtPrice,
inventoryItem: {
tracked: false,
},
},
],
},
});
try {
console.log("graphql: ", graphql);
const response = await fetch(`${SHOPIFY_DOMAIN}/admin/api/${SHOPIFY_API_VERSION}/graphql.json`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': SHOPIFY_ACCESS_TOKEN, // Consider using environment variables
},
body: graphql
});
const result = await response.json();
// Check for errors
if (result.errors || result.data.productVariantsBulkCreate.userErrors.length > 0) {
console.error('GraphQL errors:');
// Print all user errors
if (result.errors) {
result.errors.forEach(error => console.error(` - ${error.message}`));
}
if (result.data.productVariantsBulkCreate.userErrors) {
result.data.productVariantsBulkCreate.userErrors.forEach(error => console.error(` - Field: ${error.field}, Message: ${error.message}`));
}
return;
}
// Extract the productVariant ID (Global ID format)
const productVariantGlobalId = result.data.productVariantsBulkCreate.productVariants[0].id;
// Convert the Global ID to a numeric ID
const productVariantId = extractNumericId(productVariantGlobalId);
return productVariantId;
} catch (error) {
console.error('Error creating product variant:', error);
}
}
// Function to extract the numeric ID from the Global ID
function extractNumericId(globalId) {
// The globalId is in the format "gid://shopify/ProductVariant/1234567890"
const parts = globalId.split('/');
return parts[parts.length - 1];
}
// Function to trigger the button click
function triggerAddToCartButton() {
const addToCartButton = document.querySelector('.product-form__submit');
if (addToCartButton) {
addToCartButton.click();
} else {
console.error('Add to Cart button not found.');
}
}
async function getProductVariantPrice(productVariantId) {
const graphql = JSON.stringify({
query: `
query productVariant($id: ID!) {
productVariant(id: $id) {
price
}
}
`,
variables: {
id: productVariantId
}
});
try {
const response = await fetch(`${SHOPIFY_DOMAIN}/admin/api/${SHOPIFY_API_VERSION}/graphql.json`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': SHOPIFY_ACCESS_TOKEN
},
body: graphql
});
const result = await response.json();
if (result.errors) {
console.error('GraphQL errors:', result.errors);
return null;
}
const price = result.data.productVariant.price;
return price;
} catch (error) {
console.error('Error fetching product variant price:', error);
return null;
}
}
async function getProductVariantPriceStorefront(productVariantId) {
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("X-Shopify-Storefront-Access-Token", SHOPIFY_STOREFRONT_ACCESS_TOKEN);
myHeaders.append("Cookie", "request_method=POST");
const graphql = JSON.stringify({
query: `
{
node(id: "gid://shopify/ProductVariant/${productVariantId}") {
... on ProductVariant {
id
price {
amount
currencyCode
}
}
}
}
`,
variables: {}
});
const requestOptions = {
method: "POST",
headers: myHeaders,
body: graphql,
redirect: "follow"
};
let response = await fetch(SHOPIFY_DOMAIN + "/api/2024-07/graphql.json", requestOptions)
const result = await response.json();
if (result.errors) {
console.error('GraphQL errors:', result.errors);
return null;
}
const price = result.data.node.price.amount;
console.log("price: ", price);
return price;
}
// Execute the function to create the product variant
const productVariantId = await createProductVariant();
console.log("1. Product Variant created with GraphQL - productVariantId: ", productVariantId);
const price = await getProductVariantPrice("gid://shopify/ProductVariant/" + productVariantId);
console.log('2. The price of the newly created Variant can be retrieved via Admin GraphQL API - price:', price);
const priceFromStorefront = await getProductVariantPriceStorefront(productVariantId);
console.log('3. The price of the newly created Variant can be retrieved via Storefront GraphQL API - price:', priceFromStorefront);
// Update the input element in the DOM with the numeric ID
document.querySelector('input.product-variant-id').value = productVariantId;
// Trigger the "Add to Cart" button
triggerAddToCartButton();
console.log("4. Newly created product variant added to cart ");
console.log("5. open a new tab with the cart in order to check if the price is shown there");
setTimeout(function() {
window.open(SHOPIFY_DOMAIN+"/cart", '_blank');
}, 300);
Screenshot attached
I’m seeking guidance on how to resolve this issue and ensure that the correct price is displayed in the cart immediately after adding a dynamically created variant.