ما وراء القالب: كيف بنيت واجهات متجر Salla عالية الأداء مع Apple Pay
تعمق معماري في توسيع واجهات المتاجر القائمة على Salla بنظام headless وإتقان تعقيدات تكامل Apple Pay. أشارككم استراتيجيات الطبقة الوسطى (middle-tier) التي استخدمتها لحل تحديات المزامنة وفك تشفير الدفع.

ما وراء القالب: إتقان تكاملات Salla و Apple Pay
لفترة طويلة، سيطرت واجهات المتاجر الجامدة القائمة على القوالب على مشهد التجارة الإلكترونية في منطقة الشرق الأوسط وشمال أفريقيا (MENA). ولكن مع تحول توقعات المستخدمين نحو تجارب Native عالية الأداء، وجدت نفسي أمام تحدٍ هندسي كبير: فصل واجهة المستخدم (front-end) عن منظومة Salla مع الحفاظ على تكامل قوي لما يُعرف بـ "Universal Apps".
في هذا المقال، سأتجاوز الأمور الأساسية. أريد التحدث عن العقبات المعمارية الحقيقية التي واجهتها — وتحديداً دورة حياة OAuth، وإدارة الحالة (state management) عبر المنصات المختلفة، والوحش الحقيقي وهو فك تشفير Apple Pay في بيئة headless.
حلقة OAuth: أكثر من مجرد Token
عندما تبني تطبيق جوال مخصص أو واجهة متجر Next.js عالية الأداء فوق Salla، فإن أول عقبة تواجهك هي تدفق OAuth. تتعامل معظم الوثائق معه كإعداد لمرة واحدة، ولكن في بيئة الإنتاج، تصبح إدارة دورة حياة access_token و refresh_token عبر آلاف الجلسات المتزامنة أمراً معقداً.
أدركت مبكراً أن الاعتماد على العميل (client) لإدارة هذه الـ tokens كان وصفة لحدوث race conditions. لذا انتقلت إلى Token Manager Service مركزي.
من خلال تنفيذ distributed lock باستخدام Redis، قضيت على طفرات "401 unauthorized" التي تحدث عادةً عندما تحاول وظائف serverless متعددة تجديد نفس token التاجر في وقت واحد.
الجسر "الشامل" (Universal Bridge)
أحد أكبر إنجازاتي كان الابتعاد عن استدعاءات API المباشرة من تطبيق الجوال إلى Salla. بدلاً من ذلك، قمت ببناء BFF (Backend for Frontend). لماذا؟ لأن API الخاص بـ Salla، رغم قوته، ليس دائماً محسناً لحمولات بيانات (payloads) الجوال.
بالنسبة لـ Universal App (iOS، Android، و Web)، تحتاج إلى schema بيانات موحدة. استخدمت GraphQL في BFF لتجميع نقاط نهاية REST الخاصة بـ Salla. قلل هذا من العبء على تطبيق الجوال بنسبة 60%، حيث كنا نجلب فقط أجزاء المنتجات (fragments) المطلوبة للعرض، بدلاً من كائنات JSON الضخمة التي تعيدها Salla افتراضياً.
حل معضلة Apple Pay
تعتبر Apple Pay المعيار الذهبي للتحويل (conversion) في منطقتنا، لكن دمجها في تطبيق مخصص مدعوم من Salla أمر صعب للغاية. المشكلة الأساسية ليست في واجهة المستخدم؛ بل في عملية المصافحة (handshake) بين Apple Merchant Identity، و Salla Gateway، وخلفيتك البرمجية (backend) المخصصة.
الاختراق: استراتيجية فك التشفير
عندما يضغط المستخدم على زر Apple Pay، تتلقى كائن PKPayment. إذا كنت تستخدم بوابة دفع معينة مثل Checkout.com أو Moyasar عبر Salla، فأنت لا ترغب فعلياً في فك تشفير الـ token بنفسك على جانب الجوال. بل تريد تمرير Encrypted Payment Data مباشرة إلى نقطة نهاية إكمال الدفع في Salla.
ومع ذلك، كان التحدي الهندسي الحقيقي الذي واجهته هو التعامل مع تحديثات Shipping Contact. إذا كان تطبيقك يغير تكلفة الشحن بناءً على المدينة المختارة في ورقة Apple Pay، فيجب عليك الرد ضمن نافذة 30ms المطلوبة بواسطة didSelectShippingContact delegate.
من خلال تخزين مناطق وأسعار الشحن مؤقتاً في قاعدة بيانات SQLite/Room محلية على الجهاز، قمت بتجاوز زمن انتقال الشبكة (network latency) الذي يتسبب عادةً في انتهاء مهلة جلسات Apple Pay.
Webhooks: مصدر الحقيقة
في إعداد headless، يمكن لقاعدة البيانات المحلية الخاصة بك أن تصبح بسهولة غير متزامنة مع حالة Salla. تعاملت مع Salla Webhooks كـ "مصدر للحقيقة" (Source of Truth). لكن الـ webhooks غير موثوقة — فقد تصل بترتيب خاطئ.
قمت بتنفيذ Idempotency Layer. كل حدث webhook من Salla (مثل order.updated أو product.created) يتم تسجيله في جدول processed_events مع معرف الحدث الفريد الخاص بـ Salla. قبل المعالجة، نتحقق مما إذا كان هذا المعرف موجوداً. حمى هذا النظام من احتساب الإيرادات مرتين أو تكرار الطلبات خلال أحداث المبيعات ذات الزخم العالي.
كلمات أخيرة
إن هندسة واجهة متجر حديثة على Salla لا تقتصر فقط على إجراء استدعاءات API؛ بل تتعلق ببناء طبقة وسطى مرنة يمكنها التعامل مع فروق أداء الجوال والمدفوعات الآمنة. رحلتي من القوالب الأساسية إلى بنية منفصلة تماماً (decoupled) وجاهزة لـ Apple Pay علمتني أن الأجزاء "المملة" — إدارة الـ tokens، التخزين المؤقت، و idempotency — هي في الواقع المكان الذي تحدث فيه الهندسة الأكثر أهمية.
إذا كنت تبني في هذا المجال، توقف عن التفكير في واجهة المستخدم وابدأ في التركيز على تنظيم البيانات (data orchestration). فهناك تكمن مكاسب الأداء الحقيقية.