123 lines
4.7 KiB
PHP
123 lines
4.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use Core\Database;
|
|
use PDO;
|
|
|
|
class SuperQiParserService
|
|
{
|
|
/**
|
|
* Ingests and processes a notification or parsed receipt from the Android listener bridge.
|
|
*/
|
|
public static function processIngestedNotification(array $data): array
|
|
{
|
|
$refNumber = trim((string)($data['reference_number'] ?? ''));
|
|
$amount = (float)($data['amount'] ?? 0);
|
|
$sender = trim((string)($data['sender'] ?? ''));
|
|
$recipient = trim((string)($data['recipient'] ?? ''));
|
|
$rawText = (string)($data['raw_text'] ?? '');
|
|
|
|
if (empty($refNumber) || $amount <= 0) {
|
|
return [
|
|
'success' => false,
|
|
'message' => 'Invalid transaction reference or amount.',
|
|
];
|
|
}
|
|
|
|
$pdo = Database::getConnection();
|
|
|
|
// 1. Check if transaction has already been recorded and verified
|
|
$stmt = $pdo->prepare('SELECT id, status FROM transactions WHERE reference_number = :ref LIMIT 1');
|
|
$stmt->execute([':ref' => $refNumber]);
|
|
$existing = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if ($existing && $existing['status'] === 'VERIFIED_AUTO') {
|
|
return [
|
|
'success' => true,
|
|
'message' => 'Transaction already processed and verified previously.',
|
|
'transaction_id' => $existing['id'],
|
|
];
|
|
}
|
|
|
|
// 2. Search for a pending subscription matching this reference or pending payment
|
|
// First, check if any user submitted this reference number
|
|
$stmt = $pdo->prepare('
|
|
SELECT t.id AS trans_id, t.subscription_id, s.user_id, s.plan_name, u.phone, u.full_name
|
|
FROM transactions t
|
|
JOIN subscriptions s ON s.id = t.subscription_id
|
|
JOIN users u ON u.id = s.user_id
|
|
WHERE t.reference_number = :ref AND t.status = "SUBMITTED"
|
|
LIMIT 1
|
|
');
|
|
$stmt->execute([':ref' => $refNumber]);
|
|
$matched = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if ($matched) {
|
|
$pdo->beginTransaction();
|
|
try {
|
|
// Update transaction
|
|
$updTrans = $pdo->prepare('
|
|
UPDATE transactions
|
|
SET status = "VERIFIED_AUTO", amount = :amount, verified_at = NOW(),
|
|
raw_webhook_payload = :raw
|
|
WHERE id = :id
|
|
');
|
|
$updTrans->execute([
|
|
':amount' => $amount,
|
|
':raw' => json_encode($data, JSON_UNESCAPED_UNICODE),
|
|
':id' => $matched['trans_id'],
|
|
]);
|
|
|
|
// Activate subscription
|
|
$updSub = $pdo->prepare('
|
|
UPDATE subscriptions
|
|
SET status = "ACTIVE", starts_at = CURDATE(), expires_at = DATE_ADD(CURDATE(), INTERVAL 2 YEAR)
|
|
WHERE id = :sub_id
|
|
');
|
|
$updSub->execute([':sub_id' => $matched['subscription_id']]);
|
|
|
|
// Ensure user status is active
|
|
$updUser = $pdo->prepare('UPDATE users SET status = "ACTIVE" WHERE id = :user_id');
|
|
$updUser->execute([':user_id' => $matched['user_id']]);
|
|
|
|
$pdo->commit();
|
|
|
|
return [
|
|
'success' => true,
|
|
'matched' => true,
|
|
'message' => 'Subscription activated automatically for ' . $matched['full_name'],
|
|
'user_id' => $matched['user_id'],
|
|
'phone' => $matched['phone'],
|
|
];
|
|
} catch (\Throwable $e) {
|
|
$pdo->rollBack();
|
|
return ['success' => false, 'error' => $e->getMessage()];
|
|
}
|
|
}
|
|
|
|
// If no user has claimed it yet, record it in transactions as unassigned credit
|
|
$insStmt = $pdo->prepare('
|
|
INSERT INTO transactions (subscription_id, user_id, method, reference_number, sender_account_or_phone, recipient_account, amount, currency, status, raw_webhook_payload, verified_at)
|
|
VALUES (0, 0, "SUPER_QI", :ref, :sender, :recipient, :amount, "IQD", "VERIFIED_AUTO", :raw, NOW())
|
|
ON DUPLICATE KEY UPDATE amount = VALUES(amount), raw_webhook_payload = VALUES(raw_webhook_payload)
|
|
');
|
|
$insStmt->execute([
|
|
':ref' => $refNumber,
|
|
':sender' => $sender,
|
|
':recipient' => $recipient,
|
|
':amount' => $amount,
|
|
':raw' => json_encode($data, JSON_UNESCAPED_UNICODE),
|
|
]);
|
|
|
|
return [
|
|
'success' => true,
|
|
'matched' => false,
|
|
'message' => 'Transaction recorded. Awaiting user claim in app.',
|
|
'reference_number' => $refNumber,
|
|
];
|
|
}
|
|
}
|