and runs during HTML parse, but hubspotutk is set by js.hs-analytics.net, measured loading at ~834ms. On a first visit the cookie does not exist yet, so a single read returns nothing and the visitor gets no external ID at all — and a first visit is exactly what an ad click is. So poll briefly until HubSpot sets it. The SDK loads lazily (~4.5s) and replays a queue, so an init queued a second or two in still lands before any events are transmitted. */ (function attachExternalId() { var attempts = 0; var MAX_ATTEMPTS = 40; /* 40 x 200ms = 8s, then give up quietly */ var timer = null; function tryAttach() { var raw = getExternalId(); if (!raw) { if (++attempts >= MAX_ATTEMPTS && timer) clearInterval(timer); return; } if (timer) clearInterval(timer); sha256Hex(raw).then(function (hash) { oaiq("init", { user: { external_id_sha256: hash } }); }).catch(function () {}); } tryAttach(); /* returning visitor: immediate */ if (!getExternalId()) timer = setInterval(tryAttach, 200); })(); /* --------------------------------------------------------------------------- 2. Load the SDK off the critical path Whichever comes first: the main thread going idle after load, or the first sign of real user intent. No preconnect on purpose — a TLS handshake during LCP for a script we deliberately deferred is a net loss. Measured on clickpost.ai: load event 3614ms, SDK fetched 4508ms. ------------------------------------------------------------------------ */ var loaded = false; var INTENT = ["pointerdown", "keydown", "scroll"]; function loadSdk() { if (loaded) return; loaded = true; INTENT.forEach(function (t) { removeEventListener(t, loadSdk, { passive: true }); }); var s = document.createElement("script"); s.src = SDK; s.async = true; s.fetchPriority = "low"; document.head.appendChild(s); } INTENT.forEach(function (t) { addEventListener(t, loadSdk, { passive: true, once: true }); }); addEventListener("load", function () { window.requestIdleCallback ? requestIdleCallback(loadSdk, { timeout: 2500 }) : setTimeout(loadSdk, 1500); }, { once: true }); /* --------------------------------------------------------------------------- 3. Conversion id sha256(lowercase(email) + "|" + formId + "|" + ISO-hour), first 20 hex, "lead_" prefix. - email lowercased/trimmed so casing does not fork the id - formId keeps two different forms in the same hour from colliding - the hour bucket is only the server's fallback; the id computed here is sent to the relay verbatim, so the two paths cannot disagree even when a submit straddles an hour boundary Ads Manager's own sample omits event_id. We send it so the pixel event and the relay event collapse into one conversion instead of counting twice. ------------------------------------------------------------------------ */ function buildEventId(email, formId) { var seed = [ String(email || "").trim().toLowerCase(), String(formId || ""), new Date().toISOString().slice(0, 13) ].join("|"); return crypto.subtle.digest("SHA-256", new TextEncoder().encode(seed)).then(function (buf) { var hex = Array.prototype.map.call(new Uint8Array(buf), function (b) { return b.toString(16).padStart(2, "0"); }).join(""); return "lead_" + hex.slice(0, 20); }); } /* Guards a re-fire from the history.pushState that book-a-demo-core.js runs after submit, and from back-navigation onto the same state. */ function firedOnce(id) { try { if (sessionStorage.getItem("oaiq_" + id)) return true; sessionStorage.setItem("oaiq_" + id, "1"); return false; } catch (e) { return false; /* private mode / blocked storage: fire rather than lose it */ } } /* Path 2. keepalive lets the request finish even if the page navigates away. Failures are swallowed deliberately: a reporting call must never surface an error to someone who just submitted a form. The relay hashes the email server-side into user.emails_sha256 and adds the caller's IP and user agent, so this event carries the same match signals the pixel gets for free. */ function sendToRelay(email, formId, eventType, eventId) { try { var payload = { token: RELAY_TOKEN, email: email, form_id: formId || "", event_type: eventType, event_id: eventId, /* verbatim, so both paths always match */ source_url: location.href }; var oppref = getOppref(); if (oppref) payload.oppref = oppref; var externalId = getExternalId(); if (externalId) payload.external_id = externalId; fetch(RELAY_URL, { method: "POST", keepalive: true, headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) }).catch(function () {}); } catch (e) {} } /* Capture the email while the form is still on the page. onFormSubmitted does not reliably carry submissionValues, and by then the form may be removed. */ var lastEmail = ""; document.addEventListener("submit", function (e) { var f = e.target; if (!f || !f.querySelector) return; var i = f.querySelector('input[name="email"], input[type="email"]'); if (i && i.value) lastEmail = i.value; }, true); /* Every HubSpot form on the site reports through this one message event, so no module or theme JS needs editing to add coverage. */ window.addEventListener("message", function (e) { var d = e.data; if (!d || d.type !== "hsFormCallback" || d.eventName !== "onFormSubmitted") return; var email = (d.data && d.data.submissionValues && d.data.submissionValues.email) || lastEmail; if (!email) return; /* without an email there is no stable id to dedupe on */ var eventType = EVENT_BY_FORM[d.id] || EVENT_DEFAULT; buildEventId(email, d.id).then(function (id) { if (firedOnce(id)) return; oaiq("measure", eventType, { type: DATA_TYPE }, { event_id: id }); /* path 1 */ sendToRelay(email, d.id, eventType, id); /* path 2 */ }); }); })();

91ÊÓÆµ

See where your logistics stands on automation Start assessment

Home > Blog >

India's Retail Evolution: From Kirana Stores to 'Buy Now'

India's Retail Evolution: From Kirana Stores to 'Buy Now'

Aparajita Ray
By Aparajita Ray

Ready to ship smarter? Talk to our logistics experts.

Trusted by 600+ brands

In this blog

    Remember the smell of spices hitting you the second you walked into your local kirana store? The friendly shopkeeper who knew your mom's name and exactly what kind of detergent she liked? Or the pure, unadulterated joy of polishing off a pack of Parle-G biscuits with a steaming cup of tea?

    This isn't just a report about retail; it's a time machine back to the moments that shaped how we shop, connect, and, well, be Indian.

    Remember When…? Tales from India’s Retail Past

    Before "add to cart" was a thing, there were brands that felt like family. HMT watches ticked away on wrists across the country—by the '80s, they were making over a year- a symbol of dependability for a whole generation. It's the same feeling you get with Amul – even now, with endless options on supermarket shelves, they still command .

    From breakfast tables to witty billboards, the Amul girl became a voice for the nation, commenting on everything from cricket wins to political twists. And then there was the Ambassador, ferrying families and dignitaries alike—a car so dear, it was practically a family member. Nataraj and Apsara pencils were staples in every pencil box and summers were synonymous with the citrusy burst of Gold Spot.

    Long before global giants like Coca-Cola and Pepsi rolled in, school canteens across India were stocked with small glass bottles of Campa-Cola. From Nirma’s jingles (bet you can still sing them word for word) to Ujala’s promise of dazzling whites, these brands were pioneers in making quality accessible. They created memories that defined an era, shaping how we connected and consumed as a nation.

    Shifting Sands:  Dawn of Change

    The 1990s were a whirlwind. Liberalization in 1991 flung open India’s doors to global brands, sparking a dynamic mix of the familiar and the new. But another transformation was beginning: the dawn of the internet.

    In July 1996, India’s first internet café called the '' (no surprises there), opened in Mumbai's Hotel Leela Kempinski. It was like stepping into the future. But let’s not get ahead of ourselves—this was the era of dial-up connections and slow-loading websites. Yet, the potential was electric. It gave us a glimpse into a world where distance was no longer a barrier. Where anything felt possible, just by being online. 

    • In 1999, Rediff.com was already hinting at a world where you could shop in your pajamas.

    • 2000: Baazee.com (later acquired by eBay) brought the thrill of auctions to Indian homes.

    • 2002: IRCTC revolutionized train bookings, turning a time-consuming errand into something that could be done online with a few clicks.

    From battling slow internet connections to seeing the first glimmers of digital commerce, this was a period of cautious optimism. We were learning to trust technology, one step at a time.

    India Goes Online: A Whole New Way to Shop

    Then came the boom. In 2007, Flipkart packed and shipped its very first order—a book titled “�. Was this the moment India’s startup bug bit for good? Maybe it was a prophecy because, by 2010, Flipkart was shipping nearly 10,000 orders daily, turning skepticism into confidence.

    When Amazon came to India in 2013, things got even more interesting. We were drowning in choices- scrolling endlessly, clicking impulsively, and wondering if there was such a thing as too much choice.

    By 2017, e-commerce in India wasn’t just booming—it was exploding, hitting a staggering USD 30 billion. But how? Cash on Delivery, or COD, was the key ingredient. Flipkart introduced it back in 2010, and by 2015, it was part of . COD helped hesitant shoppers take the online plunge, fueling India's e-commerce growth.

    And how did these packages get everywhere? India Post, with its incredible reach, became the backbone of e-commerce, connecting even the remotest corners to the digital world. Blue Dart, Ekart, Delhivery, and DTDC joined the charge to ensure reliable deliveries nationwide.

    Connecting the Dots: Tier-2 and Tier-3 Cities Join the Digital Journey

    Remember when the idea of a "cashless India" felt like a sci-fi movie? By 2016, demonetisation was pushing digital adoption at warp speed. Suddenly, UPI was everywhere. It went from a mere 1 lakh transactions in December 2016 to an astonishing 130 crores by December 2020! The combination of affordable smartphones and the arrival of budget-friendly data plans (thanks, Jio!) meant the internet was in everyone’s pocket. This meant people in smaller towns and cities could now shop online, too.

    Our data suggests that between 2017 and 2019, orders from Tier-2 and Tier-3 cities surged by a significant shift in consumer behavior. By 2018, digital payments accounted for of retail transactions, marking the beginning of a cashless revolution. By 2024, these cities had added nearly 200 million more online orders in just four years, a testament to their growing appetite for e-commerce.

    By 2025, orders from these cities are projected to grow by another 50%, solidifying their importance. This proved that technology could democratize access and opportunity. The digital revolution had truly reached every corner of India.

    Speed of Light: The Rise of Quick Commerce

    And then, life threw us a curveball and everything changed. The pandemic hit and ecommerce became a lifeline. Speed was now king. The ability to get groceries, medicines, and essentials became critical. Pioneers like , , and led the charge, setting the stage for platforms like , , and , which redefined convenience with ultra-fast deliveries, transforming consumer expectations forever.

    By 2023, India’s hyperlocal delivery market hit INR 300 crores, reflecting the rising demand for faster and localized delivery solutions. °ä±ô¾±³¦°ì±Ê´Ç²õ³Ù’s data showed, by 2024, Same-Day Delivery made up nearly 11% of all orders. A projected growth of 35% by the end of 2025, demonstrates a continued shift toward ultra-fast deliveries.

    Coming Full Circle: The Return of Homegrown Pride

    Today, the spotlight is back on India’s own. Brands like , Campus Sutra, Kapiva, and prove that “Made in India� is synonymous with quality and community. This reflects a growing consumer preference for brands that mirror their values of sustainability and authenticity.

    Gen Z, especially, has embraced this shift, with over 60% preferring Indian brands for their values of sustainability and ethical credentials.

    This resurgence of homegrown pride feels like coming a full circle, echoing the early days of iconic Indian brands while embracing modern sensibilities and a global outlook. These brands have proven that Indian creativity and craftsmanship can stand tall on the global stage, telling stories that resonate across borders.

    The Road Ahead: A Future Built on Connection

    So, what’s next? The retail landscape is set for even more change, with these key trends shaping the future:

    Key Trends

    • With over 80% of retailers adopting AI by 2025 and the green logistics market projected to hit USD 3 trillion by 2034, the future of retail will be smarter and more sustainable. This means smarter inventory, faster deliveries—a smoother ride for everyone.

    • With quick commerce set to grab up to 70% of the online grocery market by 2030, expect even faster deliveries and more convenience.

    • With the D2C market alone projected to hit $267.03 billion by 2030 (up from $87.5 billion in 2025), expect even more exciting homegrown innovations.

    • Online shopping is set to grow, with prepaid orders projected to rise by 55% and total shipments by 49% between 2025 and 2026.

    These interconnected trends—AI, sustainability, quick commerce, homegrown brands, and the growth of e-commerce—paint a picture of a more dynamic, convenient, and exciting retail future. It’s all about adapting to what consumers want and building a shopping experience that works for them.

    A Moment of Reflection

    As we look ahead, it’s not just about speed or convenience anymore. It’s about building something that lasts. The first members of Gen Beta are here, inheriting a world that needs balance as much as progress. For them, sustainability won’t be an option—it’ll be the only way forward. Just like the brands we grew up with, the future needs stories that stand the test of time. It’s about building a future that is driven by trust and lasting value, just like the brands that shaped our past.

    The Logistics Automation Platform for E-commerce

    Momentum Leader - G2 Users Most Likely To Recommend - G2 Best Results Mid-Market - G2
    . window.disableHubSpotCookieBanner = true; function killNative() { var n = document.getElementById("hs-eu-cookie-confirmation"); if (n && n.parentNode) { n.parentNode.removeChild(n); return true; } return false; } killNative(); if (window.MutationObserver) { var mo = new MutationObserver(function () { killNative(); }); mo.observe(document.documentElement, { childList: true, subtree: true }); setTimeout(function () { mo.disconnect(); }, 15000); } var COOKIE = "cp_cookie_consent"; var EU = ["at","be","bg","hr","cy","cz","dk","ee","fi","fr","de","gr","hu","ie","it","lv","lt","lu","mt","nl","pl","pt","ro","sk","si","es","se","gb","uk","is","li","no","ch"]; function readCookie(nm) { var m = document.cookie.match(new RegExp("(?:^|; )" + nm + "=([^;]*)")); return m ? decodeURIComponent(m[1]) : null; } function writeCookie(nm, val, days) { var d = new Date(); d.setTime(d.getTime() + (days * 864e5)); document.cookie = nm + "=" + encodeURIComponent(val) + ";expires=" + d.toUTCString() + ";path=/;SameSite=Lax" + (location.protocol === "https:" ? ";Secure" : ""); } function stored() { var raw = readCookie(COOKIE); if (!raw) return null; try { var o = JSON.parse(raw); if (typeof o.analytics === "boolean") return o; } catch (e) {} return null; } function apply(state, revoke) { window._hsp = window._hsp || []; window._hsp.push(["setHubSpotConsent", { analytics: !!state.analytics, advertisement: !!state.advertisement, functionality: !!state.functionality }]); if (revoke && !state.analytics && !state.advertisement && !state.functionality) { window._hsp.push(["revokeCookieConsent"]); } window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: "cp_cookie_consent", cp_consent_analytics: !!state.analytics, cp_consent_advertisement: !!state.advertisement, cp_consent_functionality: !!state.functionality }); document.documentElement.setAttribute("data-cp-consent", "set"); } function inScope(banner) { if (banner.getAttribute("data-scope") !== "eu_only") return true; var geo = (document.body.getAttribute("data-geo_location") || "").toLowerCase(); if (!geo) return true; return EU.indexOf(geo) !== -1; } function init(banner) { var days = parseInt(banner.getAttribute("data-days"), 10) || 180; var prefs = banner.querySelector("[data-cpcb-prefs]"); var compact = banner.querySelector('[data-cpcb-actions="compact"]'); var expanded = banner.querySelector('[data-cpcb-actions="expanded"]'); var toggles = banner.querySelectorAll("[data-cpcb-toggle]"); function show() { banner.hidden = false; requestAnimationFrame(function () { banner.classList.add("is-visible"); }); } function hide() { banner.classList.remove("is-visible"); setTimeout(function () { banner.hidden = true; }, 300); } function collapse() { if (!prefs) return; prefs.hidden = true; if (expanded) expanded.hidden = true; if (compact) compact.hidden = false; } function expand() { if (!prefs) return; prefs.hidden = false; if (compact) compact.hidden = true; if (expanded) expanded.hidden = false; } function paint(state) { Array.prototype.forEach.call(toggles, function (t) { var key = t.getAttribute("data-cpcb-toggle"); if (key === "necessary") { t.setAttribute("aria-checked", "true"); return; } t.setAttribute("aria-checked", state[key] ? "true" : "false"); }); } function fromToggles() { var state = { analytics: false, advertisement: false, functionality: false }; Array.prototype.forEach.call(toggles, function (t) { var key = t.getAttribute("data-cpcb-toggle"); if (key in state) state[key] = t.getAttribute("aria-checked") === "true"; }); return state; } function commit(state, revoke) { writeCookie(COOKIE, JSON.stringify({ analytics: !!state.analytics, advertisement: !!state.advertisement, functionality: !!state.functionality, v: 1, ts: Date.now() }), days); apply(state, revoke); hide(); } Array.prototype.forEach.call(toggles, function (t) { if (t.disabled) return; t.addEventListener("click", function () { t.setAttribute("aria-checked", t.getAttribute("aria-checked") === "true" ? "false" : "true"); }); }); banner.addEventListener("click", function (e) { if (!e.target || !e.target.closest) return; var btn = e.target.closest("[data-cpcb-action]"); if (!btn) return; var action = btn.getAttribute("data-cpcb-action"); if (action === "customise") { expand(); return; } if (action === "accept") { commit({ analytics: true, advertisement: true, functionality: true }, false); return; } if (action === "reject") { commit({ analytics: false, advertisement: false, functionality: false }, true); return; } if (action === "save") { commit(fromToggles(), true); return; } }); var existing = stored(); if (existing) { apply(existing, false); paint(existing); collapse(); } else if (!inScope(banner)) { // Out of the consent-required region: implied consent, banner never shown. commitSilently(); } else { collapse(); show(); } function commitSilently() { var all = { analytics: true, advertisement: true, functionality: true }; writeCookie(COOKIE, JSON.stringify({ analytics: true, advertisement: true, functionality: true, v: 1, ts: Date.now(), implied: true }), days); apply(all, false); } // Public re-open hook for a footer "Cookie settings" link. window.cpCookieBanner = window.cpCookieBanner || {}; window.cpCookieBanner.open = function () { var s = stored() || { analytics: false, advertisement: false, functionality: false }; paint(s); expand(); show(); }; } function boot() { var banners = document.querySelectorAll("[data-cpcb]"); if (!banners.length) return; init(banners[0]); document.addEventListener("click", function (e) { if (!e.target || !e.target.closest) return; var trigger = e.target.closest("[data-cp-cookie-settings]"); if (!trigger) return; e.preventDefault(); if (window.cpCookieBanner && window.cpCookieBanner.open) window.cpCookieBanner.open(); }); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", boot); } else { boot(); } })();