202 lines
8.1 KiB
PHP
202 lines
8.1 KiB
PHP
<?php
|
|
// ============================================================
|
|
// api/payments/initiate_prime.php
|
|
// PURPOSE : شراء اشتراك Siro Prime عبر خصم رصيد المحفظة الداخلية
|
|
// AUTH : JWT (passenger)
|
|
// FLOW :
|
|
// 1. جلب هوية الراكب من JWT
|
|
// 2. تحديد السعر حسب الدولة
|
|
// 3. التحقق من رصيد الراكب في سيرفر المحفظة (S2S)
|
|
// 4. إذا الرصيد كافٍ → الخصم + تفعيل Prime
|
|
// 5. إذا الرصيد غير كافٍ → رسالة لإرشاد المستخدم للشحن
|
|
// ============================================================
|
|
|
|
require_once __DIR__ . '/../../connect.php';
|
|
|
|
// ── 1. هوية الراكب من JWT ─────────────────────────────────────
|
|
$passengerId = $user_id ?? null;
|
|
if (!$passengerId || $role !== 'passenger') {
|
|
jsonError("Unauthorized");
|
|
exit;
|
|
}
|
|
|
|
// ── 2. الدولة والسعر ──────────────────────────────────────────
|
|
$country = filterRequest("country") ?: 'Jordan';
|
|
|
|
$pricingMap = [
|
|
'Jordan' => ['amount' => 3.00, 'currency' => 'JOD'], // ~4 USD/month
|
|
'Egypt' => ['amount' => 200.00,'currency' => 'EGP'], // ~4 USD/month
|
|
'Syria' => ['amount' => 500.00,'currency' => 'SYP'], // ~4 USD/month (New Syrian Pound)
|
|
];
|
|
|
|
$amount = $pricingMap[$country]['amount'] ?? 3.00;
|
|
$currency = $pricingMap[$country]['currency'] ?? 'JOD';
|
|
|
|
// ── 3. سيرفر المحفظة حسب الدولة ──────────────────────────────
|
|
$walletServer = "https://walletintaleq.intaleq.xyz"; // Default
|
|
if (strtolower($country) === 'jordan') {
|
|
$walletServer = getenv('WALLET_SERVER_JORDAN') ?: "https://walletintaleq.intaleq.xyz";
|
|
} elseif (strtolower($country) === 'egypt') {
|
|
$walletServer = getenv('WALLET_SERVER_EGYPT') ?: "https://wallet-egypt.siromove.com";
|
|
} elseif (strtolower($country) === 'syria') {
|
|
$walletServer = getenv('WALLET_SERVER_SYRIA') ?: "https://wallet-syria.siromove.com";
|
|
}
|
|
|
|
$s2sKey = getenv('S2S_SHARED_KEY');
|
|
if (empty($s2sKey)) {
|
|
error_log("[Prime] CRITICAL: S2S_SHARED_KEY not set");
|
|
jsonError("Server configuration error");
|
|
exit;
|
|
}
|
|
|
|
// ── 4. التحقق من رصيد الراكب في سيرفر المحفظة ────────────────
|
|
$balanceUrl = "$walletServer/v2/main/ride/passengerWallet/getWalletByPassenger.php";
|
|
|
|
$chBalance = curl_init($balanceUrl);
|
|
curl_setopt_array($chBalance, [
|
|
CURLOPT_POST => true,
|
|
CURLOPT_POSTFIELDS => http_build_query(['passenger_id' => $passengerId]),
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 10,
|
|
CURLOPT_HTTPHEADER => [
|
|
'Content-Type: application/x-www-form-urlencoded',
|
|
'X-S2S-Api-Key: ' . $s2sKey
|
|
]
|
|
]);
|
|
|
|
$balanceRaw = curl_exec($chBalance);
|
|
$balanceCode = curl_getinfo($chBalance, CURLINFO_HTTP_CODE);
|
|
$balanceErr = curl_error($chBalance);
|
|
curl_close($chBalance);
|
|
|
|
if ($balanceErr || $balanceCode !== 200) {
|
|
error_log("[Prime] Wallet balance fetch failed: HTTP $balanceCode | err: $balanceErr");
|
|
jsonError("Unable to verify wallet balance. Please try again.");
|
|
exit;
|
|
}
|
|
|
|
$balanceData = json_decode($balanceRaw, true);
|
|
$walletBalance = (float)($balanceData['message'][0]['total'] ?? $balanceData['total'] ?? -1);
|
|
|
|
if ($walletBalance < 0) {
|
|
error_log("[Prime] Unexpected wallet response: $balanceRaw");
|
|
jsonError("Unable to read wallet balance.");
|
|
exit;
|
|
}
|
|
|
|
// ── 5. هل الرصيد كافٍ؟ ────────────────────────────────────────
|
|
if ($walletBalance < $amount) {
|
|
// رصيد غير كافٍ — أخبر التطبيق ليوجّه المستخدم للشحن
|
|
echo json_encode([
|
|
'status' => 'insufficient_balance',
|
|
'current_balance' => $walletBalance,
|
|
'required_amount' => $amount,
|
|
'currency' => $currency,
|
|
'message' => 'Your wallet balance is insufficient. Please top up your wallet to subscribe to Siro Prime.'
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
// ── 6. الرصيد كافٍ → بدء عملية الاشتراك ─────────────────────
|
|
try {
|
|
$con->beginTransaction();
|
|
|
|
// 6a. تسجيل الحركة في قاعدة بيانات سيرو (بادئها paid مباشرةً)
|
|
$transactionRef = "PRIME-" . time() . "-" . rand(1000, 9999);
|
|
$stmtTx = $con->prepare("
|
|
INSERT INTO prime_payment_transactions (transaction_ref, passenger_id, amount, currency, status)
|
|
VALUES (:ref, :pid, :amt, :curr, 'paid')
|
|
");
|
|
$stmtTx->execute([
|
|
':ref' => $transactionRef,
|
|
':pid' => $passengerId,
|
|
':amt' => $amount,
|
|
':curr' => $currency
|
|
]);
|
|
|
|
// 6b. تفعيل أو تجديد اشتراك Prime (30 يوماً)
|
|
$expireAt = date('Y-m-d H:i:s', strtotime('+30 days'));
|
|
$stmtPrime = $con->prepare("
|
|
INSERT INTO passenger_prime_subscriptions (passenger_id, is_prime, expire_at)
|
|
VALUES (:pid, 1, :exp)
|
|
ON DUPLICATE KEY UPDATE is_prime = 1, expire_at = :exp2, updated_at = NOW()
|
|
");
|
|
$stmtPrime->execute([
|
|
':pid' => $passengerId,
|
|
':exp' => $expireAt,
|
|
':exp2' => $expireAt
|
|
]);
|
|
|
|
// 6c. خصم المبلغ من المحفظة عبر S2S (نفس نمط tips/add.php)
|
|
$deductUrl = "$walletServer/v2/main/ride/payment/add.php";
|
|
$deductData = [
|
|
"user_id" => $passengerId,
|
|
"user_type" => "passenger",
|
|
"amount" => -1 * $amount, // سالب = خصم
|
|
"action" => "subtract",
|
|
"paymentID" => $transactionRef,
|
|
"paymentMethod" => "prime-subscription",
|
|
"reason" => "Siro Prime Subscription - 1 Month"
|
|
];
|
|
|
|
$chDeduct = curl_init($deductUrl);
|
|
curl_setopt_array($chDeduct, [
|
|
CURLOPT_POST => true,
|
|
CURLOPT_POSTFIELDS => http_build_query($deductData),
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 15,
|
|
CURLOPT_HTTPHEADER => [
|
|
'Content-Type: application/x-www-form-urlencoded',
|
|
'X-S2S-Api-Key: ' . $s2sKey
|
|
]
|
|
]);
|
|
|
|
$deductRaw = curl_exec($chDeduct);
|
|
$deductCode = curl_getinfo($chDeduct, CURLINFO_HTTP_CODE);
|
|
$deductErr = curl_error($chDeduct);
|
|
curl_close($chDeduct);
|
|
|
|
$deductRes = json_decode($deductRaw, true);
|
|
|
|
if ($deductErr || $deductCode !== 200 || ($deductRes['status'] ?? '') !== 'success') {
|
|
// فشل الخصم → نرجع الكل
|
|
$con->rollBack();
|
|
error_log("[Prime] Wallet deduct FAILED: HTTP $deductCode | err: $deductErr | response: $deductRaw");
|
|
jsonError("Failed to deduct wallet balance. Please try again.");
|
|
exit;
|
|
}
|
|
|
|
$con->commit();
|
|
|
|
// 6d. تحديث Redis فوراً (التفعيل اللحظي بدون إعادة طلب من DB)
|
|
if (isset($redis) && $redis !== null) {
|
|
try {
|
|
$primeKey = "prime:passenger:{$passengerId}";
|
|
$redis->setex($primeKey, 3600, json_encode([
|
|
'is_prime' => 1,
|
|
'expire_at' => $expireAt
|
|
]));
|
|
} catch (Exception $e) {
|
|
// Redis failure is non-critical — DB is source of truth
|
|
error_log("[Prime] Redis update failed (non-critical): " . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
// ── 7. ردّ النجاح للفلاتر ───────────────────────────────────
|
|
jsonSuccess([
|
|
'is_prime' => true,
|
|
'expire_at' => $expireAt,
|
|
'transaction_ref' => $transactionRef,
|
|
'amount_deducted' => $amount,
|
|
'currency' => $currency,
|
|
], "Welcome to Siro Prime! 👑");
|
|
|
|
} catch (PDOException $e) {
|
|
if ($con->inTransaction()) {
|
|
$con->rollBack();
|
|
}
|
|
error_log("[Prime] DB Error: " . $e->getMessage());
|
|
jsonError("Database error. Please try again.");
|
|
}
|
|
?>
|