<?php
/*
 * ============================================================
 * TryTrack — PayFast ITN (Instant Transaction Notification)
 * ============================================================
 *
 * This endpoint receives POST callbacks from PayFast when a
 * payment is completed, cancelled, or fails.
 *
 * SECURITY REQUIREMENTS (all checked below):
 *   1. PayFast IP allowlist — only accept from known PayFast IPs
 *   2. Signature verification — validate the MD5 signature
 *   3. Amount verification   — confirm amount matches expected
 *   4. Only act on COMPLETE status
 *
 * TODO before going live:
 *   - Replace the Firestore stub at the bottom with a real call
 *     to Firebase Admin SDK or a Cloud Function.
 *   - Set PAYFAST_PASSPHRASE from an environment variable.
 *
 * ============================================================
 */

header("HTTP/1.0 200 OK");

// ── Config ───────────────────────────────────────────────────
$PAYFAST_SANDBOX    = true;  // ← Match create-payfast-checkout.php
$PAYFAST_PASSPHRASE = getenv("PAYFAST_PASSPHRASE") ?: "";

// Known PayFast IP ranges (keep updated from PayFast docs)
$ALLOWED_IPS = [
    "197.97.145.144",
    "197.97.145.145",
    "197.97.145.146",
    "197.97.145.147",
    "196.33.227.224",
    "196.33.227.225",
    "196.33.227.226",
    "196.33.227.227",
    // Sandbox
    "196.33.227.207",
];

// ── Log helper ───────────────────────────────────────────────
function itn_log(string $message): void {
    file_put_contents(
        __DIR__ . "/payfast-itn-log.txt",
        date("Y-m-d H:i:s") . " " . $message . PHP_EOL,
        FILE_APPEND
    );
}

// ── 1. IP allowlist check ────────────────────────────────────
$requestIp = $_SERVER["REMOTE_ADDR"] ?? "";

// In sandbox mode, skip IP check
if (!$PAYFAST_SANDBOX && !in_array($requestIp, $ALLOWED_IPS, true)) {
    itn_log("REJECTED: IP not in allowlist — $requestIp");
    http_response_code(403);
    exit;
}

// ── 2. Parse POST data ───────────────────────────────────────
$rawPostData = file_get_contents("php://input");
parse_str($rawPostData, $data);

itn_log("RECEIVED: " . json_encode($data));

if (empty($data)) {
    itn_log("ERROR: Empty POST data");
    exit;
}

// ── 3. Signature verification ────────────────────────────────
$receivedSignature = $data["signature"] ?? "";
unset($data["signature"]);

$sigParts = [];
foreach ($data as $key => $value) {
    if ($value !== "") {
        $sigParts[] = $key . "=" . urlencode(trim($value));
    }
}

$sigString = implode("&", $sigParts);

if ($PAYFAST_PASSPHRASE !== "") {
    $sigString .= "&passphrase=" . urlencode(trim($PAYFAST_PASSPHRASE));
}

$expectedSignature = md5($sigString);

if (!hash_equals($expectedSignature, $receivedSignature)) {
    itn_log("REJECTED: Signature mismatch — expected $expectedSignature got $receivedSignature");
    http_response_code(403);
    exit;
}

// ── 4. Extract key fields ────────────────────────────────────
$paymentStatus  = $data["payment_status"]  ?? "";
$organisationId = $data["custom_str1"]     ?? "";
$plan           = $data["custom_str2"]     ?? "";
$cycle          = $data["custom_str3"]     ?? "";
$amountGross    = $data["amount_gross"]    ?? "0";
$paymentId      = $data["m_payment_id"]    ?? "";

// ── 5. Only handle COMPLETE payments ─────────────────────────
if ($paymentStatus !== "COMPLETE") {
    itn_log("IGNORED: Status is $paymentStatus for $organisationId");
    exit;
}

// ── 6. Validate required fields ──────────────────────────────
if (!$organisationId || !$plan || !$cycle) {
    itn_log("ERROR: Missing custom fields — org=$organisationId plan=$plan cycle=$cycle");
    exit;
}

itn_log("COMPLETE: Org=$organisationId Plan=$plan Cycle=$cycle Amount=$amountGross");

// ── 7. Update Firestore subscription ─────────────────────────
// Option A: Call your Firebase Cloud Function
// This is the recommended approach so the Firebase Admin SDK
// (with service account credentials) stays server-side.
//
// Example:
// $cloudFunctionUrl = getenv("FIREBASE_ACTIVATE_URL");
// $payload = json_encode([
//     "organisationId" => $organisationId,
//     "plan"           => $plan,
//     "billingCycle"   => $cycle,
//     "amount"         => $amountGross,
//     "currency"       => "ZAR",
//     "paymentId"      => $paymentId,
// ]);
// $ch = curl_init($cloudFunctionUrl);
// curl_setopt($ch, CURLOPT_POST, true);
// curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
// curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// $response = curl_exec($ch);
// $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// curl_close($ch);
// itn_log("CLOUD_FUNCTION: HTTP $httpCode — $response");

// ── Fallback log (remove once Cloud Function is wired) ───────
file_put_contents(
    __DIR__ . "/payfast-complete-log.txt",
    date("Y-m-d H:i:s")
        . " | COMPLETE"
        . " | Org: $organisationId"
        . " | Plan: $plan"
        . " | Cycle: $cycle"
        . " | Amount: $amountGross ZAR"
        . PHP_EOL,
    FILE_APPEND
);

exit;
