Overview
This customization adds a clear cost breakdown above the checkout button, showing subtotal, shipping, and total based on a fixed shipping rate.
It helps customers understand their final amount before checkout, improving trust and reducing hesitation.
Important: This method only works with fixed shipping rates. If your store uses dynamic shipping, results may be inaccurate.
If you are on Upcart V1.0
Step 1: Add custom HTML
- Go to Upcart > Cart Editor > Settings > Custom HTML
- From the Select HTML Location dropdown, choose Above checkout button
- Paste the following code and update the variables to reflect your store’s shipping cost and threshold:
<hr>
<div class="cartSummarySection">
<div class="cartSummarySubtotal alignLeft">
Subtotal:
<span class="alignRight subtotalprice">{{UPCART_SUBTOTAL}}</span>
</div>
<div class="cartSummaryShipping alignLeft">
Shipping:
<span class="alignRight upcartShipping"></span>
</div>
<div class="cartSummaryEndTotal alignLeft">
Total:
<span class="alignRight upcartEndTotal"></span>
</div>
<div style="clear: both; display: flex;"></div>
</div>
<script>
var shippingThreshold = 15000; // In cents
var shippingCostWhenUnderThreshold = 290; // In cents
var textWhenUnderShippingThreshold = "$2.90";
var textWhenOverShippingThreshold = "FREE";
var currencySymbolToAddInfrontOfEndPrice = "$";
var shouldCurrencySymbolBeOnLeftSide = true;
window.upcartSubscribeCartLoaded((event) => {
var shippingText = window.upcartDocumentOrShadowRoot.querySelector(".upcartShipping");
var endTotal = window.upcartDocumentOrShadowRoot.querySelector(".upcartEndTotal");
if (event.cart.total_price < shippingThreshold) {
shippingText.innerText = textWhenUnderShippingThreshold;
if (shouldCurrencySymbolBeOnLeftSide) {
endTotal.innerText =
currencySymbolToAddInfrontOfEndPrice +
((event.cart.total_price + shippingCostWhenUnderThreshold) / 100).toFixed(2);
} else {
endTotal.innerText =
((event.cart.total_price + shippingCostWhenUnderThreshold) / 100).toFixed(2) +
currencySymbolToAddInfrontOfEndPrice;
}
} else {
shippingText.innerText = textWhenOverShippingThreshold;
if (shouldCurrencySymbolBeOnLeftSide) {
endTotal.innerText =
currencySymbolToAddInfrontOfEndPrice +
(event.cart.total_price / 100).toFixed(2);
} else {
endTotal.innerText =
(event.cart.total_price / 100).toFixed(2) +
currencySymbolToAddInfrontOfEndPrice;
}
}
});
</script>
Legacy note: window.upcartOnCartLoaded callbacks still work but are deprecated and log console warnings. Use upcartSubscribeCartLoaded for all new scripts.
Step 2: Add custom CSS
- Go to Upcart > Cart Editor > Settings > Custom CSS
- Paste the following CSS and adjust
background-color or other styles to match your cart footer:
.upcart-footer {
padding-top: 0px !important;
}
.cartSummarySection {
background-color: #f6f4ef !important;
padding: 10px 23px;
}
.cartSummarySubtotal,
.cartSummaryShipping,
.cartSummaryEndTotal {
color: black;
width: 100%;
text-align: left;
font-weight: normal;
font-size: 16px;
padding: 0;
}
#CartPopup hr {
margin: 0px !important;
}
.alignLeft {
float: left;
}
.alignRight {
float: right;
}
Final result
Once applied:
- A cost breakdown appears above the checkout button
- Customers see subtotal, shipping (fixed or FREE), and total
- The shipping cost dynamically adjusts based on your threshold
This increases cost transparency, improves trust, and can reduce checkout abandonment.
If you are on Upcart V2.0
Step 1: Go to cart summary module
-
Go to Upcart > Cart Editor > Cart Summary > Custom template
-
Paste the following code:
-
The custom code for the section is from Line 52 to Line 73
<div>
<div className="upcart-internal-cart-summary upcart-public-cart-summary">
<div className="upcart-internal-cart-summary__discount-codes upcart-public-cart-summary__discount-codes">
<span className="upcart-internal-cart-summary__discount-label upcart-public-cart-summary__discount-label">
{props.totalSavingsText}
</span>
<div className="upcart-internal-cart-summary__slide-codes upcart-public-cart-summary__slide-codes">
{props.discountApplications.map((discountApplication) => (
<span
key={discountApplication.key}
className="upcart-internal-component-tag upcart-public-component-tag"
>
<span className="upcart-internal-component-tag__icon upcart-public-component-tag__icon">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
focusable="false"
>
<title>Discount tag icon</title>
<path
fillRule="evenodd"
d="M8.575 4.649a3.75 3.75 0 0 1 2.7-1.149h1.975a3.25 3.25 0 0 1 3.25 3.25v2.187a3.25 3.25 0 0 1-.996 2.34l-4.747 4.572a2.5 2.5 0 0 1-3.502-.033l-2.898-2.898a2.75 2.75 0 0 1-.036-3.852l4.254-4.417Zm4.425 3.351a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"
/>
</svg>
</span>
<span className="upcart-internal-component-tag__text upcart-public-component-tag__text">
{discountApplication.title}
</span>
{discountApplication.type === "discount_code" && (
<button
type="button"
className="upcart-internal-component-tag__remove-button upcart-public-component-tag__remove-button"
onClick={props.handleRemoveDiscount}
aria-label="Remove tag"
>
{props.isRemovingDiscount ? (
<div className="upcart-internal-component-loader upcart-public-component-loader" />
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
>
<path d="M12.72 13.78a.75.75 0 1 0 1.06-1.06l-2.72-2.72 2.72-2.72a.75.75 0 0 0-1.06-1.06l-2.72 2.72-2.72-2.72a.75.75 0 0 0-1.06 1.06l2.72 2.72-2.72 2.72a.75.75 0 1 0 1.06 1.06l2.72-2.72 2.72 2.72Z" />
</svg>
)}
</button>
)}
</span>
))}
</div>
</div>
<div>
{props.showCartTotalDiscount && (
<span
className="upcart-internal-cart-summary__total-discount upcart-public-cart-summary__total-discount"
dangerouslySetInnerHTML={{
__html: props.formattedCartTotalDiscount,
}}
/>
)}
</div>
</div>
{/* Custom code for summary section */}
<hr />
<div className="upcart-custom-cart-summary__container">
<div className="upcart-custom-cart-summary__row upcart-custom-cart-summary__subtotal">
Subtotal:
<span
className="upcart-internal-cart-summary__total-discount upcart-public-cart-summary__total-discount"
dangerouslySetInnerHTML={{
__html: props.formattedCartTotalDiscount,
}}
/>
</div>
<div className="upcart-custom-cart-summary__row upcart-custom-cart-summary__shipping">
Shipping:
<span className="upcart-custom-cart-summary__shipping-value">
$2.99
</span>
</div>
<div className="upcart-custom-cart-summary__row upcart-custom-cart-summary__cart-total">
Total:
<span className="upcart-custom-cart-summary__cart-total-value">
${(props.totalAfterAllDiscounts / 100).toFixed(2)}
</span>
</div>
</div>
</div>
b. The relevant part is this section from line 52 - 73, use this doc to decide what value you are planning to display on the screen
<hr />
<div className="upcart-custom-cart-summary__container">
<div className="upcart-custom-cart-summary__row upcart-custom-cart-summary__subtotal">
Subtotal:
<span
className="upcart-internal-cart-summary__total-discount upcart-public-cart-summary__total-discount"
dangerouslySetInnerHTML={{
__html: props.formattedCartTotalDiscount,
}}
/>
</div>
<div className="upcart-custom-cart-summary__row upcart-custom-cart-summary__shipping">
Shipping:
<span className="upcart-custom-cart-summary__shipping-value">
$2.99
</span>
</div>
<div className="upcart-custom-cart-summary__row upcart-custom-cart-summary__cart-total">
Total:
<span className="upcart-custom-cart-summary__cart-total-value">
${(props.totalAfterAllDiscounts / 100).toFixed(2)}
</span>
</div>
</div>
c. Go to Upcart > Cart Editor > Settings > Custom CSS, add this:
.upcart-custom-cart-summary__row {
display: flex;
flex-direction: row;
justify-content: space-between;
}
Need help?
If you want to adapt this for multiple shipping thresholds or advanced logic, we recommend working with a Shopify Expert. Upcart’s support team does not provide assistance with implementing or debugging custom code.