Deploy: 2026-06-18 15:04:52
This commit is contained in:
@@ -742,88 +742,114 @@ class WhatsAppController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* Call external API to verify payment slip
|
||||
* Verify payment — sends data to payment server for AI verification or status query.
|
||||
*
|
||||
* Two modes:
|
||||
* 1. AI Verification (receiptImage given): sends phone + invoice_number + receipt_image
|
||||
* to payment server, which runs GeminiAi::verifyPayment().
|
||||
* 2. Status Query (only jsonStr): parses {transaction_id, amount, method} from Gemini
|
||||
* chatbot auto-detection, sends as status query to payment server.
|
||||
*/
|
||||
public static function verifyPaymentSlipStatic(int $companyId, string $phone, string $jsonStr): ?string
|
||||
public static function verifyPaymentSlipStatic(
|
||||
int $companyId,
|
||||
string $phone,
|
||||
string $jsonStr,
|
||||
string $userType = 'driver',
|
||||
string $paymentMethod = '',
|
||||
string $invoiceNumber = '',
|
||||
string $receiptImage = '',
|
||||
string $imageMimeType = 'image/jpeg'
|
||||
): ?string
|
||||
{
|
||||
try {
|
||||
$data = json_decode($jsonStr, true);
|
||||
if (!$data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$transactionId = $data['transaction_id'] ?? '';
|
||||
$amount = $data['amount'] ?? '';
|
||||
$method = $data['method'] ?? '';
|
||||
|
||||
if (empty($transactionId) || empty($amount)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Find configured endpoint for verify_payment
|
||||
$endpoint = \App\Models\CompanyEndpoint::findByAction($companyId, 'verify_payment');
|
||||
$apiUrl = $endpoint ? $endpoint['endpoint_url'] : null;
|
||||
|
||||
$apiUrl = getenv('PAYMENT_API_URL') ?: getenv('ENTALEQ_PAYMENT_API_URL');
|
||||
if (empty($apiUrl)) {
|
||||
// Fallback to local default mock
|
||||
$apiUrl = getenv('ENTALEQ_PAYMENT_API_URL');
|
||||
if (empty($apiUrl)) {
|
||||
$appUrl = rtrim(getenv('APP_URL') ?: 'https://nabeh.intaleqapp.com', '/');
|
||||
$apiUrl = $appUrl . '/api/external/verify-payment';
|
||||
}
|
||||
$appUrl = rtrim(getenv('APP_URL') ?: 'https://nabeh.intaleqapp.com', '/');
|
||||
$apiUrl = $appUrl . '/api/external/verify-payment';
|
||||
}
|
||||
|
||||
$payload = json_encode([
|
||||
'phone' => $phone,
|
||||
'transaction_id' => $transactionId,
|
||||
'amount' => $amount,
|
||||
'method' => $method
|
||||
]);
|
||||
if (strpos($apiUrl, '/ride/nabeh/verify_payment.php') === false
|
||||
&& strpos($apiUrl, '/api/external/verify-payment') === false) {
|
||||
$apiUrl = rtrim($apiUrl, '/') . '/ride/nabeh/verify_payment.php';
|
||||
}
|
||||
|
||||
$headers = ['Content-Type: application/json'];
|
||||
if ($endpoint) {
|
||||
if (!empty($endpoint['api_key'])) {
|
||||
$headers[] = 'X-API-Key: ' . $endpoint['api_key'];
|
||||
$headers[] = 'Authorization: Bearer ' . $endpoint['api_key'];
|
||||
}
|
||||
if (!empty($endpoint['headers'])) {
|
||||
$customHeaders = json_decode($endpoint['headers'], true);
|
||||
if (is_array($customHeaders)) {
|
||||
foreach ($customHeaders as $key => $value) {
|
||||
$headers[] = "$key: $value";
|
||||
}
|
||||
}
|
||||
}
|
||||
$apiKey = getenv('NABEH_API_KEY') ?: '';
|
||||
$headers = [
|
||||
'Content-Type: application/json',
|
||||
'X-API-Key: ' . $apiKey,
|
||||
];
|
||||
|
||||
// ── Mode 1: AI Verification (receipt image → auto-find invoice by phone) ──
|
||||
if (!empty($receiptImage)) {
|
||||
$payload = json_encode([
|
||||
'phone' => $phone,
|
||||
'payment_method' => $paymentMethod,
|
||||
'receipt_image' => $receiptImage,
|
||||
'image_mime_type' => $imageMimeType,
|
||||
]);
|
||||
} else {
|
||||
$headers[] = 'X-API-Key: ' . (getenv('ENTALEQ_API_KEY') ?: 'mock-key');
|
||||
// ── Mode 2: Status query from chatbot auto-detection ──────────────
|
||||
$data = json_decode($jsonStr, true);
|
||||
if (!$data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$transactionId = $data['transaction_id'] ?? '';
|
||||
$amount = $data['amount'] ?? '';
|
||||
$method = $data['method'] ?? $paymentMethod;
|
||||
|
||||
if (empty($transactionId) && empty($amount) && empty($invoiceNumber)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$payload = json_encode([
|
||||
'phone' => $phone,
|
||||
'payment_method' => $method,
|
||||
'transaction_id' => $transactionId,
|
||||
'amount' => is_numeric($amount) ? (float) $amount : 0,
|
||||
'invoice_number' => $invoiceNumber,
|
||||
]);
|
||||
}
|
||||
|
||||
$ch = curl_init($apiUrl);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $payload,
|
||||
CURLOPT_HTTPHEADER => $headers,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
]);
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($httpCode !== 200) {
|
||||
return "⏳ تم استلام وصل الدفع ويجري التحقق منه حالياً من قبل المحاسب يدوياً. سنقوم بشحن رصيدك وتنبيهك فور انتهاء العملية.";
|
||||
error_log("[PaymentVerify] HTTP $httpCode from $apiUrl: $response");
|
||||
return "⏳ تم استلام معلومات الدفع ويجري التحقق منها يدوياً. سنقوم بالرد فور الانتهاء.";
|
||||
}
|
||||
|
||||
$resData = json_decode($response, true);
|
||||
if (isset($resData['status']) && $resData['status'] === 'success') {
|
||||
$amtStr = $resData['data']['amount'] ?? $amount;
|
||||
return "✅ تم التحقق من وصل الدفع تلقائياً بنجاح!\n• رقم العملية: " . $transactionId . "\n• القيمة: " . $amtStr . " دينار\n• تم تحديث رصيد حسابك بنجاح.";
|
||||
} else {
|
||||
$reason = $resData['message'] ?? 'العملية مسجلة مسبقاً أو غير صالحة';
|
||||
return "⚠️ لم نتمكن من تأكيد العملية تلقائياً:\n• السبب: " . $reason . "\n\nيجري الآن تحويل المعاملة للمراجعة اليدوية من قبل الإدارة وسنقوم بالرد عليك قريباً.";
|
||||
if (!$resData) {
|
||||
return "⏳ تم استلام معلومات الدفع. يجري التحقق منها يدوياً.";
|
||||
}
|
||||
|
||||
if (($resData['status'] ?? '') === 'success') {
|
||||
$verified = $resData['verified'] ?? false;
|
||||
if ($verified) {
|
||||
return "✅ تم التحقق من عملية الدفع تلقائياً بنجاح!\n"
|
||||
. "• تم تحديث رصيد حسابك.";
|
||||
}
|
||||
|
||||
$reason = $resData['message']
|
||||
?? $resData['ai_reason']
|
||||
?? 'لم يتم التأكيد بعد';
|
||||
return "⚠️ " . $reason . "\n\nسيتم مراجعة العملية من قبل الإدارة والرد عليك قريباً.";
|
||||
}
|
||||
|
||||
return "⏳ تم استلام معلومات الدفع. يجري التحقق منها يدوياً.";
|
||||
} catch (\Exception $e) {
|
||||
error_log("[Payment Verification Exception] " . $e->getMessage());
|
||||
return "⏳ تم استلام وصل الدفع بنجاح. يجري الآن مراجعته وتدقيقه يدوياً من قبل الإدارة الفنية لتأكيد شحن رصيدك.";
|
||||
error_log("[PaymentVerify Exception] " . $e->getMessage());
|
||||
return "⏳ تم استلام معلومات الدفع. يجري التحقق منها يدوياً.";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user