<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hashir WebX Studio</title>
    <description>The latest articles on DEV Community by Hashir WebX Studio (hashirwebx).</description>
    <link>https://dev.to/hashirwebx</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F13618%2F0936a948-46c3-4c00-ba37-498659666413.jpeg</url>
      <title>DEV Community: Hashir WebX Studio</title>
      <link>https://dev.to/hashirwebx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hashirwebx"/>
    <language>en</language>
    <item>
      <title>What WhatsApp's Cloud API forces you to design before you send a single reminder</title>
      <dc:creator>Hashir Khan</dc:creator>
      <pubDate>Thu, 05 Nov 2026 09:04:05 +0000</pubDate>
      <link>https://dev.to/hashirwebx/what-whatsapps-cloud-api-forces-you-to-design-before-you-send-a-single-reminder-e3k</link>
      <guid>https://dev.to/hashirwebx/what-whatsapps-cloud-api-forces-you-to-design-before-you-send-a-single-reminder-e3k</guid>
      <description>&lt;p&gt;I thought the hard part of a reminder app would be the user interface. Turns out the hard part is everything that needs to happen before the first reminder can even get sent out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I'm building this
&lt;/h2&gt;

&lt;p&gt;People don't forget to pay for their subscriptions. They forget to cancel them. The idea was to have the reminder show up in the right place, a couple days in advance, when I can still cancel the payment.&lt;/p&gt;

&lt;p&gt;It turned into RenewChime: a WhatsApp-first subscription tracker. Default currency is PKR and everything is managed via a chat.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Next.js (App Router), TypeScript, Tailwind&lt;/li&gt;
&lt;li&gt;Supabase for Auth, Postgres and Row Level Security&lt;/li&gt;
&lt;li&gt;Subscriptions CRUD, dashboard, analytics and reminders screen&lt;/li&gt;
&lt;li&gt;Rule-based chat bot (&lt;code&gt;add Netflix 1500 PKR monthly 5th&lt;/code&gt;, &lt;code&gt;list&lt;/code&gt;, &lt;code&gt;upcoming&lt;/code&gt;, &lt;code&gt;paid Netflix&lt;/code&gt;, &lt;code&gt;snooze Netflix 2d&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Cron route that finds due reminders and sends them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Status, honestly: the whole flow works end to end on a mock provider. The Cloud API provider is written behind the same interface but isn't tested against Meta yet. I'm still getting a test number and templates approved.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it's structured
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. One provider interface.&lt;/strong&gt; The app never talks to WhatsApp directly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;WhatsAppProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;sendTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;sendText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;verifySignature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rawBody&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A mock implementation is the default. The real one is selected with an env var. That's what let me build the whole product before Meta approved anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Consent is data, not a checkbox.&lt;/strong&gt; &lt;code&gt;whatsapp_contacts&lt;/code&gt; stores &lt;code&gt;opted_in_at&lt;/code&gt;, &lt;code&gt;opted_out_at&lt;/code&gt; and &lt;code&gt;last_inbound_at&lt;/code&gt;. The cron skips any contact without a recorded opt-in, and &lt;code&gt;STOP&lt;/code&gt; sets &lt;code&gt;opted_out_at&lt;/code&gt; immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Templates vs free text.&lt;/strong&gt; A business can't start a conversation with free text. Reminders go out as pre-approved templates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hi {{1}}, your {{2}} subscription ({{3}} {{4}}) renews on {{5}}.
Reply PAID, SNOOZE or CANCEL.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Free-form replies are only allowed within 24 hours of &lt;code&gt;last_inbound_at&lt;/code&gt;. This also bit me with verification codes: a number that has never messaged you has no open window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Claim before you send.&lt;/strong&gt; Two overlapping cron runs shouldn't double-send. Instead of check-then-send, each run claims a row atomically (simplified):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;update&lt;/span&gt; &lt;span class="n"&gt;reminders&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;claimed_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'queued'&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;claimed_at&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
&lt;span class="n"&gt;returning&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only the run that gets a row back sends. Failed sends retry after 5 and 15 minutes, then are marked failed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. The webhook trusts nothing.&lt;/strong&gt; It verifies &lt;code&gt;X-Hub-Signature-256&lt;/code&gt; against the raw body with a timing-safe compare, and dedupes inbound messages by provider message ID.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd have shipped without noticing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Month-end renewals: a subscription on Jan 31 has to roll to Feb 28, not March 3.&lt;/li&gt;
&lt;li&gt;Money stored as integer minor units, converted only for display.&lt;/li&gt;
&lt;li&gt;Quiet hours and timezones: reminders outside 9am to 9pm local time move to the next window.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;Working today: add, pause, cancel and mark-paid via UI or chat, reminders scheduled at 7, 3 and 1 day, atomic sending, and Row Level Security tested with two users. Next: real delivery through the Cloud API.&lt;/p&gt;

&lt;p&gt;Live: &lt;a href="https://renewchime.vercel.app" rel="noopener noreferrer"&gt;https://renewchime.vercel.app&lt;/a&gt;&lt;br&gt;
GitHub: comment "Chime" I'll send it to you&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;The platform's constraints turned out to be product design in disguise. Opt-in, templates and the 24-hour window are annoying to build around, but they're exactly what keeps a reminder from feeling like spam.&lt;/p&gt;

&lt;p&gt;Should I break down the reminder engine in a follow-up? Want the provider layer as a small open-source package? And what should I build next?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>typescript</category>
      <category>supabase</category>
    </item>
    <item>
      <title>I Built a Full SaaS-Style WhatsApp Subscription Management System, Here's How</title>
      <dc:creator>Hashir Khan</dc:creator>
      <pubDate>Wed, 10 Jun 2026 08:50:46 +0000</pubDate>
      <link>https://dev.to/hashirwebx/i-built-a-full-saas-style-whatsapp-subscription-management-system-heres-how-253n</link>
      <guid>https://dev.to/hashirwebx/i-built-a-full-saas-style-whatsapp-subscription-management-system-heres-how-253n</guid>
      <description>&lt;p&gt;&lt;strong&gt;Most subscription tools are complex, overpriced, and ignore how small businesses actually operate.&lt;br&gt;
In Pakistan and across emerging markets, businesses manage subscriptions through WhatsApp. Not emails. Not portals. WhatsApp.&lt;br&gt;
So I built a complete frontend system around that exact workflow.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Built This
&lt;/h2&gt;

&lt;p&gt;While working as a Frontend Engineering Intern at Peham LTD, I kept noticing the same gap: businesses needed a clean way to manage subscriptions tied to WhatsApp-based communication workflows.&lt;br&gt;
Existing SaaS dashboards are built for enterprise. They assume complex CRMs, payment APIs, and dedicated ops teams.&lt;/p&gt;

&lt;p&gt;But a local gym, a newsletter creator, or a service business running on WhatsApp? They need something simpler — and more focused.&lt;/p&gt;

&lt;p&gt;I wanted to build a real SaaS-style product that solved this specific problem. A system with a proper landing page, an admin dashboard, and a workflow that maps to how these businesses actually communicate with their users.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;WhatsApp Subscription Management System — a complete frontend SaaS application with two core parts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🏠 Landing Page&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean, conversion-focused hero section&lt;/li&gt;
&lt;li&gt;Feature highlights explaining the WhatsApp-first workflow&lt;/li&gt;
&lt;li&gt;Pricing section&lt;/li&gt;
&lt;li&gt;Call-to-action flows&lt;/li&gt;
&lt;li&gt;Fully responsive across all screen sizes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;📊 Admin Dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Subscription overview and stats&lt;/li&gt;
&lt;li&gt;Subscriber list with status management (active, paused, cancelled)&lt;/li&gt;
&lt;li&gt;WhatsApp message workflow triggers&lt;/li&gt;
&lt;li&gt;Clean UI with intuitive navigation&lt;/li&gt;
&lt;li&gt;Mobile-responsive layout&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;React.js — component-based architecture&lt;/li&gt;
&lt;li&gt;Modern CSS — responsive, utility-first styling&lt;/li&gt;
&lt;li&gt;React Router — client-side navigation between landing and dashboard&lt;/li&gt;
&lt;li&gt;Component composition — reusable UI elements across views&lt;/li&gt;
&lt;li&gt;Vercel — deployed and live&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 Live Demo: whatsappsubscriptionmanagementsyste-flax. vercel.app&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It — The Breakdown
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Landing Page Architecture
The landing page was designed as a standalone marketing surface. I separated it from the dashboard routing intentionally — different goals, different component trees.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Key sections:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;HeroSection — above-the-fold hook with CTA&lt;/li&gt;
&lt;li&gt;FeaturesGrid — card-based feature breakdown&lt;/li&gt;
&lt;li&gt;Pricing Section — tiered plan layout&lt;/li&gt;
&lt;li&gt;Footer — links and brand close&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each section is a standalone component. Easy to update independently without touching unrelated UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Admin Dashboard Structure
&lt;/h2&gt;

&lt;p&gt;The dashboard follows a classic SaaS layout pattern:&lt;/p&gt;

&lt;p&gt;Fixed sidebar with navigation&lt;br&gt;
Top bar with context and user info&lt;br&gt;
Main content area with dynamic views&lt;/p&gt;

&lt;p&gt;I built the subscriber management table as a controlled component with local state, cleanly handling status filters, row actions, and empty states.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg71wpi6zuxvbzrjtc3ph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg71wpi6zuxvbzrjtc3ph.png" alt=" " width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. WhatsApp Workflow UI
&lt;/h2&gt;

&lt;p&gt;This is the most unique part of the system. Instead of generic "send email" buttons, the workflow UI is built around WhatsApp actions — message triggers tied to subscription lifecycle events (onboarding, renewal reminder, cancellation confirmation).&lt;br&gt;
Each trigger maps to a clear UI state. No backend yet — but the frontend is structured to plug into a WhatsApp API layer (like Twilio or Meta's Cloud API) without a rebuild.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Responsive Design Strategy
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;I used a mobile-first approach throughout:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sidebar collapses to a hamburger on mobile&lt;br&gt;
The subscriber table becomes a card list on smaller screens&lt;br&gt;
Landing page sections stack cleanly on all breakpoints&lt;/p&gt;

&lt;p&gt;No UI library — custom responsive components. More control, less bloat.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result &amp;amp; What I Learned:
&lt;/h2&gt;

&lt;p&gt;The system is live and fully functional as a frontend application.&lt;br&gt;
What I got out of this build:&lt;/p&gt;

&lt;p&gt;✅ Deeper understanding of SaaS dashboard architecture in React&lt;br&gt;
✅ Cleaner thinking about component separation and responsibility&lt;br&gt;
✅ Hands-on experience designing around real-world workflows (not textbook features)&lt;br&gt;
✅ Confidence in building landing page + dashboard as one cohesive product&lt;/p&gt;

&lt;p&gt;The biggest shift was thinking like a product engineer rather than just a UI developer. Every component decision is tied back to: Does this serve the user's actual workflow?&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts:
&lt;/h2&gt;

&lt;p&gt;Frontend engineering isn't just about shipping UI — it's about building systems that fit how people actually work.&lt;br&gt;
This project pushed me to design around a specific, real use case. Not a generic CRUD app. A product that understands its users communicate through WhatsApp, not email, and builds the entire experience around that.&lt;br&gt;
That kind of thinking — workflow-first, not feature-first — is what I want to carry into every project I build at Hashir WebX Studio.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Let's Talk 💬&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;a href="https://whatsappsubscriptionmanagementsyste-flax.vercel.app" rel="noopener noreferrer"&gt;Live Demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Want the source code? Drop a comment, and I'll share the GitHub link.&lt;br&gt;
Should I break down the WhatsApp workflow architecture in a dedicated post?&lt;br&gt;
What kind of SaaS dashboard should I build next — open to ideas from the community.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Built by Hashir WebX Studio — React.js • Next.js • TypeScript • SaaS UI Engineering&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
