Codex · III

Install and style Tiny Cart

Let buyers collect several digital products and pay once. Turn the cart on for a store, add its button to your website, and use CSS to make it your own.

Enable the cart

Choose your store in the dashboard, open Products → Website setup, and enable the shopping cart. The setting applies to that store only. Another store can keep regular Buy now buttons.

  • Use fixed-price, one-time products. Subscriptions and products where the buyer enters a price keep their separate checkout.
  • Every eligible product in the store needs the same currency and test setting, plus at least one compatible payment method in common.
  • Quantities follow each product’s settings and available stock. The trash button removes one copy at a time.
  • One cart checkout counts as one transaction. After payment, buyers can download each purchased file; eligible download links arrive together in one email.

Payment methods and cart availability

Cart availability applies to the whole store. All eligible products must share at least one payment provider that can process them together. Checkout offers only the methods available for every item in the cart.

For example, a book that accepts cards and another that accepts cards and crypto can be bought together by card. To offer crypto for that purchase too, enable the same crypto provider for both products.

If the store has no compatible payment method shared by all eligible products, the Cart button is hidden and customers use individual Buy buttons. The dashboard prevents you from enabling an incompatible cart and hides its preview. If you change payment settings after enabling the cart, the same store-wide check applies. Customers do not see payment-configuration guidance on your website.

Open Products → Website setup → Payment methods for guidance. Check the eligible products’ enabled providers, currencies, and test settings. PayPal, Stripe, and Square also need a consistent tax choice for the provider to be available. Dodo needs a distinct linked product for each item, with a matching price and currency.

Add it to your website

Copy the snippets from Website setup. Load the SDK script once per page, place the Cart button where buyers can find it, and keep a buy button beside each product. This example uses two digital products; replace the store ID and product references with your own.

<script src="https://sdk.coinmoebius.com/latest/sdk.global.js"
  crossorigin="anonymous" defer></script>

<coin-moebius-cart class="shop-cart"
  project-id="proj_YOUR_STORE_ID">
</coin-moebius-cart>

<coin-moebius-buy class="shop-cart"
  project-id="proj_YOUR_STORE_ID" product-id="ebook">
</coin-moebius-buy>

<coin-moebius-buy class="shop-cart"
  project-id="proj_YOUR_STORE_ID" product-id="album">
</coin-moebius-buy>

When the store’s cart is enabled and available, matching buy buttons become Add to cart. Each successful addition shows a short confirmation on the clicked button, and the Cart button’s badge shows the total quantity. The cart opens when the buyer chooses it. Add the Cart component to every page where you want Add to cart behavior; pages without it keep their usual checkout.

Cart contents are saved in the buyer’s browser for this website and store. Different stores keep separate carts, even when they share a page or product reference. Carts are not shared across devices or unrelated websites. These features require SDK version 3.3.0 or later.

Choose the button text

The default is Cart. Change the text in Website setup, or use the label attribute on a particular Cart button. An empty label leaves only the icon; an accessible name remains available to screen readers.

<!-- Custom text -->
<coin-moebius-cart project-id="proj_YOUR_STORE_ID" label="Basket">
</coin-moebius-cart>

<!-- Icon only -->
<coin-moebius-cart project-id="proj_YOUR_STORE_ID" label="">
</coin-moebius-cart>

Match your website

Give the Cart and Add to cart components the same class, as in the installation example. Add these rules to your website’s stylesheet. CSS variables set the shared theme; ::part() selectors reach individual controls inside the components.

.shop-cart {
  --cm-font: Georgia, serif;
  --cm-color: #213b37;
  --cm-modal-bg: #fffdf5;
  --cm-border: #d8dece;
  --cm-accent: #286653;
  --cm-button-bg: #286653;
  --cm-button-color: #fff;
  --cm-button-radius: 999px;
  --cm-cart-width: 540px;
  --cm-cart-radius: 20px;
  --cm-cart-padding: 28px;
  --cm-modal-overlay: rgb(16 37 31 / 55%);
  --cm-cart-continue-bg: transparent;
  --cm-cart-continue-color: #286653;
  --cm-cart-continue-border: #286653;
  --cm-cart-continue-hover-bg: #eaf0e7;
}

.shop-cart::part(button),
.shop-cart::part(continue-button) {
  padding: 12px 20px;
}
.shop-cart::part(item-name) { font-weight: 700; }
.shop-cart::part(quantity-input) { border-radius: 8px; }
.shop-cart::part(checkout-button):hover { background: #1c4e3f; }
.shop-cart::part(checkout-button):focus-visible {
  outline: 3px solid #ab6d13;
}

The buttons use a dark palette by default. Set theme="light" on both for light buttons. The cart popup follows the visitor’s color preference unless its theme is set explicitly. Your CSS variables take precedence. Keep text readable, keyboard focus visible, and controls easy to tap.

Style the badges

Cart quantity

The Cart button’s corner badge is hidden when empty. It works with either text or an icon-only button.

.shop-cart {
  --cm-cart-count-bg: #f2d58a;
  --cm-cart-count-color: #213b37;
  --cm-cart-count-border: #fffdf5;
}
.shop-cart::part(count) {
  font-size: 12px;
  inset-block-start: 0;
  inset-inline-end: 0;
  transform: translate(40%, -40%);
}

Add to cart confirmation

A green checkmark and +1 briefly overlap the clicked button. Each successful addition starts a fresh animation, without moving the button text. You can change the badge’s color, shape, position, typography, and icon.

coin-moebius-buy.shop-cart {
  --cm-added-bg: #286653;
  --cm-added-color: #fff;
  --cm-added-border: #fffdf5;
  /* Optional: replace the checkmark with your own SVG. */
  /* --cm-added-icon: url('/assets/my-checkmark.svg'); */
}
coin-moebius-buy.shop-cart::part(added-badge) {
  border-radius: 8px;
  padding: 4px 8px;
  font-size: 14px;
  top: 50%;
  left: calc(100% - 14px);
}
coin-moebius-buy.shop-cart::part(added-icon) {
  width: 14px;
  height: 14px;
}
coin-moebius-buy.shop-cart::part(added-amount) { font-weight: 800; }

Successful feedback disappears after 1.1 seconds. Reduced-motion preferences use a fade without movement. A product that allows only one copy shows “Already in cart” when it is already present. Stock or connection problems can show an error. To keep the confirmation stationary, add these rules; it will still appear for each addition and disappear automatically.

coin-moebius-buy.shop-cart::part(added-badge) {
  animation: none;
  transform: translateY(-50%);
}

Change the trash icon

Use remove for the button and remove-icon for its icon. Supply your own SVG with --cm-cart-remove-icon. The icon takes the button’s text color, while its accessible label and remove-one action stay in place.

.shop-cart {
  --cm-cart-remove-icon: url('/assets/my-trash-icon.svg');
}
.shop-cart::part(remove) {
  color: #76513b;
  border-radius: 50%;
  min-width: 44px;
  min-height: 44px;
}
.shop-cart::part(remove-icon) {
  width: 22px;
  height: 22px;
}

Style the popup and checkout

In version 3.3.1 and later, long product lists scroll while the title, subtotal, and checkout controls stay visible. Adjust the list height, row spacing, and dividers to suit your website. The items and item parts provide further control.

.shop-cart {
  --cm-cart-items-max-height: 45dvh;
  --cm-cart-item-padding: 12px 0;
  --cm-cart-item-gap: 8px;
  --cm-cart-item-border: #d8dece;
  --cm-cart-item-bg: transparent;
}

Use dialog and panel to change the cart layout. For example, this turns the popup into a side panel. The close control, Escape key, and keyboard focus continue to work.

.shop-cart::part(dialog) {
  margin: 0 0 0 auto;
  width: min(440px, 100vw);
  height: 100dvh;
  max-height: 100dvh;
  border-radius: 0;
}
.shop-cart::part(panel) { padding: 24px; }

The payment screens inside the cart expose parts with a checkout- prefix. Their colors and font inherit the same theme. A payment provider’s own hosted page is styled in that provider’s settings.

.shop-cart::part(checkout-dialog) {
  max-width: 540px;
  border: 1px solid #d8dece;
  border-radius: 20px;
}
.shop-cart::part(checkout-title) { font-family: Georgia, serif; }
.shop-cart::part(checkout-provider) {
  border-radius: 12px;
  padding: 16px;
}
.shop-cart::part(checkout-email-input) { border-radius: 8px; }

Other useful parts include icon, label, title, close, items, item, item-line, item-price, item-controls, subtotal, checkout-button, continue-button, empty, error, and status. Use these public part names instead of internal class names or selectors that depend on the component’s HTML structure.

Taxes and what the cart includes

The cart uses your product and payment-provider settings. PayPal, Stripe, and Square offer a per-product choice to apply your provider’s tax settings. All items in one checkout must share that provider’s tax choice; otherwise that method is unavailable for the cart. Dodo uses its linked product settings. Each cart item needs its own Dodo product with a matching price and currency. If automatic tax is unavailable for a payment method, include any applicable sales tax or VAT in your product price or that method’s price override. Coin Moebius charges that amount without adding or calculating tax. Coin Moebius does not choose tax rates or act as merchant of record.

Tiny Cart handles several products in one purchase. Shipping, discount codes, customer accounts, and order-management tools are outside its scope. To stop new cart purchases, disable the cart in Website setup. Regular product checkout stays available, and existing payments and download links continue to be processed.

Ready to wire it up?

Free tier covers most sites and never asks for a card.