Changing Price when addiing to Cart

Hi I want to recalculate the product price when adding it to the Cart. I need to do this based upon various user choices (not product variants).

So I have written the following code ( see red code text ), everything works and choices, custom text and info etc are added to the CART except the prices are not changed ! Any help please

$w(‘#CartIcon’).addToCart(“0c49ab91-3da8-3375-ded0-ac778628a4c6”, 1, {
“choices”: {

“No of Panels and Traffic Door Position”: $w(‘#NoPanels’).value + " - " + $w(‘#TrafficDoor’).value,
“External Colour”: $w(‘#ExternalColour’).value,
“Internal Colour”: $w(‘#InternalColour’).value,
“Handle”: $w(‘#Handle’).value,
“Glass”: $w(‘#Glass’).value,
“Blinds”: $w(‘#Blinds’).value
},

“customTextFields”: [{

“title”: “Width of Opening in cm (Width x Height)”,
“value”: $w(‘#Width’).value + "cm x " + $w(‘#Height’).value + “cm”
},
{
“title”: “Special Ral Colours (External and Internal)”,
“value”: "External Ral " + $w(‘#ExternalRal’).value + "Internal Ral " + $w(‘#InternalRal’).value
}
],

“additionalInfoSections”: [{
“title”: “Configuration”,
“description”: DoorConfiguration
},
{
“title”: “Design”,
“description”: DoorDesign
},
{
“title”: “Accessories”,
“description”: Accessories
}
],

“price”: session.getItem(“TotalPriceValue”),
“discountedPrice”: session.getItem(“TotalPriceValue”),
“formattedPrice”: session.getItem(“TotalPrice”),
“formattedDiscountedPrice”: session.getItem(“TotalPrice”),

    }) 
    .then(() => { 
        console.log("Product added"); 
        console.log("price " + session.getItem("TotalPriceValue")); 
        console.log("discountedPrice " + session.getItem("TotalPriceValue")); 
        console.log("formattedPrice " + session.getItem("TotalPrice")); 
        console.log("formattedDiscountedPrice " + session.getItem("TotalPrice")); 
    }) 
    . **catch** ((error) => { 
        console.log(error); 
    });
2 Likes

Any help on this please?

Hi Martin,

Did you manage to get this working? I’m trying to do something very similar, but it appears you can’t add a custom price based on the users choices?

Thanks for any info, very much appreciate it.

Cheers,

Andy.

@Martin, @andydavidson1965 , I’m trying to do the same thing. Any luck figuring it out. The only workaround seems to be to use the WixPay API, but that doesn’t allow you to add the new price to the cart. If you have any insights on how you solved this, would you be willing to share?

Hi Sean,

Yes, I got it to work, but it’s a bit of a workaround (as always!).

For my application, it’s custom sizes of timber, length, width, thickness, where the user can enter the dimensions they want.

So what I’ve ended up doing, is not to use predefined products, instead, when the workflow is as follows:

User enters the width, length, thickness, then clicks “Add to Cart”.

At this point, the API code, creates their item as a unique product, then, once the product is created, it than also adds that product to the cart.

example code:

/*******************************
 * Backend code - products.jsw *
 *******************************/

import wixStoresBackend from 'wix-stores-backend';

export function createProduct(product) {
 return wixStoresBackend.createProduct(product);
}

export function addProductMedia(productId, mediaData) {
 return wixStoresBackend.addProductMedia(productId, mediaData);
}

Front End Code:

import { createProduct } from 'backend/products';
import { addProductMedia } from 'backend/products';

function sleep(milliseconds) {
 const date = Date.now();
 let currentDate = null;
 do {
   currentDate = Date.now();
 } while (currentDate - date < milliseconds);
}

function updatePrice(){
 let price = Number
 let totalprice = Number
 let costPerSquareMetre = Number

    costPerSquareMetre = 0.00

 if ($w('#InputThickness').value === "3mm")  { costPerSquareMetre = 8.88 }
 if ($w('#InputThickness').value === "4mm")  { costPerSquareMetre = 10.39 }
 if ($w('#InputThickness').value === "6mm")  { costPerSquareMetre = 11.82 }
 if ($w('#InputThickness').value === "9mm")  { costPerSquareMetre = 17.66 }
 if ($w('#InputThickness').value === "12mm")  { costPerSquareMetre = 20.76 }
 if ($w('#InputThickness').value === "15mm")  { costPerSquareMetre = 23.98 }
 if ($w('#InputThickness').value === "18mm")  { costPerSquareMetre = 27.07 }
 if ($w('#InputThickness').value === "22mm")  { costPerSquareMetre = 35.37 }
 if ($w('#InputThickness').value === "25mm")  { costPerSquareMetre = 38.46 }
 if ($w('#InputThickness').value === "30mm")  { costPerSquareMetre = 54.81 }
 if ($w('#InputThickness').value === "38mm")  { costPerSquareMetre = 62.71 }

    price =  ((($w('#InputLength').value * $w('#InputWidth').value) / 1000000) * costPerSquareMetre).toFixed(2)  
    totalprice = (price * $w('#InputQuantity').value).toFixed(2)

    $w('#PriceEach').value = '£' + price
    $w('#TotalPrice').value = '£' + totalprice

}

export function InputLength_change(event) {
  updatePrice() 
}

export function InputWidth_change(event) {
  updatePrice() 
}

export function InputThickness_change(event) {
  updatePrice() 
}

export function InputQuantity_change(event) {
  updatePrice() 
}

export function InputQuantity_input(event) {
  updatePrice() 
}

export function InputLength_input(event) {
  updatePrice() 
}

export function InputWidth_input(event) {
  updatePrice() 
}

$w.onReady(function () {
  $w("#addToCartButton").onClick(async () => {
 let length = $w('#InputLength').value;
 let width = $w('#InputWidth').value;
 let thickness = $w('#InputThickness').value;
 let quantity = $w('#InputQuantity').value;
 let price = parseFloat($w('#PriceEach').value.replace('£', ''));
 let totalprice = $w('#TotalPrice').value;

 const product = {
 "name": "Standard MDF",
 "description": "<p>Length: " + length + "mm <br>Width: " + width + "mm <br>Thickness: " + thickness + "<br><br>Standard MDF, medium density fibreboard is a popular product for furniture, cabinetry and boxes as it offers a smooth finish and strength. Standard MDF means the product is in its raw state and has not been covered or treated in anyway.</p>",
 "price": price,
 "productType": "physical"
      }

 try {
 let newProduct = await createProduct(product);
 // Product was created...
      console.log('Product created...') 


 // add product to cart

 const productId = newProduct._id
 const description = newProduct.description
 const src = "https://static.wixstatic.com/media/7edb98_b821b1326c0842b5ad93bb4e148e7cf0~mv2.jpg";
 const mediaData = [{src}]

            console.log(productId)
            console.log(description)

            sleep(1000);

            addProductMedia(productId, mediaData);

            console.log('Adding product to cart...')

            $w('#shoppingCartIcon1').addToCart(productId, quantity, {
 "customTextFields": [ {
 "title": "Length",
 "value": length + 'mm'
             },
             {
 "title": "Width",
 "value": width + 'mm'
             },
             {
 "title": "Thickness",
 "value": thickness
             }, 
             ],

            }
            )
            .then( () => {
                console.log("Product added");
             } )
            .catch( (err) => {
              console.log("Product not added to cart:")
              console.log(err);
              } );

    }
 
 catch (err) {
 // Product not created!
      console.log('Product not created!')
      console.log(err)
    }

  });
}) 

The above code is the full code for my application but the key elements are define your product, here’s mine using variables for the length and price etc it gets from elsewhere:

const product = {
 "name": "Standard MDF",
 "description": "<p>Length: " + length + "mm <br>Width: " + width + "mm <br>Thickness: " + thickness + "<br><br>Standard MDF, medium density fibreboard is a popular product for furniture, cabinetry and boxes as it offers a smooth finish and strength. Standard MDF means the product is in its raw state and has not been covered or treated in anyway.</p>",
 "price": price,
 "productType": "physical"
      }

Next create the product and add the product image too:

 try {
 let newProduct = await createProduct(product);
 // Product was created...
      console.log('Product created...') 


 // add product to cart

 const productId = newProduct._id
 const description = newProduct.description
 const src = "https://static.wixstatic.com/media/7edb98_b821b1326c0842b5ad93bb4e148e7cf0~mv2.jpg";
 const mediaData = [{src}]

            console.log(productId)
            console.log(description)

            sleep(1000);

            addProductMedia(productId, mediaData);

Now that the product is created, add it to the cart, using it’s _ID that was just created:

console.log('Adding product to cart...')

            $w('#shoppingCartIcon1').addToCart(productId, quantity, {
 "customTextFields": [ {
 "title": "Length",
 "value": length + 'mm'
             },
             {
 "title": "Width",
 "value": width + 'mm'
             },
             {
 "title": "Thickness",
 "value": thickness
             }, 
             ],

            }
            )
            .then( () => {
                console.log("Product added");
             } )
            .catch( (err) => {
              console.log("Product not added to cart:")
              console.log(err);
              } );

    }
 
 catch (err) {
 // Product not created!
      console.log('Product not created!')
      console.log(err)
    }

  });
}) 

Note that there is a kludge is there!

The sleep 1000! It’s a crude one second delay between the product being created and then it being added to the cart. Without this, it fails and errors with “cannot find product…” as it’s trying to add it as it’s still creating it.

I know a hard coded delay is not the done thing, but I tried to run it synchronous to no avail, no matter what I did, it would still fail. So a brute force delay gets it working for now. Might tidy that up later!

So the plan is:

Create the whole product in code.
Add the image to the code
Wait until the product is added
Add that product to the cart with option custom text

There is one small bug, there’s a slight delay in the correct image appearing in the mini-cart! But it’s only a slight issue, then the true image shows. Again, I think this is to do with it not being created before it’s added.

That’s about it, hope this helps! See how you go!

Cheers,

Andy.

@andydavidson1965 This is amazing, and exactly what I need! You are a savior. Thank you. I had considered creating an entirely new product, and your approach validates that. Thank you very much. What a great workaround! I owe you a beer.

You’re welcome! It’s involved a fair bit of me pulling my hair out, but got there in the end! There’s a few snags such as needing the hard coded delay but it’s working for now!

Good luck and let me know if you manage to get the product to properly wait before adding itself to the cart, rather than using the kludge delay!

Have fun, I’ll drink to that!

Cheers,

Andy.

@andydavidson1965 This works like a charm for adding the custom product/price to the cart. Is there a similar approach for a “Buy Now” button that bypasses the cart and goes straight to checkout?