Skip to main content

Calculate Totals & Tax

This guide explains how to calculate and display cart totals, including taxes, in your Elastic Path implementation.

Using getCart for Totals Calculation​

Cart totals information is included in the meta.display_price object when retrieving a cart with the getCart SDK method:

import { getCart, getCartId } from "@epcc-sdk/sdks-shopper";

// Fetch cart with totals information
const fetchCart = async () => {
const cartId = getCartId();
if (!cartId) {
throw new Error("No cart found");
}

const response = await getCart({
path: {
cartID: cartId,
},
query: {
include: ["items"], // Include cart items in the response
},
});

// Cart totals are available in meta.display_price
return response.data;
};

Available Pricing Fields​

The cart response contains several pricing components. Here's a comprehensive overview of all available pricing fields:

FieldLocationDescription
with_tax.amountCart meta.display_priceTotal cart value including tax, in minor units (e.g., cents)
with_tax.formattedCart meta.display_priceFormatted total cart value including tax (e.g., "$99.99")
without_tax.amountCart meta.display_priceTotal cart value excluding tax, in minor units
without_tax.formattedCart meta.display_priceFormatted total cart value excluding tax
without_discount.amountCart meta.display_priceSubtotal before any discounts, in minor units
without_discount.formattedCart meta.display_priceFormatted subtotal before any discounts
discount.amountCart meta.display_priceTotal discount amount (negative value), in minor units
discount.formattedCart meta.display_priceFormatted total discount amount
tax.amountCart meta.display_priceTotal tax amount, in minor units
tax.formattedCart meta.display_priceFormatted total tax amount
shipping.amountCart meta.display_priceShipping cost, in minor units (if applicable)
shipping.formattedCart meta.display_priceFormatted shipping cost (if applicable)
item.unit.amountCart item meta.display_pricePrice per unit before discounts, in minor units
item.unit.formattedCart item meta.display_priceFormatted price per unit before discounts
item.value.amountCart item meta.display_priceTotal value for this item (unit price × quantity), in minor units
item.value.formattedCart item meta.display_priceFormatted total value for this item
item.discount.amountCart item meta.display_priceDiscount amount for this item (negative value), in minor units
item.discount.formattedCart item meta.display_priceFormatted discount amount for this item
item.discounted.amountCart item meta.display_pricePrice after discount, in minor units
item.discounted.formattedCart item meta.display_priceFormatted price after discount

Calculation Methods​

Elastic Path uses two calculation methods that affect how totals are calculated:

  • Simple method: Discounts applied after tax, rounding at unit level
  • Line method: Discounts applied before tax, rounding at line level

The default for stores created after February 2020 is the "line" method.

For details, see Calculate Cart and Order Totals.

Tax Management​

Elastic Path offers several approaches to handle taxes in your shopping cart implementation.

Adding Tax Items to a Cart Item​

Tax items are applied to specific cart items, not directly to the cart:

import { addTaxItemToCart, getCartId } from "@epcc-sdk/sdks-shopper";

// Get the current cart ID
const cartId = getCartId();

// Add a tax item to a specific cart item
// Note: You must have an existing cart item to apply tax to
const cartItemId = "cart-item-12345"; // ID of an existing cart item

const response = await addTaxItemToCart({
path: {
cartID: cartId,
cartitemID: cartItemId, // Required: ID of the cart item to apply tax to
},
body: {
data: {
type: "tax_item",
name: "CA State Tax",
jurisdiction: "California",
code: "CA_STATE_TAX",
rate: 0.0725, // 7.25%
},
},
});

Important Notes About Tax Items:​

  • Tax items must be applied to existing cart items
  • You need the cart item ID (cartitemID) to apply a tax
  • The tax rate is specified as a decimal (e.g., 0.0725 for 7.25%)

Best Practices for Tax Management​

  1. Determine tax strategy early: Decide if you'll use Elastic Path's calculation or a third-party tax service
  2. Consider tax complexity: Different jurisdictions have different tax rules and rates
  3. Keep tax rates updated: Tax rates can change - ensure your system stays current
  4. Document tax decisions: Maintain clear records of tax-related implementation choices
  5. Test across regions: Verify tax calculations for different geographic locations

Integrating with Cart Initialization​

When calculating totals, it's important to ensure a cart exists first. You can use the SDK's built-in initializeCart utility:

import { getCart, initializeCart } from "@epcc-sdk/sdks-shopper";

// Get cart totals, creating a cart if needed
const getCartTotals = async () => {
// First ensure a cart exists using the SDK's initializeCart utility
const cartId = await initializeCart();

// Fetch cart with totals
const response = await getCart({
path: {
cartID: cartId,
},
query: {
include: ["items"],
},
});

// Extract pricing information
const pricing = response.data?.data?.meta?.display_price;
if (!pricing) {
return {
subtotal: "$0.00",
discount: "$0.00",
tax: "$0.00",
total: "$0.00",
};
}

return {
subtotal: pricing.without_discount?.formatted || "$0.00",
discount: pricing.discount?.formatted || "$0.00",
tax: pricing.tax?.formatted || "$0.00",
total: pricing.with_tax?.formatted || "$0.00",
hasDiscount: (pricing.discount?.amount || 0) < 0,
};
};

For more details on cart initialization, see the Elastic Path documentation.

Understanding Cart Total Components​

The cart response contains several pricing components in the meta.display_price object:

// Extract pricing information from cart response
const getCartPricing = (cart) => {
if (!cart?.data?.meta?.display_price) return null;

const pricing = cart.data.meta.display_price;

return {
// Total with tax included
total: pricing.with_tax?.formatted || "$0.00",

// Subtotal before discounts
subtotal: pricing.without_discount?.formatted || "$0.00",

// Discount amount (negative value)
discount: pricing.discount?.formatted || "$0.00",

// Tax amount
tax: pricing.tax?.formatted || "$0.00",

// Shipping cost
shipping: pricing.shipping?.formatted || "$0.00",

// Check if a discount has been applied
hasDiscount: (pricing.discount?.amount || 0) < 0,
};
};

UI Implementation​

Common patterns for displaying cart totals:

// Cart totals display component
const CartTotals = ({ pricing }) => {
if (!pricing) return null;

return (
<div className="mt-4 border-t border-gray-200 pt-4">
<h3 className="text-md font-medium mb-3">Cart Summary</h3>

<div className="space-y-2 text-sm">
<div className="flex justify-between">
<span>Subtotal</span>
<span>{pricing.subtotal}</span>
</div>

{pricing.hasDiscount && (
<div className="flex justify-between text-green-600">
<span>Discount</span>
<span>{pricing.discount}</span>
</div>
)}

{pricing.shipping !== "$0.00" && (
<div className="flex justify-between">
<span>Shipping</span>
<span>{pricing.shipping}</span>
</div>
)}

<div className="flex justify-between">
<span>Tax</span>
<span>{pricing.tax}</span>
</div>

<div className="flex justify-between font-medium text-black border-t border-gray-200 pt-2 mt-2">
<span>Total</span>
<span>{pricing.total}</span>
</div>
</div>
</div>
);
};

Special Considerations​

  • B2B tax handling: Business customers may have different tax requirements
  • International tax concerns: Different regions have different tax rules
  • Tax exemption handling: Some customers may be exempt from certain taxes
tip

For a real-world implementation of cart totals calculation that uses the initializeCart utility, see the SPA Cart Example on GitHub.

Ask External AI