چرا فروشگاههای اینترنتی بعد از اولین ماه شلوغ متوقف میشوند
گرفتن سفارش، همان بخشی است که کار میکند. هر چیزی بعد از آن — موجودیای که دیگر با خودش نمیخواند، صد سفارش که هرکدام کار متفاوتی میخواهند، مرجوعی، فاکتور، و این سؤال که امسال واقعاً چه چیزی فروش رفته — جایی است که یا سامانهای پشت فروشگاه هست یا نیست.
فروشگاه، همان ده درصد آسان ماجراست
فروشگاه اینترنتی یک کار میکند و پلتفرمهای امروزی آن یک کار را خیلی خوب انجام میدهند: نمایش کالا، دریافت پول، و ثبت اینکه سفارشی ثبت شد. هفتهٔ اول راهاندازی حس موفقیت دارد، چون در همان هفته فروشگاه *همان* کسبوکار است.
بعد ماه دوم میرسد. سفارشها ادامه دارند و معلوم میشود گرفتن سفارش هیچوقت بخش سخت ماجرا نبوده. بخش سخت، همهٔ کارهایی است که هر سفارش راه میاندازد — و تقریباً هیچکدامشان داخل فروشگاه نیستند.
فروشگاه اینترنتی ساخته شده تا سفارش بگیرد. هیچوقت ساخته نشده تا کارهای بعدش را اداره کند. اینها دو محصول متفاوتاند و روز راهاندازی فقط یکیشان خریده میشود.
چیزی که با سفارش صدم از راه میرسد
با روزی پنج سفارش، یک نفر کل کسبوکار را در ذهنش نگه میدارد. با روزی صد سفارش، همان آدم فهرستی در دست دارد که نمیتواند بخواندش، چون فهرست سفارشها فهرست *کار* نیست.
ببینید صد سفارش یک روز معمولی واقعاً شامل چیست:
- شصتتا هیچ چیزی لازم ندارند. جمعآوری، بستهبندی، ارسال.
- دوازدهتا قبل از هر کاری تأیید میخواهند: یک تنوع کالا، یک تعداد، یک آدرس غیرعادی.
- نهتا منتظر تأیید رنگ از طرف مشتریاند و مشتری از دیروز جواب نداده.
- هشتتا باید کد رهگیری برایشان ارسال شود، و سهتا از اینها کد را هم گرفتهاند؛ فقط کسی نفرستاده.
- پنجتا آدرسی دارند که ارسال با آن شکست میخورد و باید تماس گرفته شود.
- چهارتا مرجوعی هفتهٔ قبلاند، هرکدام در مرحلهای متفاوت: درخواستشده، در راه، دریافتشده، بازپرداختشده.
- دوتا ناقصاند: یک قلم موجود است و یک قلم نیست.
فروشگاه اینترنتی به شما صد سطر و یک ستون وضعیت نشان میدهد. چیزی که کسبوکار لازم دارد هفت صف است؛ هر صف سفارشهایی که *یک کار مشترک* میخواهند، مرتبشده بر اساس اینکه وقت کدام دارد تمام میشود. فاصلهٔ این دو نما، فاصلهٔ تیمی است که کار میکند با تیمی که فقط زیاد کار میکند.
ضررهای بیصدا هم از همینجا شروع میشوند. هیچ چیزی خراب نیست. فقط آن سفارشی که تماس تلفنی لازم داشت چهار روز سر جایش میماند، و بعد تبدیل میشود به یک بازپرداخت، یک نظر منفی، و مشتریای که دیگر برنمیگردد.
عدد موجودی از کجا اشتباه میشود
از یک فروشگاه در حال رشد بپرسید از فلان کالا چندتا دارید؛ معمولاً سه جواب میگیرید.
فروشگاه یک عدد میگوید، چون هنگام پرداخت کم میکند. انبار عدد دیگری میگوید، چون کارتنی آسیب دیده و کسی به فروشگاه خبر نداده. کسی که جلوی قفسه ایستاده عدد سومی میگوید، چون دارد به خود قفسه نگاه میکند.
دلیلش بیدقتی نیست. دلیلش این است که «چندتا داریم» در واقع چهار سؤال جداگانه است که یک عدد نمیتواند جوابشان را بدهد:
- موجود — همین حالا فیزیکی روی قفسه.
- رزرو — موجود است، اما از قبل به سفارشی که پولش پرداخت شده تعلق گرفته.
- قابل فروش — موجود منهای رزرو. تنها عددی که فروشگاه باید بر اساس آن بفروشد.
- در راه — از تأمینکننده در راه است، با یک تاریخ مشخص.
فروشگاه اینترنتی معمولاً فقط یک عدد را نگه میدارد. وقتی آن یک عدد تنها عدد موجود باشد، دو اتفاق میافتد. بیشتر از موجودی میفروشید، چون کالا روی قفسه بود اما از قبل به کس دیگری قول داده شده بود. و بیشتر از لازم سفارش میدهید، چون هیچجای سیستم نمیداند سی عدد از همان کالا در راه است.
راهحل این مشکل، جدول بزرگتر نیست. دفتر موجودی است: یک جدول فقطافزودنی که هر حرکت — فروش، مرجوعی، آسیب، رسید کالا، اصلاح، انتقال — در آن یک سطر است با تعداد، دلیل و زمان. هیچ سطری هیچوقت در جای خودش تغییر نمیکند. موجودی فعلی حاصل جمع سطرهاست، و وقتی شمارش اشتباه دربیاید دفتر دقیقاً میگوید کدام حرکت این کار را کرده. عددِ بازنویسیشده هرگز نمیتواند این را بگوید؛ آن عدد از قبل فراموش کرده است.
دو جزئیات پیادهسازی تعیین میکنند این ساختار زیر بار دوام میآورد یا نه. اول، رزرو باید عمر داشته باشد: موجودی وقتی سبد وارد مرحلهٔ پرداخت میشود رزرو میشود و اگر پرداخت کامل نشد با یک زمانسنج آزاد میشود؛ وگرنه یک سبد رهاشده، یک سایز ۴۲ را یک هفته گروگان نگه میدارد. دوم، همان شرایط رقابتی است که همهجا شمارش موجودی را خراب میکند: دو مشتری در یک لحظه موجودی را بررسی میکنند، هر دو یک عدد میبینند و هر دو اجازهٔ پرداخت میگیرند. بررسی و رزرو باید یک گام اتمی باشند. در یک پایگاه دادهٔ رابطهای یعنی یک نوشتن شرطی — UPDATE ... SET reserved = reserved + 1 WHERE available >= 1 و اگر صفر سطر بهروز شد یعنی کالا تمام شده — یا گرفتن سطر با SELECT ... FOR UPDATE پیش از نوشتن. خواندن موجودی و بعد نوشتنش در دو دستور جدا، بیشفروش میکند؛ و دقیقاً در شلوغترین روزتان این کار را میکند، چون همان روز است که دو درخواست بالاخره روی هم میافتند.
جمع زدن یک دفتر با بزرگ شدنش کند میشود. پاسخ متعارف، عکس لحظهای دورهای است: هر شب یک سطر برای هر کالا که مانده تا آن لحظه را نگه میدارد، تا کوئری زنده فقط عکس آخر بهعلاوهٔ امروز را جمع بزند، نه چهار سال تاریخچه را.
مرجوعی: فرایندی که هیچجا مدل نشده
مرجوعی روشنترین نمونهٔ کاری است که کاملاً بیرون از فروشگاه اینترنتی زندگی میکند.
یک مرجوعی شش تغییر وضعیت است: درخواست، تأیید، در راه، دریافت، بررسی، تعیین تکلیف. و «تعیین تکلیف» چهار شاخه دارد — برگشت به موجودی، تعمیر، اسقاط، یا ارسال جایگزین — و هر شاخه اثر متفاوتی روی موجودی دارد و اثر متفاوتی روی پول.
چیزی که اینجا ارزش ساختن دارد یک فیلد وضعیت نیست، یک ماشین حالت صریح است: فهرست وضعیتها، و فهرست گذارهایی که میان آنها مجازند. همین را که بنویسید، دو مشکل همزمان از بین میرود. هیچکس نمیتواند مرجوعی را از «درخواستشده» مستقیم به «بازپرداختشده» ببرد بدون اینکه از «دریافتشده» رد شود، چون چنین گذاری اصلاً وجود ندارد. و چون هر گذار با زمان و نام انجامدهندهاش ذخیره میشود، گزارشها رایگان به دست میآیند: میانگین زمان از دریافت تا بازپرداخت، اینکه چندتا بیشتر از سه روز در مرحلهٔ بررسی ماندهاند، و اینکه کالای کدام تأمینکننده بیشتر برمیگردد. هیچکدام از اینها گزارشنویسی لازم ندارد. یک کوئری است روی سطرهایی که فرایند از قبل تولیدشان میکرد.
همین را دستی روی بیست مرجوعی در هفته اجرا کنید تا چیزها شروع کنند به گم شدن. کالا برمیگردد و هیچوقت به موجودی اضافه نمیشود، پس چیزی را ندارید که در واقع دارید. بازپرداخت دو بار انجام میشود. یک نفر به مشتری میگوید «دریافت کردیم» و نفر بعدی میگوید «نکردیم»، چون جای واحدی برای نگاه کردن وجود نداشت.
هیچکدام از اینها به اشتباه بزرگی نیاز ندارد. فقط کافی است فرایند در پیامها و حافظهٔ آدمها باشد، نه داخل یک سامانه.
سه سؤالی که به تماس تلفنی تبدیل میشوند
تقریباً همهٔ تماس مشتری با یک فروشگاه، سه سؤال است:
- سفارش من کجاست؟
- میشود فاکتور را برایم بفرستید؟
- دفعهٔ قبل چه چیزی خریدم؟
جواب دقیق هر سه، همین حالا داخل دادههای شما نشسته است. اگر مشتری نتواند خودش به آن جواب برسد، هر کدام به یک تماس تلفنی تبدیل میشود و هر تماس، یک نفر را از آن هفت صف بالا بیرون میکشد.
راهحلش جذاب نیست اما اثرش بزرگ است: یک پنل کاربری که مشتری در آن سفارشها، رهگیری، فاکتورها و سابقهٔ خودش را میبیند. این کار رایجترین دلیل تماس را حذف میکند؛ نه با سریعتر جواب دادن، بلکه با از بین بردن نیاز به پرسیدن.
یک مشتری، سه جا
یک نفر از سایت شما خرید میکند، در اینستاگرام پیام میدهد و دربارهٔ ارسال تماس میگیرد. در بیشتر فروشگاهها این سه، سه رکورد بیارتباط است؛ پس هیچکس نمیتواند جواب بدهد «این مشتری قبلاً مشکلی داشته؟» — و این تنها سؤالی است که وقتی مشتری عصبانی است اهمیت دارد.
پروندهٔ مشتری که هویت، همهٔ سفارشها از همهٔ کانالها، همهٔ گفتوگوها، همهٔ مرجوعیها و هر یادداشتی که یک همکار گذاشته را نگه دارد، همان چیزی است که معامله را به رابطه تبدیل میکند. مدیریت ارتباط با مشتری اینجا فقط همین معنا را دارد. محصول جداگانهای برای خریدن نیست؛ جدولی است که سامانههای خودتان در آن مینویسند، تا هر کس گوشی را برداشت از قبل بداند با چه کسی حرف میزند.
رسیدن به آن یک مسئلهٔ تشخیص هویت است و از چیزی که به نظر میرسد مکانیکیتر است. شمارهٔ تلفن را همان موقع ورود به یک قالب بینالمللی واحد تبدیل کنید، تا ۰۹۱۲… و +۹۸۹۱۲… و آن یکی که وسطش فاصله دارد یک رشتهٔ یکسان شوند. ایمیل را کوچک و بدون فاصلهٔ اضافه ذخیره کنید. بعد بر اساس همینها تطبیق بدهید؛ و وقتی معلوم شد دو پرونده یک نفرند، ادغام کنید نه حذف: یک شناسه را زنده نگه دارید، سفارشها را به آن منتقل کنید، و شناسهٔ قدیمی را در یک جدول نامهای مستعار نگه دارید که به شناسهٔ زنده اشاره میکند. اگر اینطور انجامش بدهید، یک لینک قدیمی، یک فاکتور قدیمی یا یک گفتوگوی پشتیبانی قدیمی سالها بعد هم درست باز میشود. اگر بهجایش پروندهٔ بازنده را حذف کنید، یک سال بعدی را صرف پیدا کردن سطرهای بیصاحب میکنید.
همین چیز است که ارزش کسبوکار را از ارزش موجودی انبارش بیشتر میکند. فهرست آدمهایی که از شما خرید کردهاند، همراه با اینکه چه خریدند و کِی، یک دارایی است. فهرست سفارشها فقط یک رسید است.
دستیاری که واقعاً جواب را میداند
دستیار هوشمندی که به مشتری جواب میدهد در یک فروشگاه واقعاً مفید است — اما فقط وقتی به همان سامانههایی وصل باشد که بقیه به آن وصلاند. تفاوت مهم است:
دستیاری که به دادههای شما دسترسی ندارد فقط میتواند قوانین را مبهم توضیح بدهد و دربارهٔ موجودی حدس بزند. مشتری این را در همان اولین رفتوبرگشت میفهمد.
دستیاری که روی سامانههای خودتان تکیه دارد میتواند بگوید از این کالا چهار عدد قابل فروش است، این سفارش سهشنبه با این کد رهگیری ارسال شده، و مهلت مرجوعی اینقدر است چون قانون مکتوب خودتان همین را میگوید.
اینها دو سازوکار متفاوتاند و دانستن تفاوتشان مهم است، چون جور متفاوتی خراب میشوند. سؤالهای مربوط به قوانین با بازیابی جواب داده میشوند: متن قوانین به قطعههای کوچک شکسته میشود، بر اساس معنا و نه کلیدواژه ایندکس میشود، و نزدیکترین قطعهها به سؤال جلوی مدل گذاشته میشوند تا فقط از روی همانها جواب بدهد. اما سؤالهای زنده — موجودی، وضعیت سفارش، رهگیری — اصلاً بازیابی نیستند. اینها فراخوانی معمولی و احرازهویتشدهٔ API هستند که مدل اجازهٔ زدنشان را دارد، و همان عددی را برمیگردانند که صفحهٔ انبار نشان میدهد، چون از همان جدول آمده است.
سه قاعده این را صادق نگه میدارد. فقط از روی چیزی جواب بدهد که بازیابی یا برگردانده شده، و منبعش را نشان بدهد، تا جواب اشتباه قابل ردیابی باشد نه قابل بحث. وقتی بازیابی چیزی بالاتر از آستانهٔ ارتباط پیدا نکرد، همین را بگوید بهجای ساختن جوابی محتمل — یک جواب غلط اما با اطمینان دربارهٔ قانون بازپرداخت، از نبود جواب گرانتر تمام میشود. و دسترسیها را روی خود فراخوانیها اعمال کنید، نه داخل متن دستور: «سفارش مشتریهای دیگر را فاش نکن» یک توصیه است، در حالی که کوئریای که به مشتری واردشده محدود شده یک تضمین است.
همین پایگاه دانش به تیم خودتان هم خدمت میکند؛ بخشی که بیشتر فروشگاهها انتظارش را ندارند. نیروی تازهوارد سؤالهایی را از آن میپرسد که در غیر این صورت باید از همکارش بپرسد.
دو مرز را باید صریح گفت. دستیار باید منبع جوابش را نشان بدهد، تا جواب قابل بررسی باشد نه فقط قابل اعتماد. و هیچوقت نباید تنها مسیر رسیدن به یک آدم باشد؛ دستیاری که نشود از آن عبور کرد، از نبودنش بدتر است.
دانشی که پنجشنبه از در بیرون میرود
در بیشتر فروشگاههایی که از روزی ده سفارش گذشتهاند، دفترچهٔ راهنمای واقعی کسبوکار یک نفر باتجربه است. او میداند کدام تأمینکننده کند است، کدام مشتری دیر پرداخت میکند، برای کالای شکستنی کدام پیک را باید گرفت، و آن استثنایی که فقط برای یک محصول خاص وجود دارد.
وقتی آن نفر مرخصی میرود، همهچیز دو برابر طول میکشد. وقتی برود، بخشی از آن دانش دیگر برنمیگردد.
سامانهای که فرایند را ثبت کند — مراحلی که سفارش طی میکند، قاعدهٔ انتخاب پیک، فهرست بررسی مرجوعی — آموزش نیرو را از یک دورهٔ شاگردی به یک هفته تبدیل میکند. نه به این دلیل که آدمها بیاهمیت میشوند، بلکه چون بخش تکراری دیگر به حافظه وابسته نیست و آنچه برای آموزش میماند، قضاوت است.
مسئلهٔ پایان سال
هر سال همین اتفاق میافتد. موعد مالیات میرسد و یک نفر سه هفته وقت میگذارد تا از روی خروجیها و صورتحسابهای بانکی چیزی را سرهم کند که کسبوکار از اول میدانست:
- چه چیزی فروخته شده، به تفکیک کالا و به تفکیک ماه.
- چه چیزی مرجوع شده و هزینهاش چقدر بوده.
- بهای تمامشده در برابر فروش — یعنی حاشیهٔ سود واقعی، نه آنکه روی لیست قیمت است.
- موجودی پایان سال، با ارزشگذاری.
این کار فقط به این دلیل دردناک است که داده هیچوقت در شکلی نگه داشته نشده که بتواند جواب بدهد. وقتی هر فروش، هر مرجوعی و هر حرکت موجودی یک سطر دفتر با تاریخ و دلیل باشد، گزارش سالانه یک کوئری است، نه یک پروژه.
یک فیلد تعیین میکند که اصلاً میشود حاشیهٔ سود را حساب کرد یا نه: بهای تمامشدهٔ هر قلم در همان لحظهای که فروخته شده، نوشتهشده روی خط سفارش، نه جستوجوشده در آینده. قیمت تأمینکننده تغییر میکند. اگر قیمت امروز را در برابر فروش بهار پارسال بگذارید، حاشیهای که حساب میکنید داستان است. اگر همان لحظه ثبتش کنید، هر دو روش ارزشگذاری برایتان باز میماند: اولینورودی-اولینخروجی که دنبال خود بَچها میرود، یا میانگین موزون که سادهتر است و معمولاً کافی. هر دو قابل دفاعاند. هیچکدام یازده ماه بعد از روی یک لیست قیمت قابل بازسازی نیست. همان داده به سؤالهایی هم جواب میدهد که مالک باید ماهانه بپرسد نه سالانه: کدام کالاها واقعاً سود میدهند، کدام موجودی شش ماه است تکان نخورده، کدام مشتریها برگشتهاند و کدامها فقط یک بار در یک تخفیف آمدهاند.
اینها سؤالهای پایان سال نیستند. اینها تصمیمهای خرید هستند، و بیشتر فروشگاهها آنها را از روی حافظه میگیرند، چون درآوردن عددش خیلی طول میکشد.
آن موتور پشت صحنه دقیقاً چیست
هیچکدام از اینها معماری عجیبی لازم ندارد. یک سامانهٔ مرجع لازم دارد با چهار چیز داخلش:
- یک هویت برای هر مشتری، از هر کانالی که سفارش آمده باشد.
- یک دفتر موجودی، که هر حرکت یک سطر است و عدد از روی سطرها محاسبه میشود.
- یک چرخهٔ عمر سفارش — مراحل واقعی کسبوکار خودتان، از جمله مراحل دردسرساز، که هرکدام بگوید منتظر چه کاری است و مسئولش کیست.
- یک تاریخچه، که برای همیشه نگه داشته میشود؛ چون هر گزارشی که در آینده بخواهید، سؤالی دربارهٔ گذشته است.
فروشگاه اینترنتی آنوقت همان چیزی میشود که از اول بود: یکی از کانالهایی که در این سامانه مینویسد. اینستاگرام هم همینطور، سفارش تلفنی هم، مشتری حضوری هم. سایت دیگر خودِ کسبوکار نیست؛ ویترین کسبوکار است، که دقیقاً همان چیزی است که هست.
لازم نیست همهٔ اینها را روز اول داشته باشید
این متن دعوت به توقف همهچیز و ساختن یک پلتفرم بزرگ نیست. دعوت به ساختن با ترتیبی است که کمترین درد را دارد:
- اول چرخهٔ عمر سفارش و صفهای کاری. روز شلوغ همینجا خراب میشود و ارزانترین مورد این فهرست هم همین است.
- بعد دفتر موجودی — بهمحض اینکه دو بار بیشتر از موجودی فروخته باشید.
- پنل مشتری — رهگیری، فاکتور و سابقه بهصورت خودسرویس، که بیشتر تماسهای ورودی را حذف میکند.
- مرجوعی بهعنوان یک فرایند واقعی، وقتی مرجوعی آنقدر زیاد شد که دیگر استثنا نباشد.
- یک پروندهٔ واحد برای مشتری در همهٔ کانالها، وقتی مشتریها از بیش از یک جا میآیند.
- گزارشگیری، که تا این مرحله تقریباً رایگان است؛ داده از قبل در شکل درست است.
- دستیار هوشمند در آخر، چون کیفیتش بیشتر از سامانههایی که از آنها میخواند نمیشود.
هر مرحله همان روزی که تحویل میشود مفید است و مرحلهٔ بعدی را ارزانتر میکند. هیچکدامشان هم به دور انداختن فروشگاه فعلی نیاز ندارند.
کجا این جواب اشتباهی است
فروشگاهی که ماهی چهل سفارش دارد به هیچکدام از اینها نیاز ندارد و ساختنشان راه گرانی برای فرار از یک فایل اکسل است. مرز، یک عدد فروش نیست — روزی است که یک سؤال بسته به اینکه از چه کسی بپرسید جوابهای متفاوت میگیرد، و روزی است که کار روزمره دیگر در ذهن یک نفر جا نمیشود.
پیش از آن روز، یک فروشگاه اینترنتی و یک آدم دقیق، معماری درستی است. بعد از آن روز، بهای هر هفتهٔ اضافه با کالای بیشفروختهشده، مرجوعی گمشده و مشتریای که برنگشت پرداخت میشود — و هیچکدام از اینها در هیچ گزارشی بهصورت یک عدد دیده نمیشود.