Inspiration
In Pakistan, a lot of online shopping doesn't happen on big stores. It happens on Instagram pages, Facebook ads, and WhatsApp chats, where the seller says "send payment to this JazzCash number and we'll ship today." Sometimes the parcel never comes. Sometimes it's a copy of the product. Sometimes the "70% off" price was never real.
Most people do check things. Just not at the right moment. By the time you're on the payment screen, excitement and "limited stock!" pressure have already won.
Existing tools like ScamAdviser and shopping assistants help, but they're built around Western stores, USD prices, and website checkouts. None of them can answer the question a Pakistani buyer actually has: "Is it safe to send money to this seller?"
So I built Ruko ("wait" in Urdu): a last-second second opinion before your money leaves.
What it does
Ruko pauses you at the moment of payment and runs three checks:
- 🛡️ Scam Check: Is the store or seller real? Looks at website age, online complaints, missing contact or return info, "advance payment only" pressure, requests for OTPs or codes, and community reports on the seller's number, account, or handle.
- 💰 Price Check: Is the price fair? Compares the price against live PKR prices from Pakistani stores, and flags prices that are unrealistically low or "discounts" based on an inflated original price.
- ⭐ Quality Check: Is the product good? Summarizes real buyer complaints from outside reviews, and flags "master copy" and replica listings.
Then it gives a clear verdict (🟢 / 🟡 / 🔴) with source links, and a Safe Pay Plan: a safer way to buy, like asking for cash on delivery, paying a small token first, checking the warranty, or comparing with an authorized seller.
It works in two places:
- Chrome extension: opens by itself on checkout pages, and adds a "Check with Ruko" button to product pages.
- Web checker (mobile-friendly): paste a seller's message, phone or JazzCash/Easypaisa number, IBAN, Instagram handle, shop link, or a screenshot of the ad.
Results are shown in English and Urdu.
Example of a safer outcome
Ali sees an Instagram post: AirPods Pro 3, Rs. 4,500, JazzCash advance only, no COD, limited stock. He pastes the message into Ruko. Ruko searches Pakistani stores live and finds genuine AirPods Pro 3 sell for Rs. 63,899 to 90,000, so Rs. 4,500 is 93% below market. It also flags the advance-payment-only demand and the "limited stock" pressure. Verdict: 🔴 High risk. Don't pay in advance. Ruko suggests asking for cash on delivery instead. Ali doesn't send the money.
On a real store page (PriceOye.pk, Apple AirPods 4), Ruko found the price is in the normal range but surfaced real online complaints about the seller, so it advised caution with source links.
(The demo's example sellers, phone numbers, and community reports are synthetic. Web search, prices, and reviews are live.)
How I built it
- Chrome extension: Manifest V3, plain JavaScript. Scores each page on several signals (URL words, card fields, "Place order" buttons, payment-method text) to detect checkout pages, and renders the Ruko card inside a Shadow DOM so the site's CSS can't break it.
- Web app: React + TypeScript, built with Vite, hosted as a static site on Amazon S3.
- Backend: Supabase Edge Functions (Deno) with Postgres. All API keys stay server-side.
- Signals: RDAP for website age, Tavily web search (restricted to Pakistani results) for complaints, reviews, and prices, and Postgres for community reports.
- AI: DeepSeek (
deepseek-flash) reads screenshots and extracts cited evidence from search results: complaints, market prices, and product problems.
Rules decide, AI explains
I didn't want an AI to make up a verdict. A deterministic rules engine scores each check from weighted signals:
$$ \text{Risk}{\text{check}} = \sum{i} w_i $$
Each signal has a weight. For example, a website younger than 30 days adds 35, a price below half the market price adds 50, and a request for an OTP adds 45. Reassuring signals (an old website, a fair price) subtract. A check with a score of 40 or more is 🔴, 15 or more is 🟡, otherwise 🟢. The AI only extracts facts and writes the plain-language explanation, and any citation that doesn't match a page Ruko actually retrieved is dropped.
Privacy by design
- Phone numbers, accounts, and handles in community reports are stored only as salted SHA-256 hashes. The salt is generated inside the database and never leaves it.
- Reporters' notes are never shown to anyone; lookups return counts only.
- Every table has Row Level Security on, with no public access.
- The extension only sends data on checkout pages or when you click the button: the page address, product name, price, payment options, and a few payment-related sentences. It never reads what you type into forms.
Challenges
- Detecting checkout pages on very different sites. I score each page on several signals and only open the full card at checkout. On normal product pages Ruko shows a small button instead. A real bug I hit: PriceOye's product page has an animated carousel that changes the page constantly, and my re-check timer kept resetting, so the button never appeared. Switching from a debounce to a throttle (re-check at most once a second) fixed it.
- Getting real Pakistani prices. My first price searches returned US articles with dollar prices, so the price check always said "not enough info." Restricting the search to Pakistani results fixed it: the same search then returned real PKR prices from PriceOye, Apple Pakistan, and others.
- Matching the same product across stores. Page titles like "Apple AirPods 4 Price in Pakistan 2026 | Priceoye" made searches noisy, so I clean titles down to the product name first. When reading prices, Ruko skips "master copy," used, and refurbished listings, and keeps only the middle cluster of prices so one odd listing can't skew the range. Close variants (with or without noise cancelling, for example) can still widen the range, which is why Ruko shows the range and its sources.
- Keeping the AI honest. Every claim must cite a page Ruko actually retrieved, or it's dropped. I also found that DeepSeek's reasoning model was running out of tokens before finishing its answer, which silently produced empty results. Giving it more room fixed that.
- Community reports could be abused. Numbers are stored only as hashes, notes are never shown, lookups return counts only, and reports are rate-limited per user. Demo reports are marked synthetic and only used in demo mode, so a real person's number can never match fake data. A real launch would still need moderation and a way for sellers to appeal.
What I learned
- Timing matters more than features: the same warning that gets ignored on a homepage gets read on the payment screen.
- "Works in my test" isn't "works on real sites." The carousel bug and the dollar-price bug only showed up on live pages.
- Letting rules make the decision and AI only explain it made the results easier to trust, test, and debug.
- Most scams here happen in DMs, not on websites, so checking a pasted message or a JazzCash number mattered as much as the browser extension.
Limitations (honest)
- New scam stores and accounts have little or no history, so Ruko relies on weaker signals like website age, price, and payment terms.
- Most
.pkdomains don't publish registration dates, so website age is often unavailable for them. - Search results can miss complaints, and price matching works best for popular products.
- Community reports would need moderation in real use to protect honest sellers.
- The web app is served over HTTP for now; a real launch would add HTTPS.
- Ruko gives evidence and safer options. It cannot guarantee a seller is honest.
What's next
- Moderated, verified community reporting with a seller appeal process
- Price history tracking for fake-discount detection
- An Android share-sheet integration ("Share to Ruko" from Instagram/WhatsApp)
- Scanning payment-related emails and invoices
- Publishing the extension on the Chrome Web Store
Built during the hackathon & credits
- All code was written during the build period (Oct 17 – Nov 22, 2026), starting November 10. Pre-existing components: none besides the open-source libraries below.
- Libraries: React, React DOM, Vite, TypeScript, @supabase/supabase-js. Fonts: Bricolage Grotesque and Noto Nastaliq Urdu (SIL Open Font License).
- APIs and services: DeepSeek API, Tavily Search API, RDAP (rdap.org), Supabase, Amazon S3.
- AI assistance: Claude (Anthropic) was used for brainstorming, planning, writing code, and producing the demo video and screenshots.
- The demo's example sellers, phone numbers, payment accounts, and community reports are synthetic. Web search, prices, and reviews in the demo are live.
Built With
- ai
- amazon-web-services
- chrome
- css3
- deepseek
- fraud-prevention
- javascript
- llm
- node.js
- postgresql
- rdap
- react
- safety
- scam-detection
- security
- sha-256
- shadow-dom
- supabase
- supabase-edge-functions
- tavily
- typescript
- urdu
- web-search