سیستمعامل فروشگاه، بخش ۱: عاملهای تجاری روی Workers و D1
ساخت سبد خرید، پرداخت و مسیر کارتبهکارت تیتان روی Cloudflare Workers و D1 — دو پست اول از مجموعهای درباره ساخت فروشگاه خودمان روی همان زیرساختی که میفروشیم.
چرا این را مینویسیم
تیتان فروشگاه چاپ سهبعدی خودِ ماست — نه یک همکاری با مشتری، پول و موجودی خودمان، ساختهشده روی React Router 7، Cloudflare Workers، D1، KV و R2، دقیقاً همان پلتفرمی که میفروشیم. «سیستمعامل فروشگاه» گزارش ساخت آن است: تصمیمهای واقعی، باگهای واقعی، بدون رنگوروغن تبلیغاتی. تیتان هنوز راهاندازی نشده — این پست سشن ۳ (سبد خرید و پرداخت) و سشن ۸ (موتور اتوماسیون) را پوشش میدهد، درحالیکه ساخت هنوز پیش از راهاندازی است.
هسته تجاری
خطوط سبد خرید قیمت را ذخیره نمیکنند — فقط { variantId, qty }. هر خواندن، قیمت زنده را
دوباره محاسبه میکند و هر چیزی که واقعاً موجود نباشد را حذف میکند. این تصمیم در میانه
همان سشن جواب داد: تست دستی نشان داد بدون این کار، یک محصول پیشفروش میتوانست با قیمت
قدیمی نامحدود در سبد بماند. محاسبه دوباره در هر خواندن، این شکاف را رایگان بست.
کارتبهکارت بهعنوان روش پرداخت درجهیک
ایران به درگاههای کارت بینالمللی دسترسی ندارد. انتقال بانکی کارتبهکارت — مشتری مستقیم پول را واریز میکند و ادمین دستی تأیید میکند — اینجا یک جایگزین نیست، مسیر اصلی پرداخت است. بخش جالب یک جزئیات کوچک است: هر سفارش یک افست تصادفی ۱ تا ۹۹ تومانی به مبلغ انتقالش اضافه میکند. کل ترفند همین است — مبلغ دقیق هر انتقال معلق را یکتا میکند، تا ادمینی که یک انتقال بانکی ورودی را با سفارش تطبیق میدهد، فقط با مبلغ این کار را بکند، بدون دنبال کردن دستی شماره پیگیری.
یکپارچهسازی درگاه زرینپال هم بهطور کامل و همزمان ساخته شده، پشت یک فلگ ویژگی تا تأیید نماد اعتماد اینماد بیاید. این یک انتخاب عمدی است، نه یک فراموشی — کارتبهکارت امروز تنها مسیر پرداخت فعال است چون تنها روشی است که واقعاً مجوز اجرا دارد.
باگی که اهمیت داشت: فونتهای PDF
تولیدکننده فاکتور از pdf-lib استفاده میکند که دقیقاً همان بایتهای فونتی که به آن داده
شود را جاسازی میکند. فایلهای فونت اولیه، فایلهای .woff2 فونتسورس بودند — معتبر در
مرورگر، اما بهعنوان برنامه فونت جاسازیشده در PDF معتبر نیست. ساخت موفق شد، typecheck رد
شد و کد درست بهنظر میرسید. تا وقتی خروجی واقعی PDF را با یک رندرکننده واقعی رندر نکردیم،
خطای FT_New_Memory_Face: unknown file format آشکار نشد و صفحه فاکتور بصری خالی درآمد.
درسی که ماند: فونتی که در مرورگر رندر میشود و فونتی که در PDF جاسازی میشود، یک ادعای
یکسان نیستند، و فقط رندر کردن آرتیفکت واقعی این تفاوت را نشان میدهد.
ده عامل، یک Cron Trigger، بدون شعاع انفجار مشترک
سشن ۸ موتور اتوماسیون را سیمکشی کرد: یک Cron Trigger کلادفلر هر ۱۵ دقیقه اجرا میشود و به ده وظیفه مستقل شاخه میزند — بازیابی سبد رهاشده، نگهبان کارتبهکارت که صف تأیید را زیر نظر دارد و وقتی چیزی خیلی طولانی معلق بماند به مالک اطلاع میدهد، هشدارهای موجودی مجدد، یک یادداشت امکانسنجی نوشتهشده توسط Claude برای درخواستهای سفارشی جدید (قیمت همیشه از یک فرمول قطعی میآید — مدل هرگز قیمت تعیین نمیکند)، پیشنویس پاسخ برای تیکتهای باز پشتیبانی، دایجست روزانه تلگرامی، یک عامل هفتگی پیشنویس محتوا که مینویسد اما هرگز خودش منتشر نمیکند، و پشتیبانگیری شبانه D1. هر وظیفه در try/catch مخصوص خودش پیچیده شده و در هر اجرا سطر وضعیت خودش را مینویسد، صرفنظر از اینکه کاری انجام داده یا نه — پس یک روز بد برای یک عامل، بقیه را با خودش پایین نمیکشد، و یک خرابی بیصدا هرگز بدون رد پا ناپدید نمیشود.
چه چیزی بعد میآید
بخش دوم سشن ۴ را پوشش میدهد — ورود با کد پیامکی ساختهشده برای شکل واقعی تأیید هویت خریداران ایرانی، و طراحی محدودیت نرخی که مانع سوءاستفاده از آن میشود. داستان کامل ساخت، با تمام کاستیها، در /fa/work/titan است. اگر پلتفرم تجاریای میخواهید که به همین شکل ساخته شود — عاملهای واقعی، مسیر واگذاری برای هر چیزی که نباید بدون نظارت اجرا شود — درباره ساخت فروشگاه آنلاین با ما بخوانید.
چکلیستی برای پروژه خودتان میخواهید؟
بگویید روی چه چیزی کار میکنید — ظرف ۴۸ ساعت با یک طرح اولیه معماری پاسخ میدهیم.
پست بعدی: سیستمعامل فروشگاه، بخش ۲: ورود با کد پیامکی برای بازار ایران