Dashboard

How to Add a Shopping Cart to an AI-Built App

A cart is a table, not a feature. Here is the schema, the three rules that stop price tampering, and the handoff to a hosted checkout.

Steve Jefferson
Steve Jefferson
Developer Advocate
18 October 20261 min read

The safest way to add a shopping cart to an AI-built app is to make the cart a row in your own database that the server owns, store only product IDs and quantities in it, and calculate every price on the server when the customer pays. The browser should never tell your backend what something costs.

AI app builders will happily generate a cart that lives in browser storage and posts a total to the checkout. It looks right in the demo. It also lets anyone open the developer tools and change a 120 dollar order into a 1 dollar order. Everything below is about avoiding that, while keeping the cart simple.

What a shopping cart is in an AI-built app

A cart is a draft order. It has an owner, a list of lines, and a status. It becomes an order at the moment payment succeeds, and not before.

Keep it in two tables:

sql
create table carts (
  id uuid primary key default gen_random_uuid(),
  user_id uuid references auth.users(id),
  guest_token text unique,
  status text not null default 'open',   -- open | converted | abandoned
  created_at timestamptz default now(),
  updated_at timestamptz default now(),
  check (user_id is not null or guest_token is not null)
);

create table cart_items (
  id uuid primary key default gen_random_uuid(),
  cart_id uuid not null references carts(id) on delete cascade,
  product_id uuid not null references products(id),
  quantity int not null check (quantity between 1 and 99),
  unique (cart_id, product_id)
);

Three choices in that schema are deliberate.

  • No price column on the cart line. Price lives on the product. The cart refers to it, so a price change is picked up automatically and nothing in the browser can influence it.

  • A unique pair of cart and product. Adding the same item twice should raise the quantity, not create two lines.

  • A quantity ceiling. It stops a typo or a script from putting a million units in a cart.

A cart is one feature in a larger build, and the guide to building an app with AI covers the foundations it sits on.

Guest carts and the login merge

Most shops lose customers by demanding an account before the cart. Let people shop first, and attach the cart to an account later. If you are still deciding how accounts work, the guide to adding user accounts to an AI-built app covers the basics.

For a guest, generate a random token, store it in a cookie, and save it as guest_token. When that person signs in, you have two carts: the guest one and any cart tied to their account. Merge with one rule and write it down so the AI builder does not invent another:

On login, move each guest line into the account cart. If the product is already there, keep the higher quantity, capped at 99. Mark the guest cart converted and delete the token.

Keeping the higher quantity, rather than adding them, avoids a surprise where someone who signed in on a second device finds double the stock in the basket.

Server rules that stop tampering

Give your AI builder these three rules as hard requirements, not suggestions.

  1. The client sends product IDs and quantities only. Never a price, a name, a discount or a total.

  2. Every cart read recalculates from the product table. Show the browser a computed total, but never accept one back.

  3. Re-validate at checkout. Between adding and paying, a product may have been unpublished, repriced or sold out. Check again at the moment you create the payment.

A prompt that works well:

Build the cart on the server. The client may only send product_id and quantity. Look up the current price in the products table on every request. Reject any request that includes a price or total field. Re-check stock and availability when the checkout is created.

Then test it yourself. Open the network tab, find the add-to-cart request, and try adding a price field with a lower number. A correct build ignores it or returns an error.

Handing off to a hosted checkout

You do not need to build a payment form. Stripe's Checkout Session takes a list of line items and a mode. In payment mode, each line carries a price and a quantity, and the Checkout Session reference documents a maximum of 100 line items for one-time payments, with a recommendation to consolidate if you have more than a few dozen.

Build the session from your cart rows on the server:

javascript
const items = await db.cartItems.withProducts(cartId);

const session = await stripe.checkout.sessions.create({
  mode: 'payment',
  line_items: items.map(i => ({
    price: i.product.stripe_price_id,
    quantity: i.quantity,
  })),
  client_reference_id: cartId,
  success_url: `${SITE}/order/confirmed`,
  cancel_url: `${SITE}/cart`,
});

The client_reference_id field exists for exactly this: Stripe's reference describes it as a unique string, such as a cart ID, used to reconcile the session with your internal systems. When the payment webhook arrives, use it to find the cart, mark it converted and create the order. The full flow of taking money, including what the webhook should verify, is in the guide to adding payments to an AI-built app, and the unhappy path is covered in handling failed payments.

Sessions also expire. Stripe's reference says the expiry can be set anywhere from 30 minutes to 24 hours after creation, with 24 hours as the default. If your stock is limited, a shorter window stops an abandoned checkout holding items for a day.

Stock, and when to reserve it

If you sell items you can run out of, decide when stock is claimed. Reserving on add-to-cart is generous to customers and hostile to your inventory, because one idle basket can block a sale. Most small shops decrement stock when payment succeeds and re-check at checkout creation, accepting the rare case of a customer paying for the last item twice and being refunded. If you keep stock counts in the app, the walkthrough for building an inventory app with AI gives you the stock table to check against.

A short test list before launch

  • Add an item as a guest, close the browser, return, and confirm the cart is still there.

  • Sign in with a guest cart and an existing account cart, and confirm the merge follows your rule.

  • Edit the request body to include a price, and confirm it is ignored.

  • Change a product price in the database, reload the cart, and confirm the total follows.

  • Unpublish a product that is already in a cart and confirm checkout refuses it with a clear message.

  • Pay with a test card and confirm the cart is marked converted exactly once, even if the webhook arrives twice.

Frequently asked questions

Should the cart be stored in the browser or the database?

The database, for anything that takes payment. Browser storage is fine as a cache or to remember a guest token, but the authoritative cart and every price calculation should live on the server.

Do I need an account to use a cart?

No. A guest cart keyed by a random token works well. Add the merge rule so signing in later does not lose or double items.

How do I handle discounts in a cart?

Treat a discount as data the server applies, never a number the client sends. Stripe's Checkout Session reference lists a discounts field and an allow_promotion_codes option, so you can lean on those rather than building your own discount maths.

Can I let an AI coding agent write the whole cart?

It can write the code, but review the price handling yourself. Check that no request accepts a price, that totals are computed server-side, and that checkout re-validates. Those three checks catch most serious cart bugs.

How did this land?

About the author

Steve Jefferson
Steve Jefferson

Developer Advocate

Steve builds something with Swarmz every week and writes up what worked, what broke, and what he'd do differently. Tutorials and hands-on guides are his lane.

Share

Get the next post in your inbox

One email a month. Product updates, engineering posts, and the best of Built with Swarmz.

I agree to receive emails about AI building tips and Swarmz product news. Unsubscribe any time.