Inspiration
When a shopper likes a product but cannot justify the price, they usually leave. A store's usual answer is a sale for everyone, including customers who would have paid full price.
We wanted to bring the conversation of a market stall to online shopping: explain what you need, make an offer, and find something that works for both sides. That meant building a shopkeeper a merchant could trust with pricing rules and a way to test those rules before using them with customers.
What it does
Dealify is an AI shopkeeper for Shopify, demonstrated in our Trailhead store. It combines a shopping assistant, a pricing engine, and an owner Console with a simulation tool called the Gym.
For shoppers: Jarvis helps people find products, answers questions, and negotiates through offer cards. Shoppers can type or use voice. The assistant understands the current page and can open products, select sizes, change quantities, and manage the cart. Accepting a deal remains the shopper's choice.
A negotiation can lead to a counteroffer, a bundle, or a cheaper alternative. Prices depend on product costs, stock age, the negotiation round, the shopper's stated reason, and the owner's settings. Repeating a low offer does not automatically unlock the lowest price. Accepted offers are checked again before the server creates a Shopify Checkout link with the applicable discount.
For merchants: the authenticated Console shows negotiations and blocked attempts as they happen. Owners can set pricing limits, approve or decline eligible thin-margin offers, and pause deals. Costs, profit figures, and internal decision details stay on the merchant's side.
Before adopting a policy: the Gym runs 300 seeded, rule-based synthetic shoppers against the same pricing engine. Owners can preview changes to the floor, discount cap, negotiation rounds, and lowball cutoff, then compare outcomes with their saved policy, list-price sales, and a 20%-off banner. The simulation can show that haggling performs worse. It is a reproducible rehearsal, not a revenue prediction.
How we built it
Dealify is a pnpm monorepo with three applications and four shared TypeScript packages. Shopify serves the storefront, a Node.js server coordinates negotiations and integrations, and a React Console gives the merchant control. The shared packages contain the pricing engine, Gym simulator, Backboard client, and public/private data contracts.
1. Storefront and shopping assistant
Shopify Liquid, JavaScript, HTML, and CSS power the Trailhead store. Liquid renders product, collection, and cart pages with Shopify data. Our JavaScript widget adds chat, product recommendations, offer cards, countdowns, negotiation history, and context-aware suggestion chips.
Jarvis receives the current page, product, size, quantity, and cart context. Its action layer can open products, select sizes, change quantities, add or remove cart items, and navigate the store. It works through storefront controls and provides Undo for supported actions. Pure shopping actions can run locally; requests that also bargain go to the server.
We also built a movable, resizable, minimizable chat, conversation persistence across page navigation, product highlighting, and an assistant panel that moves out of the way when acting. The shopper still presses Deal and completes checkout.
2. Voice interaction
Browser speech recognition and ElevenLabs let shoppers speak to Jarvis and hear its replies. Supported browsers can recognize speech directly; recorded audio can fall back to the server's ElevenLabs transcription endpoint. ElevenLabs also generates spoken replies.
We added “Hey Jarvis” activation, hands-free turn-taking, microphone activity indicators, and listening/speaking animations. A pause ends a spoken turn, and listening can resume after the reply. Voice depends on microphone permission, browser support, and the configured service.
3. Backend and Shopify integration
The backend uses Node.js 22+, JavaScript, and TypeScript, with Node's built-in HTTP server. It exposes shopper chat, offer acceptance, voice, merchant policy, approval, and event-stream endpoints.
The Shopify Admin GraphQL API supplies products, variants, inventory, recorded costs, and stock-date metadata for a server-side catalog mirror. Public responses contain the product and offer details a shopper needs; private costs and policy details stay behind authenticated owner routes.
For discounted offers, the server creates a single-use Shopify discount code and returns a cart permalink containing the selected variants and quantities. Shopify provides checkout and payment.
4. AI, store knowledge, and memory
Backboard routes our language-model calls to OpenAI. The integration helps interpret requests, answer product questions, and select and describe an eligible offer. Indexed store documents provide product, sizing, shipping, and returns context. Threads preserve conversation context, while identified shoppers can use isolated assistant memory for remembered preferences.
Our central rule is: the AI picks from a menu; code writes the menu. The model receives public fields from eligible offers and chooses an option. It cannot create an arbitrary offer price. The server checks the selection and wording before display; failed, invalid, or timed-out calls fall back to deterministic replies.
5. Pricing engine and offer lifecycle
Our pricing engine is pure TypeScript. It takes catalog data, quantities, recorded costs, stock age, negotiation rounds, the shopper's stated reason, and merchant settings, then constructs eligible counters, bundles, and alternatives.
The floor is a percentage over recorded product cost: a 25% floor on an $80 cost means a $100 minimum autonomous offer. A discount cap, round limit, and lowball rule further control negotiation. Missing costs or unavailable products prevent an item from entering an eligible offer.
Each offer has an identifier, expiry, and explicit status. The server handles replaced and expired cards, pending approvals, pause, and repeated acceptance requests. Eligible offers below the normal floor can go to the owner for a timed decision; the approval path still rejects totals at or below recorded product cost.
6. Owner Console
We built the Console with React 19, Vite, TypeScript, and Tailwind CSS 4. React manages the interface and state, Vite handles development and production builds, and Tailwind supports styling alongside custom CSS.
The Console includes:
- A live feed of offers, selected options, blocked attempts, recalled context, and model latency and cost when available.
- Policy previews for the floor, maximum discount, negotiation rounds, and lowball cutoff, with Adopt to apply changes.
- Timed Approve / Decline cards and a PAUSE control.
- Product-data warnings and a recorded red-team summary.
- Deal summaries kept separate from simulated Gym results. They reflect recorded checkout handoffs, not payment-confirmed order analytics.
The owner feed uses Server-Sent Events. The storefront polls offer status so owner decisions and pause changes can update existing cards.
7. Gym simulation and visualization
The Gym is a pure TypeScript package that runs in the Console and calls the same pricing engine used by the server. It generates 300 seeded synthetic shoppers across five personas: bargain hunters, budgeted shoppers, impatient shoppers, loyal shoppers, and lowballers. Each has rules for willingness to pay, opening offers, patience, and bundle interest.
We built the animated price race with React and SVG. Every dot, round, outcome, and shopper detail comes from the simulation record. Policy changes rerun the same seeded population, making comparisons reproducible.
The Gym reports purchases, bundles, walkaways, potential approvals, and missed deals. Owners can compare policies with list-price sales and a 20%-off banner. The shoppers are rule-based and make no LLM calls. The Gym rehearses policy choices; it does not train the model or predict real revenue.
8. Authentication, database, and deployment
Supabase Auth and PostgreSQL support owner sign-in, merchant records, policy history, and recorded deals. Owner requests require a verified bearer token and a matching merchant owner. Database constraints also reject recorded deals that violate the cost and approval rules. Shared TypeScript contracts keep owner-only fields out of public offer shapes.
Railway hosts a long-running Node.js service and the built Console. Shopify hosts the theme separately. Backboard hosts the configured assistant, indexed documents, and memory. pnpm workspaces link the applications and shared packages, and TypeScript checks their interfaces.
The hackathon server keeps active negotiations, approvals, and the live feed in memory and is designed for one instance. Durable session recovery remains a next step.
9. Testing and development tools
We used Vitest for unit and integration tests, fast-check for seeded property-based pricing tests, and React Testing Library and jsdom for interface and storefront behavior. TypeScript checks shared contracts, and Shopify Theme Check validates theme code.
Tests cover pricing bounds, rounding, bundles, variants and quantities, offer expiry and reuse, approvals, pause, and public/private data separation. A separate red-team harness exercises scripted attacks against an isolated server with test substitutes for external services. Browser walkthroughs check the rendered experience.
Codex supported implementation, debugging, and test development. Our development log records concrete examples, including tests that exposed rounding and bundle-safety bugs.
How a negotiation works, end to end
- The shopper types or speaks. The storefront attaches product, variant, quantity, and page context. Local shopping actions are handled on the page where possible.
- The server interprets the request. It resolves products and offer intent using code and, where needed, Backboard's language-model integration.
- The engine builds the menu. Deterministic rules calculate eligible offers from catalog data and merchant policy.
- The AI selects and explains an option. The server validates the choice and wording, then returns a public offer card. The owner's feed receives private decision details.
- The owner decides when required. Eligible thin-margin offers wait for approval, and the shopper's card updates with the outcome.
- The shopper accepts. The server refreshes Shopify data and checks the offer, cost, policy, availability, and pause state. It checks policy again after discount creation and attempts revocation if conditions changed during that operation.
- Shopify Checkout opens. The server records the handoff and returns the cart link. The shopper completes payment through Shopify.
Challenges we ran into
The hardest part was keeping natural conversation consistent with an enforceable offer. A sentence, an offer card, and a checkout link all need to refer to the same items, quantities, and price. Expired offers, changed variants, owner approvals, and repeated acceptance requests each needed explicit handling.
Voice and page actions added another challenge: “make it two” should change a quantity, not become a two-dollar offer. We separated shopping actions from bargaining and carried page context into the conversation.
Testing also exposed problems that a polished demo could hide. During development, Codex helped build property tests that caught premature money rounding and an unsafe bundle edge case. Those findings led to arithmetic fixes and additional checks, documented in our development log.
Accomplishments that we're proud of
- Connecting a Shopify shopping conversation to offer cards and a real Shopify Checkout handoff.
- Giving the merchant visible controls over the agent, including approvals and pause.
- Using the same pricing engine for shopper negotiations and policy simulations.
- Building a voice-enabled assistant that can act on the storefront while leaving deal acceptance to the shopper.
- Making the Gym show unfavorable results instead of assuming negotiation always wins.
What we learned
An AI shopping experience needs clear boundaries around money. Models are useful for understanding requests and explaining options; pricing decisions need explicit rules, current data, and tests.
We also learned that the merchant needs more than a working chatbot. They need to see what it is doing, control what it may offer, and understand the tradeoffs before changing a policy.
What's next for Dealify
We want to harden checkout enforcement with Shopify Functions, package the Console as an embedded Shopify app, and calibrate the Gym against real order outcomes. We also want to improve persistence across server restarts and expand testing of cart changes, discount reuse, taxes, and shipping.
A ChatGPT shopping surface is a future extension of the same engine. The current experience runs on the Shopify storefront.
Built With
- backboard
- elevenlabs
- fast-check
- graphql
- javascript
- liquid
- node.js
- openai
- pnpm
- postgresql
- railway
- react
- shopify
- supabase
- tailwindcss
- typescript
- vite
- vitest
Log in or sign up for Devpost to join the conversation.