(int)$invoice, 'Phone' => $phone, 'Guid' => $guid, 'OperationNumber' => (int)$operationNumber, 'Code' => $codeB64, 'Accept-Language' => $lang ]; $bodyJson = json_encode($body, JSON_UNESCAPED_UNICODE); mlog("MTN Confirm: Prepared body JSON: " . $bodyJson); // توقيع الجسم $sig = null; $signResult = openssl_sign($bodyJson, $sig, $privateKey, OPENSSL_ALGO_SHA256); if (!$signResult || !$sig) { mlog("MTN Confirm: Failed to generate signature"); printFailure("Signature error."); exit; } $xSignature = base64_encode($sig); mlog("MTN Confirm: Generated signature"); // إرسال الطلب إلى MTN $ch = curl_init("{$baseUrl}/pos_web/payment_phone/confirm"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => $bodyJson, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "Request-Name: pos_web/payment_phone/confirm", "Subject: {$terminalId}", "X-Signature: {$xSignature}" ], CURLOPT_TIMEOUT => 25, ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curlError = curl_error($ch); curl_close($ch); mlog("MTN Confirm: HTTP {$httpCode} - Response: " . ($response ?? '')); if ($curlError) { mlog("MTN Confirm: cURL error - {$curlError}"); } // فك JSON لرد MTN (حتى لو خطأ) لعرض سبب واضح $mtn = json_decode($response ?: '{}', true); if (!is_array($mtn)) { $mtn = []; } // 🧠 سياسة القرار: // - إذا HTTP≠200 → فشل شبكة/بوابة // - إذا HTTP=200 لكن Errno≠0 → خطأ من MTN (مثل Incorrect sms code) // - فقط إذا HTTP=200 && Errno=0 → نجاح، نحدّث DB ونضيف للمحافظ if ($httpCode !== 200) { // لا تحدّث DB printFailure([ 'message' => 'MTN confirm HTTP failure', 'http' => $httpCode, 'mtn' => $mtn ]); exit; } // HTTP 200 — افحص Errno $errno = isset($mtn['Errno']) ? (int)$mtn['Errno'] : null; if ($errno !== 0) { // لا تحدّث DB في هذه الحالة $errText = isset($mtn['Error']) ? $mtn['Error'] : 'Unknown MTN error'; // اطبع لوج مشابه للمثال المطلوب // مثال: {"Errno":662,"Error":"Incorrect sms code","Abuse":2,"Transaction":""} mlog("MTN Confirm: Business failure from MTN - Errno={$errno}, Error=" . json_encode($mtn, JSON_UNESCAPED_UNICODE)); printFailure([ 'message' => $errText, 'errno' => $errno, 'mtn' => $mtn ]); exit; } // ✅ نجاح كامل من MTN — تحديث DB ثم المحافظ try { global $con; $stmt = $con->prepare( "UPDATE `paymentsLogSyria` SET status = 1, updated_at = NOW() WHERE order_ref = :inv" ); $stmt->execute([':inv' => $invoice]); mlog("MTN Confirm: Payment updated successfully in DB for invoice={$invoice}"); $stmt = $con->prepare("SELECT * FROM paymentsLogSyria WHERE order_ref = :order_ref LIMIT 1"); $stmt->execute([':order_ref' => $invoice]); $payment = $stmt->fetch(PDO::FETCH_ASSOC); if (!$payment) { mlog("MTN Confirm: Payment row not found after update"); printFailure("Payment row not found"); exit; } $userId = $payment['user_id']; $amount = $payment['amount']; $paymentMethod = $payment['payment_method'] ?? 'mtn'; $finalAmount = calculateBonus($amount); $token = generatePaymentToken($userId, $finalAmount); $walletResult = addToPassengerWallet($userId, $finalAmount, $token); $siroToken = generatePaymentToken($userId, $amount); $siroWalletResult = addToSiroWallet($userId, $amount, $paymentMethod, $siroToken); // رجّع رد موحّد + ضمّن رد MTN printSuccess([ 'message' => 'MTN Confirm', 'data' => [ 'invoice' => $invoice, 'finalAmount' => $finalAmount, 'wallet' => $walletResult, 'siroWallet' => $siroWalletResult, 'mtn' => $mtn ] ]); exit; } catch (PDOException $e) { mlog("MTN Confirm: DB update error - " . $e->getMessage()); printFailure("DB error"); exit; } } catch (Throwable $e) { mlog("MTN Confirm: Exception - " . $e->getMessage()); printFailure("Server error"); exit; } /** * نفس دوال المساعدة، لكن باستعمال 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) { $url = rtrim(BASE_URL, '/') . "/passengerWallet/addPaymentTokenPassenger.php"; $postData = ['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($postData)); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode != 200 || !$response) return null; $data = json_decode($response, true); return $data['message'] ?? null; } function addToPassengerWallet($passengerId, $amount, $token) { $url = rtrim(BASE_URL, '/') . "/passengerWallet/add.php"; $postData = ['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($postData)); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode != 200 || !$response) return null; return json_decode($response, true); } function addToSiroWallet($passengerId, $amount, $paymentMethod, $token) { $url = rtrim(BASE_URL, '/') . "/siroWallet/add.php"; $postData = [ 'amount' => $amount, 'paymentMethod' => $paymentMethod, '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($postData)); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode != 200 || !$response) return null; return json_decode($response, true); }