prepare(" SELECT id, message_body, sender FROM raw_sms_log WHERE status = 'pending' ORDER BY created_at ASC LIMIT 1 "); $stmt->execute(); $sms = $stmt->fetch(PDO::FETCH_ASSOC); if (!$sms) { echo json_encode(["status" => "idle", "message" => "No pending messages"]); exit; } } catch (PDOException $e) { printFailure("DB fetch error: " . $e->getMessage()); exit; } $smsId = (int)$sms['id']; $body = (string)$sms['message_body']; $sender = (string)$sms['sender']; // نستخدمه لاشتقاق طريقة الدفع /* ===== Prompt لِـ Gemini ===== */ $prompt = "Analyze the following financial SMS and return ONLY a valid JSON object: { \"transaction_type\": \"income\" | \"payout\", \"amount\": number, \"currency\": \"SYP\" | string (3 letters), \"phone_number\": string | null } SMS Text: \"$body\""; $payload = ['contents' => [['parts' => [['text' => $prompt]]]]]; $ch = curl_init($geminiApiUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE)); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curlErr = curl_error($ch); curl_close($ch); if ($response === false) { printFailure("Gemini curl error: " . $curlErr); exit; } $gem = json_decode($response, true); $gemText = $gem['candidates'][0]['content']['parts'][0]['text'] ?? null; if ($httpCode !== 200 || !$gemText) { printFailure("Gemini HTTP $httpCode / empty response"); exit; } /* Gemini أحيانًا يحيط الـ JSON بعلامات Markdown */ $clean = trim(str_replace(['```json','```JSON','```'], '', $gemText)); $data = json_decode($clean, true); if (!is_array($data) || empty($data['transaction_type'])) { printFailure("Failed to parse Gemini JSON"); exit; } /* ===== القيم المستخرجة ===== */ $trxType = strtolower((string)$data['transaction_type']); $amount = isset($data['amount']) ? floatval($data['amount']) : 0.0; $currency = isset($data['currency']) ? strtoupper((string)$data['currency']) : ''; $phone = isset($data['phone_number']) ? (string)$data['phone_number'] : ''; /* ===== طريقة الدفع من الـ sender (الآن ثابتة shamcash كما طلبت) ===== */ $paymentMethod = 'shamcash'; // أو اشتقاق ذكي: strpos(strtolower($sender),'sham') !== false ? 'shamcash' : 'unknown'; /* ===== فقط INCOME: نفّذ تدفّق الراكب ===== */ if ($trxType === 'income' && $amount > 0 && $phone !== '') { try { // ابحث عن فاتورة راكب حديثة متطابقة خلال 60 دقيقة $q = $con->prepare(" SELECT id FROM invoices_sms_passenger WHERE status='pending' AND user_phone = :p AND amount = :a AND created_at >= (NOW() - INTERVAL 60 MINUTE) ORDER BY created_at DESC LIMIT 1 "); $q->execute([':p' => $phone, ':a' => $amount]); $inv = $q->fetch(PDO::FETCH_ASSOC); if (!$inv) { printFailure( "No matching passenger invoice"); exit; } $invoiceId = $inv['id']; // حدّث حالة الفاتورة $con->prepare("UPDATE invoices_sms_passenger SET status='completed', updated_at=NOW() WHERE id=:id") ->execute([':id' => $invoiceId]); // احضر بيانات الفاتورة لمعرفة passengerID والمبلغ المؤكد $st = $con->prepare("SELECT passengerID, amount FROM invoices_sms_passenger WHERE id=:id LIMIT 1"); $st->execute([':id' => $invoiceId]); $row = $st->fetch(PDO::FETCH_ASSOC); if (!$row) { printFailure("Invoice row not found after update"); exit; } $passengerId = $row['passengerID']; $amt = floatval($row['amount']); // 1) Bonus $finalAmount = calculateBonus($amt); // 2) Generate payment token (للراكب) $token = generatePaymentToken($passengerId, $finalAmount); // 3) Add to Passenger Wallet $walletResult = addToPassengerWallet($passengerId, $finalAmount, $token); // 4) Add to Siro Wallet (محاسبي) بطريقة الدفع المستخلصة من sender $token2 = generatePaymentToken($passengerId, $amt); $siroWalletResult = addToSiroWallet($passengerId, $amt, $paymentMethod, $token2); printSuccess([ "message" => "Passenger income processed", "invoice_id" => $invoiceId, "passenger_id" => $passengerId, "amount" => $amt, "final_amount" => $finalAmount, "payment_method" => $paymentMethod, "wallet" => $walletResult, "siroWallet" => $siroWalletResult, "sender" => $sender ]); exit; } catch (PDOException $e) { printFailure("DB income error: " . $e->getMessage()); exit; } } /* غير مدعوم الآن (payout أو مدخلات ناقصة) */ printFailure([ "status" => "ignored", "message" => "Unsupported or incomplete transaction", "type" => $trxType, "sender" => $sender ]); exit; /* ===== Helpers — تعتمد على BASE_URL الموجودة عندك ===== */ function calculateBonus($amount) { if ($amount == 20000) return 20500; if ($amount == 40000) return 42500; if ($amount == 100000) return 104000; return $amount; } function generatePaymentToken($passengerId, $amount) { if (!defined('BASE_URL')) return null; // نعتمد وجودها لديك $url = rtrim(BASE_URL, '/') . "/passengerWallet/addPaymentTokenPassenger.php"; $post = ['passengerId' => $passengerId, 'amount' => $amount]; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post)); $resp = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($code != 200 || !$resp) return null; $j = json_decode($resp, true); return $j['message'] ?? null; } function addToPassengerWallet($passengerId, $amount, $token) { if (!defined('BASE_URL')) return null; $url = rtrim(BASE_URL, '/') . "/passengerWallet/add.php"; $post = ['passenger_id' => $passengerId, 'balance' => $amount, 'token' => $token]; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post)); $resp = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($code != 200 || !$resp) return null; return json_decode($resp, true); } function addToSiroWallet($passengerId, $amount, $paymentMethod, $token) { if (!defined('BASE_URL')) return null; $url = rtrim(BASE_URL, '/') . "/siroWallet/add.php"; $post = [ 'amount' => $amount, 'paymentMethod' => $paymentMethod, // من sender 'passengerId' => $passengerId, 'token' => $token, 'driverId' => 'passenger' ]; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post)); $resp = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($code != 200 || !$resp) return null; return json_decode($resp, true); }