Files
Siro/walletintaleq.intaleq.xyz/mtnpayment.html
2026-06-11 18:22:59 +03:00

293 lines
19 KiB
HTML
Executable File

<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>الدليل التفاعلي للتكامل بين Intaleq و MTN</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700;800&display=swap" rel="stylesheet">
<style>
body { font-family: 'Tajawal', sans-serif; scroll-behavior: smooth; }
.code-block { background-color: #1e293b; color: #e2e8f0; padding: 1rem; border-radius: 0.5rem; direction: ltr; text-align: left; font-family: 'Courier New', Courier, monospace; }
.tab-active { border-color: #3b82f6; color: #3b82f6; background-color: #eff6ff; }
.tab-inactive { border-color: transparent; color: #4b5563; }
.endpoint-section { display: none; }
.endpoint-section.active { display: block; }
.flow-step { position: relative; padding-right: 40px; }
.flow-step:not(:last-child)::before { content: ''; position: absolute; right: 15px; top: 40px; bottom: -20px; width: 2px; background-color: #d1d5db; }
.flow-number { position: absolute; right: 0; top: 0; width: 32px; height: 32px; }
</style>
</head>
<body class="bg-slate-50 text-slate-800">
<div class="max-w-6xl mx-auto p-4 md:p-8">
<header class="text-center mb-12">
<div class="inline-block bg-blue-600 text-white p-4 rounded-full shadow-lg mb-4">
<svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" /></svg>
</div>
<h1 class="text-4xl font-extrabold text-slate-900">الدليل التفاعلي للتكامل بين Intaleq و MTN</h1>
<p class="mt-4 text-lg text-slate-600 max-w-3xl mx-auto">دليلك الكامل لفهم واختبار آلية الدفع عبر MTN. تم تصميم هذا الدليل لتسهيل عملية التطوير وضمان تكامل سلس وفعال.</p>
</header>
<div class="bg-white p-8 rounded-2xl shadow-lg border border-slate-200">
<!-- Flow Section -->
<section id="flow" class="mb-12">
<h2 class="text-2xl font-bold mb-6 border-r-4 border-blue-500 pr-4">آلية عمل دورة الدفع</h2>
<div class="space-y-8">
<div class="flow-step">
<div class="flow-number flex items-center justify-center bg-slate-200 text-slate-600 rounded-full font-bold text-lg">1</div>
<h3 class="font-bold text-lg text-slate-800">إنشاء الفاتورة</h3>
<p class="text-slate-600">يبدأ المستخدم (سائق/راكب) عملية الدفع من تطبيق Intaleq، فيقوم نظامنا بإنشاء فاتورة داخلية بحالة "انتظار".</p>
</div>
<div class="flow-step">
<div class="flow-number flex items-center justify-center bg-slate-200 text-slate-600 rounded-full font-bold text-lg">2</div>
<h3 class="font-bold text-lg text-slate-800">استعلام MTN</h3>
<p class="text-slate-600">عندما يقوم المستخدم بفتح تطبيق MTN Cash Mobile للدفع، يقوم سيرفر MTN بإرسال طلب استعلام إلى سيرفرنا باستخدام رقم هاتف المستخدم للتحقق من وجود فاتورة معلقة وقيمتها.</p>
</div>
<div class="flow-step">
<div class="flow-number flex items-center justify-center bg-slate-200 text-slate-600 rounded-full font-bold text-lg">3</div>
<h3 class="font-bold text-lg text-slate-800">تأكيد الدفع</h3>
<p class="text-slate-600">بعد أن يكمل المستخدم عملية الدفع بنجاح في تطبيق MTN، يقوم سيرفر MTN بإرسال طلب تأكيد (Webhook) إلى سيرفرنا يحتوي على تفاصيل العملية الناجحة.</p>
</div>
<div class="flow-step">
<div class="flow-number flex items-center justify-center bg-green-500 text-white rounded-full font-bold text-lg">4</div>
<h3 class="font-bold text-lg text-slate-800">إتمام العملية</h3>
<p class="text-slate-600">يتحقق سيرفرنا من صحة طلب التأكيد، ويقوم بتحديث حالة الفاتورة إلى "مكتملة"، ثم يضيف الرصيد تلقائياً إلى محفظة المستخدم في تطبيق Intaleq.</p>
</div>
</div>
</section>
<!-- Security Section -->
<section id="security" class="mb-12 p-6 bg-slate-100 rounded-xl">
<h2 class="text-2xl font-bold mb-4 border-r-4 border-blue-500 pr-4">آلية الحماية والتوثيق</h2>
<p class="text-slate-700 mb-4">لضمان أن جميع الطلبات تأتي من مصدر موثوق (سيرفرات MTN حصراً)، نعتمد على آلية المفتاح السري المشترك (Shared Secret Key). يجب على سيرفراتكم إرسال هذا المفتاح في كل طلب يتم إرساله إلى نقاط النهاية الخاصة بنا.</p>
<div class="bg-white p-4 rounded-lg shadow-sm">
<p class="font-semibold">الهيدر المطلوب: <code class="text-red-600">X-AUTH-TOKEN</code></p>
<div class="bg-orange-50 border border-orange-200 p-3 rounded-md mt-2">
<p class="text-sm text-orange-800 font-medium">سيتم تزويدكم بالمفتاح السري (Secret Key) بشكل آمن عبر قنوات التواصل الرسمية.</p>
</div>
</div>
</section>
<!-- IP Whitelisting Section -->
<section id="ip-whitelisting" class="mb-12 p-6 bg-yellow-50 border border-yellow-300 rounded-xl">
<div class="flex items-start">
<div class="flex-shrink-0">
<svg class="h-6 w-6 text-yellow-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
</div>
<div class="mr-4">
<h2 class="text-2xl font-bold mb-4 border-r-4 border-yellow-500 pr-4">زيادة مستوى الأمان: القائمة البيضاء (IP Whitelisting)</h2>
<p class="text-yellow-800 mb-3">للوصول إلى أعلى مستويات الأمان وحماية التكامل، نعتمد آلية القائمة البيضاء لعناوين IP. هذه الآلية تضمن أن سيرفراتنا لن تقبل الطلبات إلا من سيرفرات MTN المصرح بها حصراً.</p>
<div class="bg-white p-4 rounded-lg shadow-sm border border-yellow-200">
<p class="font-bold text-slate-800">الإجراء المطلوب:</p>
<p class="mt-2 text-slate-700">نرجو منكم تزويدنا بقائمة ثابتة وكاملة لجميع عناوين IP العامة (Public IPs) التي تستخدمونها لإرسال الطلبات إلى نقاط النهاية الخاصة بنا، ليقوم فريقنا بإضافتها إلى جدار الحماية.</p>
</div>
</div>
</div>
</section>
<!-- API Endpoints Section -->
<section id="api-endpoints">
<h2 class="text-2xl font-bold mb-6 border-r-4 border-blue-500 pr-4">نقاط النهاية (API Endpoints)</h2>
<div class="flex border-b border-slate-200 mb-6">
<button class="api-tab p-4 text-lg font-semibold border-b-2 tab-active" onclick="showEndpoint('query')">1. الاستعلام عن فاتورة</button>
<button class="api-tab p-4 text-lg font-semibold border-b-2 tab-inactive" onclick="showEndpoint('webhook')">2. تأكيد الدفع (Webhook)</button>
</div>
<!-- Query Invoice Endpoint -->
<div id="query-section" class="endpoint-section active">
<h3 class="text-xl font-bold mb-2">نقطة النهاية: الاستعلام عن فاتورة</h3>
<p class="mb-4 text-slate-600">تستخدمها سيرفرات MTN للتحقق من وجود فاتورة معلقة لمستخدم معين قبل عرضها له في تطبيق الدفع.</p>
<div class="grid md:grid-cols-2 gap-6">
<div>
<h4 class="font-semibold mb-2">تفاصيل الطلب:</h4>
<div class="bg-slate-50 p-4 rounded-lg border border-slate-200 space-y-3">
<p><strong>Method:</strong> <span class="bg-sky-100 text-sky-800 font-mono text-sm font-bold mr-2 px-2.5 py-0.5 rounded">GET</span></p>
<div>
<p><strong>URL:</strong></p>
<div class="flex items-center">
<code class="text-sm break-all flex-grow" id="queryUrl">https://walletintaleq.intaleq.xyz/v1/main/ride/mtn_new/query_mtn_invoice.php</code>
<button onclick="copyToClipboard('queryUrl')" class="text-blue-500 hover:text-blue-700 text-xs mr-2 flex-shrink-0">نسخ</button>
</div>
</div>
<p><strong>Header:</strong> <code class="text-sm">X-AUTH-TOKEN: [المفتاح السري]</code></p>
<p><strong>Query Parameter:</strong></p>
<ul class="list-disc pr-6 text-sm">
<li><code>phone_number</code> (إلزامي): رقم هاتف المستخدم.</li>
</ul>
</div>
</div>
<div>
<h4 class="font-semibold mb-2">جرّب الآن:</h4>
<div class="space-y-4">
<div>
<label for="query-phone" class="block text-sm font-medium text-slate-700">رقم الهاتف:</label>
<input type="text" id="query-phone" class="mt-1 block w-full px-3 py-2 bg-white border border-slate-300 rounded-md text-sm shadow-sm placeholder-slate-400 focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500" placeholder="e.g., 9639xxxxxxxx">
</div>
<button onclick="testQuery()" class="w-full bg-blue-600 text-white font-bold py-2 px-4 rounded-lg hover:bg-blue-700 transition duration-300">إرسال طلب استعلام</button>
</div>
</div>
</div>
<div class="mt-6">
<h4 class="font-semibold mb-2">الاستجابات المتوقعة:</h4>
<pre id="query-response" class="code-block min-h-[100px]"><code>// The response from the server will appear here...</code></pre>
</div>
</div>
<!-- Webhook Handler Endpoint -->
<div id="webhook-section" class="endpoint-section">
<h3 class="text-xl font-bold mb-2">نقطة النهاية: تأكيد الدفع (Webhook)</h3>
<p class="mb-4 text-slate-600">بعد إتمام الدفع، يجب على سيرفرات MTN إرسال طلب إلى نقطة النهاية هذه لتأكيد العملية وإضافة الرصيد للمستخدم.</p>
<div class="grid md:grid-cols-2 gap-6">
<div>
<h4 class="font-semibold mb-2">تفاصيل الطلب:</h4>
<div class="bg-slate-50 p-4 rounded-lg border border-slate-200 space-y-3">
<p><strong>Method:</strong> <span class="bg-green-100 text-green-800 font-mono text-sm font-bold mr-2 px-2.5 py-0.5 rounded">POST</span></p>
<div>
<p><strong>URL:</strong></p>
<div class="flex items-center">
<code class="text-sm break-all flex-grow" id="webhookUrl">https://walletintaleq.intaleq.xyz/v1/main/ride/mtn_new/mtn_webhook_handler.php</code>
<button onclick="copyToClipboard('webhookUrl')" class="text-blue-500 hover:text-blue-700 text-xs mr-2 flex-shrink-0">نسخ</button>
</div>
</div>
<p><strong>Header:</strong> <code class="text-sm">X-AUTH-TOKEN: [المفتاح السري]</code></p>
<p><strong>Body (JSON):</strong> انظر هيكل البيانات أدناه.</p>
</div>
</div>
<div>
<h4 class="font-semibold mb-2">جرّب الآن:</h4>
<div class="space-y-4">
<div>
<label for="webhook-invoice" class="block text-sm font-medium text-slate-700">رقم الفاتورة:</label>
<input type="text" id="webhook-invoice" class="mt-1 block w-full px-3 py-2 bg-white border border-slate-300 rounded-md text-sm shadow-sm" value="MTN-FAKE-12345">
</div>
<button onclick="testWebhook()" class="w-full bg-blue-600 text-white font-bold py-2 px-4 rounded-lg hover:bg-blue-700 transition duration-300">إرسال طلب تأكيد</button>
</div>
</div>
</div>
<div class="mt-6">
<h4 class="font-semibold mb-2">هيكل JSON Body والاستجابات المتوقعة:</h4>
<pre id="webhook-response" class="code-block min-h-[200px]"><code>// The response from the server will appear here...
// Example Request Body:
{
"invoice_number": "MTN-FAKE-12345",
"transaction_id": "MTN_TRX_ABC123456",
"amount_paid": 50000.00,
"status": "success",
"payment_timestamp": "2023-03-15T12:00:00Z"
}</code></pre>
</div>
</div>
</section>
</div>
<footer class="text-center mt-8 text-sm text-slate-500">
<p>&copy; 2025 Intaleq. All rights reserved.</p>
</footer>
</div>
<script>
function showEndpoint(endpoint) {
document.querySelectorAll('.endpoint-section').forEach(section => {
section.classList.remove('active');
});
document.getElementById(endpoint + '-section').classList.add('active');
document.querySelectorAll('.api-tab').forEach(tab => {
tab.classList.remove('tab-active');
tab.classList.add('tab-inactive');
});
event.currentTarget.classList.add('tab-active');
event.currentTarget.classList.remove('tab-inactive');
}
function copyToClipboard(elementId) {
const text = document.getElementById(elementId).innerText;
navigator.clipboard.writeText(text).then(() => {
alert('تم نسخ: ' + text);
}, (err) => {
alert('فشل النسخ: ', err);
});
}
function testQuery() {
const phone = document.getElementById('query-phone').value;
const responseEl = document.getElementById('query-response');
if (!phone) {
responseEl.innerHTML = `<code>{\n "status": "error",\n "message": "الرجاء إدخال رقم هاتف."\n}</code>`;
return;
}
responseEl.innerHTML = `<code>// Sending request...</code>`;
// Simulate server responses based on phone number
setTimeout(() => {
let response = {};
if (phone.includes('963911111111')) { // Success case
response = {
status: "success",
invoice_number: "MTN-" + Date.now(),
amount: 50000.00,
user_name: "محمد الأحمد",
user_type: "driver"
};
} else if (phone.includes('963922222222')) { // No pending invoice
response = {
status: "not_found",
message: "No pending invoice found for this user."
};
} else { // Generic error / user not found
response = {
status: "error",
message: "User not found or invalid phone number."
};
}
responseEl.innerHTML = `<code>${JSON.stringify(response, null, 4)}</code>`;
}, 1000);
}
function testWebhook() {
const invoice = document.getElementById('webhook-invoice').value;
const responseEl = document.getElementById('webhook-response');
if (!invoice) {
responseEl.innerHTML = `<code>{\n "status": "error",\n "message": "الرجاء إدخال رقم فاتورة."\n}</code>`;
return;
}
responseEl.innerHTML = `<code>// Sending request...</code>`;
setTimeout(() => {
let response = {};
if(invoice.includes('12345')){ // Success
response = {
status: "success",
message: "Transaction finalized."
};
} else if (invoice.includes('67890')) { // Already processed
response = {
status: "error",
message: "Invoice not found or already processed."
};
} else { // Generic invalid
response = {
status: "error",
message: "Invalid or missing parameters."
};
}
responseEl.innerHTML = `<code>${JSON.stringify(response, null, 4)}</code>`;
}, 1000);
}
</script>
</body>
</html>