→ كل الأعمالسوق فعاليات وتجارب لعُمان: يُدرِج البائعون الفعاليات والتجارب، ويبيعون تذاكر متعدّدة الفئات، ويُجرون تسجيل دخول QR يوم الفعالية، بينما يكتشف العملاء ويحجزون ويدفعون بالريال العُماني عبر تطبيق ويب Next.js وتطبيق جوال أصلي.
سوق ذو جانبين: بوابة بائع + ويب للعملاء + تطبيق أصليدورة حياة تذكرة QR مع تسجيل دخول يحتمل عدم الاتصالAmwalPay — موقّع بـ HMAC، مُسوّى عبر webhook، تسوية بالريال العُماني

المشكلة
لم يكن لدى منظّمي الفعاليات والتجارب المحلّيين في عُمان منصّة واحدة مناسبة للسوق لبيع التذاكر وإدارة البوابة. كان إدراج المخزون، وتحصيل الدفع بالريال العُماني، وإصدار التذاكر، والتحقّق من الحاضرين عند المدخل موزّعاً على أدوات عامّة وقوائم يدوية — ولا شيء منها يتعامل مع قوائم بالعربية أولاً، أو بوّابة دفع محلّية، أو تسجيل دخول موثوق يصمد أمام اتصال متقطّع في الموقع.
المنهجية
بنينا MyTicket كسوق ذي جانبين في أحادي-مستودع Turborepo: تطبيق ويب للعملاء بـ Next.js 16، وبوابة بائع ذاتية الخدمة، وتطبيق جوال أصلي بـ Expo/React Native، جميعها فوق خلفية Drizzle و Neon Postgres واحدة مع Better Auth (إضافة المؤسسات) تفصل بين العملاء والبائعين والمسؤولين. يُنشئ البائعون منتجات فعالية/تجربة بفئات تذاكر متعدّدة، وفتحات إتاحة بتاريخ ثابت بسعة فعلية، ونماذج حجز ونماذج لكل حاضر مخصّصة، وسياسات استرداد، ومدفوعات، وتحليلات. الدفع رحلة موجّهة مع حجز مخزون لمدّة ١٥ دقيقة كيلا تُباع التذاكر مرّتين أثناء تنفيذ الدفع. يجري الدفع عبر AmwalPay (عُمان) بتوقيع طلبات HMAC-SHA256 ومسار تسوية تكون فيه الكلمة الفصل لـ webhook وهو خامل (idempotent) — يُكتشف أي نداء مكرّر من المزوّد عبر المرجع النظامي ولا يؤكّد الحجز مرّتين أبداً. كل حجز مدفوع يتفرّع إلى تذاكر فردية، لكلٍّ رمز QR فريد ودورة حياة صالحة ← مستخدمة ← منتهية. يتحقّق ماسح البائع من التذاكر عند البوابة ويميّز بين النجاح والمَسح المسبق وغير الصالحة والمنتهية والملغاة وتذكرة بائع آخر، ويكتب كل مسح في سجلّ تدقيق؛ ويحتفظ طابور مسح دون اتصال بالبيانات في التخزين المحلّي ويُزامنها دفعةً مع إعادة محاولة عند عودة الاتصال، فتستمر حركة البوابة حتى دون إشارة. تُرسَل التأكيدات بالبريد مع مرفق تقويم ICS.
النتيجة
MyTicket تشغيلي في الإنتاج في عُمان على حساب تاجر AmwalPay فعلي، ويُسوّي مبيعات التذاكر بالريال العُماني. يدير البائعون الدورة الكاملة بأنفسهم — الإدراج، والبيع، والتحقّق عند البوابة، والتسوية، وتلقّي المدفوعات — من البوابة، بينما يشتري العملاء عبر الويب أو التطبيق الأصلي على iOS و Android. يصمد تسجيل دخول QR عند البوابة سواء توفّر اتصال مستقرّ في الموقع أم لا، وتسوية الدفع تكون الكلمة الفصل فيها لـ webhook فيُؤكَّد الحجز المؤكَّد مرّةً واحدة بالضبط.
نطاق الارتباط
- سوق ذو جانبين فوق نموذج Better Auth واحد: عملاء وبائعون ومسؤولو منصّة
- بوابة البائع: منتجات (فعالية/تجربة)، فئات تذاكر متعدّدة، إتاحة بتاريخ ثابت بسعة، نماذج حجز وحاضرين مخصّصة، سياسات استرداد، مدفوعات، وتحليلات
- رحلة دفع موجّهة مع حجز مخزون لمدّة ١٥ دقيقة لمنع البيع الزائد أثناء الدفع
- تكامل AmwalPay — توقيع HMAC-SHA256، تدفّق إعادة توجيه، تسوية خاملة تكون الكلمة الفصل فيها لـ webhook، تسوية بالريال العُماني
- توليد QR لكل تذكرة ودورة حياة صالحة/مستخدمة/منتهية/ملغاة مع سجلّ تدقيق لأحداث المسح
- ماسح QR للبائع بكشف المَسح المسبق / تذكرة بائع آخر / المنتهية وطابور مسح يحتمل عدم الاتصال (حفظ بالتخزين المحلّي، إعادة محاولة، مزامنة دفعية)
- تطبيق جوال أصلي بـ Expo / React Native (iOS و Android) يشارك الخلفية نفسها، بروابط عميقة myticket.om
- عربي وإنجليزي، آمن لـ RTL؛ تأكيدات بريد مع مرفقات تقويم ICS
Next.js 16TypeScriptReact 19Drizzle ORMNeon PostgresBetter Auth (Organization)AmwalPayExpo / React NativeTurborepo