merce.STACK
merce.STACK
Skip to content
PricingWhat's new
Log inGet started
{}Developers
GuidesAPI referenceChangelogGet API keys →
  • Get started

    • Quickstart
    • Keys & authentication
  • Storefront

    • Products & catalog
    • Carts
    • Checkout & payment
    • Customer accounts
    • Digital products
    • Without a build step
    • Bookings
    • Courses
    • Drop-in components
  • Server API

    • Server API
    • Customers
    • Payment links & transactions
    • Balance & payouts
    • Classes & students
    • Node SDK
  • Email API

    • Email API
    • Sending email
    • Delivery events
  • Events & errors

    • Webhooks
    • Errors
  • Reference

    • API reference
    • Changelog

Storefront

Carts

Server-backed, so nothing about money can be edited by the browser.

TypeScript
await mercestack.addToCart({ variantId, quantity: 2 });
await mercestack.updateCartItem(lineId, 3);
await mercestack.removeFromCart(lineId);
await mercestack.clearCart();

const cart = await mercestack.getCart();

Three things you do not have to handle

  • —A tab left open for two weeks. If the stored cart expired or was already checked out, the SDK quietly starts a new one and retries. Your shopper gets their item, not an error about a cart they never knew existed.
  • —Two calls racing. A page that adds two items on load creates one cart, not two. Without that, the first item lands in a basket nothing ever looks at again.
  • —A listener that throws. A cart-count badge that blows up does not fail the add — the item is in the basket either way.

Totals

TypeScript
cart.subtotalMinor;  // "4500000"
cart.discountMinor;  // "450000"
cart.giftCardMinor;  // "200000"
cart.totalMinor;     // "3850000"  the basket, before gift cards
cart.payableMinor;   // "1850000"  what the payment provider is asked for

The SDK computes none of these. Every figure came from the server on this request, recalculated from current prices and the current discount record — which is why a cart line has no stored price and a code that expires overnight stops applying by itself.

payableMinor of "0" means there is nothing to pay

Gift cards covered the basket. Checkout will confirm the order without contacting a payment provider, and come back with paid: true and no payment link.

Discounts and gift cards

TypeScript
await mercestack.applyDiscount("SUMMER20");
await mercestack.applyDiscount(null);              // remove it

await mercestack.applyGiftCard("A3F9-K2MN-7PQR-XT4W");
await mercestack.removeGiftCard(giftCardId);

Applying a gift card holds nothing and deducts nothing — it is a statement of intent. The card is charged once, at checkout, under its own lock. cart.giftCards[].appliedMinor previews what each would cover.

Carrying a cart across a server render

TypeScript
// Server: pass the token in, do not let the SDK persist it. One process
// serves many shoppers, and a shared cart between them is a bug.
const mercestack = new Mercestack({
  publicKey: process.env.MERCESTACK_PUBLIC_KEY!,
  cartToken: cookies().get("cart")?.value,
});

// Client: hand it back out again.
const token = await mercestack.cart.token();
← PreviousProducts & catalogNext →Checkout & payment

On this page

  • Three things you do not have to handle
  • Totals
  • Discounts and gift cards
  • Carrying a cart across a server render
Create a workspaceTalk to usPricing

One workspace for everything your business runs on — your team, customers, store, marketing and payouts in one place.

Get started

Product

  • All products
  • Pricing
  • What's new
  • Security

Resources

  • Documentation
  • Guides
  • Use cases
  • Blog
  • Get support

Company

  • About
  • Careers
  • Contact us
  • Talk to the team

Legal

  • Privacy
  • Terms
  • Cookie policy
  • GDPR
  • Report a vulnerability

© 2026 Mercestack. All rights reserved.

Mercestack StructureOS

mercestack