Fintech · Microserviceفينتك · Microservice

Miswag Pay

Miswag's payment stack was fragmented across five different gateway integrations, each owned by a different part of the platform. I was asked to unify them — one microservice, one API, five gateways, production in four months. كانت منظومة الدفع في Miswag مشتتة عبر خمس تكاملات مختلفة مع بوابات الدفع، تمتلك كل منها جزء مختلف من المنصة. طُلب مني توحيدها — Microservice واحد، API واحد، خمس بوابات، وإطلاق في الإنتاج خلال أربعة أشهر.

Five gateways, no single source of truthخمس بوابات، ولا مرجع موحّد

Miswag operates across Iraq's major payment networks — ZainCash, SuperQi, QiPay, and Aqsati for wallet-based payments, plus HyperPay for card payments. Each gateway had its own authentication model, request format, webhook structure, and failure behavior. The rest of the platform dealt with all of this directly through point-to-point integrations, making each one fragile, hard to monitor, and expensive to change. There was no central view of payment state across the system. تعمل Miswag عبر شبكات الدفع الرئيسية في العراق — ZainCash وSuperQi وQiPay وAqsati للمحافظ الإلكترونية، إضافةً إلى HyperPay لمدفوعات البطاقات. كانت لكل بوابة نموذج مصادقة وتنسيق طلبات وهيكل Webhook وسلوك أعطال خاص بها. كانت بقية المنصة تتعامل مع كل هذا مباشرةً عبر تكاملات نقطة إلى نقطة، مما جعل كل واحدة هشة وصعبة المراقبة ومكلفة التعديل. لم تكن ثمة رؤية مركزية لحالة المدفوعات عبر النظام.

Security at scale across five untrusted callback surfacesالأمان على نطاق واسع عبر خمس نقاط استدعاء غير موثوقة

Five gateways means five different webhook formats, five authentication schemes, and five different failure modes — all of them inbound to a service processing over a million transactions per month. The security challenge was significant: a spoofed or replayed gateway callback at this volume could trigger fraudulent transactions before anyone noticed. Building a unified abstraction that was developer-friendly and genuinely secure — not just "check a signature" — was the core problem to solve. خمس بوابات تعني خمسة تنسيقات مختلفة لـ Webhook، وخمس مخططات مصادقة، وخمسة أنماط أعطال — كلها واردة إلى خدمة تعالج أكثر من مليون معاملة شهرياً. كان التحدي الأمني جوهرياً: استدعاء مزوّر أو مُعاد تشغيله بهذا الحجم قد يُطلق معاملات احتيالية قبل أن يلاحظها أحد. بناء تجريد موحّد يكون سهل الاستخدام للمطورين وآمناً فعلياً — لا مجرد "التحقق من التوقيع" — كان جوهر المشكلة.

Three choices that defined the serviceثلاثة قرارات شكّلت الخدمة

Microservice, not a shared libraryMicroservice لا مكتبة مشتركة

The alternative to a microservice was a Laravel package that each part of the platform would install and call directly. I chose the microservice boundary instead because payment credentials, security logic, and transaction state needed to be isolated — not distributed across every service that needed to charge a customer. A single JWT-authenticated API meant one place to audit, monitor, and update. If a gateway changes its API, one service changes, not five. كان البديل عن الـ Microservice هو حزمة Laravel تثبّتها كل جزء من المنصة وتستدعيها مباشرةً. اخترت حدود الـ Microservice لأن بيانات اعتماد الدفع ومنطق الأمان وحالة المعاملات بحاجة إلى عزل — لا توزيع على كل خدمة تحتاج إلى تحصيل رسوم. API واحد مع مصادقة JWT يعني مكاناً واحداً للتدقيق والمراقبة والتحديث. إذا غيّرت بوابة ما API الخاصة بها، تتغير خدمة واحدة فقط، لا خمس.

HMAC-SHA256 webhook verification with replay preventionالتحقق من Webhook بـ HMAC-SHA256 مع منع إعادة التشغيل

Every inbound gateway webhook is verified against an HMAC-SHA256 signature computed from the request body and a shared secret. I added a replay-attack prevention layer that rejects any webhook with a timestamp more than five minutes old, and checks incoming signature hashes against a rolling window of recently seen values. This made the inbound callback surface safe against both spoofing and replays — meaningful protection at 1M+ tx/month where a single vulnerability window could affect thousands of transactions. كل Webhook وارد من بوابة يُتحقق منه باستخدام توقيع HMAC-SHA256 محسوب من جسم الطلب وسر مشترك. أضفت طبقة لمنع هجمات إعادة التشغيل ترفض أي Webhook بطابع زمني أقدم من خمس دقائق، وتفحص هاشات التوقيعات الواردة مقابل نافذة متحركة من القيم المرصودة مؤخراً. هذا جعل سطح الاستدعاء الوارد محمياً ضد كل من الانتحال وإعادة التشغيل — حماية فعلية عند 1M+ معاملة شهرياً حيث نافذة ثغرة واحدة قد تطال آلاف المعاملات.

Unified gateway interface: charge, verify, refund, handle Webhookواجهة موحّدة للبوابات: الشحن، التحقق، الاسترداد، معالجة Webhook

Each gateway implements a common four-method interface. Calling services never know which gateway is active — they call the same API regardless. Gateway-specific quirks (HyperPay's session-based card flow vs. ZainCash's redirect model vs. SuperQi's escrow variant) are handled entirely inside the adapter layer. The result: adding a sixth gateway means implementing the interface. The core service, the API contract, and every calling service remain unchanged. كل بوابة تُنفّذ واجهة مشتركة من أربع دوال. الخدمات المستدعية لا تعرف أبداً أي بوابة نشطة — تستدعي نفس الـ API بغض النظر. التفاصيل الخاصة بكل بوابة (تدفق البطاقة المبني على الجلسة في HyperPay مقابل نموذج إعادة التوجيه في ZainCash مقابل نوع الضمان في SuperQi) تُعالَج بالكامل داخل طبقة المحوّل. النتيجة: إضافة بوابة سادسة تعني تنفيذ الواجهة فقط. الخدمة الأساسية وعقد الـ API وكل خدمة مستدعية تبقى دون تغيير.

One service, one contract, production in four monthsخدمة واحدة، عقد واحد، إنتاج في أربعة أشهر

4 mo٤ شهر

Solo build to productionمن الصفر للإنتاج منفرداً

1 M+١ مليون+

Transactions / monthمعاملة شهرياً

5٥

Gateways unifiedبوابات موحّدة

0٠

Security incidents in productionحوادث أمنية في الإنتاج