Update: 2026-06-16 22:44:11
This commit is contained in:
255
walletintaleq.intaleq.xyz/v2/main/sms_webhook/process_passenger_sms_payment.php
Executable file
255
walletintaleq.intaleq.xyz/v2/main/sms_webhook/process_passenger_sms_payment.php
Executable file
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
/**
|
||||
* process_passenger_sms_payment.php
|
||||
* - يستخدم BASE_URL الموجودة مسبقًا (لا يُعرّف بديل).
|
||||
* - يستخدم Gemini 2.5 Flash Lite.
|
||||
* - لا يحدّث raw_sms_log الآن (لا mark processed/failed).
|
||||
* - الدفع للراكب فقط: invoices_sms_passenger → bonus → generate token → add to wallets.
|
||||
*/
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
include_once __DIR__ . '/../../jwtconnect.php';
|
||||
|
||||
if (!defined('BASE_URL')) {
|
||||
$APP_BASE_URL = rtrim(getenv('APP_BASE_URL') ?: '', '/');
|
||||
if ($APP_BASE_URL === '') {
|
||||
$scheme = isset($_SERVER['REQUEST_SCHEME']) ? $_SERVER['REQUEST_SCHEME'] : 'https';
|
||||
$host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
|
||||
define('BASE_URL', $scheme . '://' . $host);
|
||||
} else {
|
||||
define('BASE_URL', $APP_BASE_URL);
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== Gemini: Flash Lite ===== */
|
||||
$geminiModel = 'gemini-2.5-flash-lite';
|
||||
$geminiApiKey = getenv('GEMINI_API_KEY');
|
||||
if (!$geminiApiKey) {
|
||||
printFailure("Missing GEMINI_API_KEY");
|
||||
exit;
|
||||
}
|
||||
$geminiApiUrl = "https://generativelanguage.googleapis.com/v1beta/models/{$geminiModel}:generateContent?key={$geminiApiKey}";
|
||||
|
||||
/* ===== اجلب رسالة واحدة pending (مع sender) ===== */
|
||||
try {
|
||||
$stmt = $con->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);
|
||||
}
|
||||
Reference in New Issue
Block a user