feat: استيراد كود سيرو إلى تريبز (سيرو @ecfe7568) — بلا تعديل
قرار المالك 2026-07-27: باك إند سيرو PHP هو المعتمد، وتطبيقاته المجرّبة ميدانياً تحل محل إعادة البناء المؤرشفة. سيرو نفسه لم يُمسّ. الخريطة: backend · payment_server · loction_server · ride_server · passenger_server · docker · dashboard · stress_test → الجذر siro_rider → apps/rider siro_driver → apps/driver siro_admin → dashboards/admin siro_service → dashboards/service android_bot → apps/android_bot socialBot → apps/socialBot نُسخ المتعقَّب في git سيرو فقط عبر `git archive` (3,198 ملفاً / ~169 م.ب) لا `cp -r` — فاستُثنيت مخلفات البناء تلقائياً. بلا أي تعديل محتوى عمداً: كل ما يلي يصير فرقاً مقروءاً مقابل المصدر. لم يُستورد وسببه: siromove.com (الموقع التسويقي يبقى marketing/ في تريبز، سيرو فيه 8 ملفات) · docs و planning (تريبز له docs/ الخاص) · deploy.sh (ليس نشراً على سيرفر بل `git add . && git push origin --all` — فخّ في مستودع آخر) · transit_dashboard (بانتظار قرار مصير backend-transit و dashboards/transit-web). ⚠️ لا يبني بعد — ثلاثة نواقص متوقعة ومقصودة: 1. `.env` و `lib/env/env.g.dart` غير متعقَّبين في سيرو (أسرار لكل مستأجر): كل تطبيق فلاتر يحتاج .env خاصاً ثم توليد env.g.dart بـ build_runner. 2. إعدادات Firebase (9 ملفات google-services.json و GoogleService-Info.plist) يستبعدها .gitignore تريبز — ولكل مستأجر مشروع Firebase خاص أصلاً. 3. apps/driver في سيرو يشير إلى `../../Intaleq/packages/get` خارج المستودع → يجب ضمّ الحزم داخله أسوة بـ apps/rider. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9909d9b4c1
commit
4d8414c96b
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
// --- click_webhook_handler.php ---
|
||||
// هذا هو الـ Webhook الرئيسي الذي يستقبل إشعار تأكيد الدفع من Click
|
||||
|
||||
include "../../jwtconnect.php";
|
||||
include "./finalize_payment.php"; // تضمين ملف إتمام العملية
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// **مهم جداً: التحقق من مصدر الطلب**
|
||||
// يجب التحقق من أن هذا الطلب قادم فعلاً من Click وليس من أي طرف آخر
|
||||
// المثال التالي يستخدم مفتاح سري مشترك (Shared Secret)
|
||||
$expectedToken = trim(file_get_contents('/home/intaleq-wallet/.clickKey')); // يجب استبداله بتوكن حقيقي
|
||||
$receivedToken = $_SERVER['HTTP_X_AUTH_TOKEN'] ?? '';
|
||||
|
||||
if ($receivedToken !== $expectedToken) {
|
||||
http_response_code(401); // Unauthorized
|
||||
echo json_encode(["status" => "error", "message" => "Authentication failed."]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// قراءة البيانات القادمة من Click (عادة تكون بصيغة JSON في الـ body)
|
||||
$json_data = file_get_contents('php://input');
|
||||
$data = json_decode($json_data, true);
|
||||
|
||||
$invoiceNumber = $data['invoice_number'] ?? null;
|
||||
$transactionId = $data['transaction_id'] ?? null;
|
||||
$paymentStatus = $data['status'] ?? null;
|
||||
|
||||
if (empty($invoiceNumber) || empty($transactionId) || $paymentStatus !== 'success') {
|
||||
http_response_code(400); // Bad Request
|
||||
echo json_encode(["status" => "error", "message" => "Missing or invalid payment data."]);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$con->beginTransaction();
|
||||
|
||||
// 1. البحث عن الفاتورة وتحديث حالتها
|
||||
$stmt = $con->prepare(
|
||||
"UPDATE `click_invoices`
|
||||
SET `status` = 'completed', `click_transaction_id` = :transaction_id
|
||||
WHERE `invoice_number` = :invoice_number AND `status` = 'pending'"
|
||||
);
|
||||
$stmt->execute([
|
||||
':transaction_id' => $transactionId,
|
||||
':invoice_number' => $invoiceNumber
|
||||
]);
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// تم تحديث الفاتورة بنجاح، الآن نقوم بإتمام العملية
|
||||
$invoiceId = $con->lastInsertId(); // ملاحظة: هذا قد لا يعمل دائماً مع UPDATE، الأفضل جلب الـ ID
|
||||
|
||||
// جلب ID الفاتورة بعد التأكد من وجودها
|
||||
$idStmt = $con->prepare("SELECT id FROM `click_invoices` WHERE `invoice_number` = :invoice_number");
|
||||
$idStmt->execute([':invoice_number' => $invoiceNumber]);
|
||||
$invoiceRecord = $idStmt->fetch();
|
||||
$invoiceId = $invoiceRecord['id'];
|
||||
|
||||
$finalizationResult = finalizeClickPayment($con, $invoiceId);
|
||||
|
||||
if ($finalizationResult['success']) {
|
||||
$con->commit();
|
||||
echo json_encode(["status" => "success", "message" => "Transaction finalized."]);
|
||||
} else {
|
||||
$con->rollBack();
|
||||
// يجب هنا التعامل مع الحالة التي فشل فيها الإيداع رغم نجاح الدفع
|
||||
error_log("CRITICAL: Payment received for invoice {$invoiceNumber} but finalization failed.");
|
||||
http_response_code(500);
|
||||
echo json_encode(["status" => "error", "message" => "Finalization failed."]);
|
||||
}
|
||||
} else {
|
||||
// لم يتم العثور على فاتورة معلقة بهذا الرقم (ربما تمت معالجتها سابقاً)
|
||||
$con->rollBack();
|
||||
http_response_code(404);
|
||||
echo json_encode(["status" => "error", "message" => "Invoice not found or already processed."]);
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
$con->rollBack();
|
||||
error_log("Error in click_webhook_handler.php: " . $e->getMessage());
|
||||
http_response_code(500);
|
||||
echo json_encode(["status" => "error", "message" => "An internal server error occurred."]);
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user