<?php
/**
 * express-stk.php
 * Sends M-Pesa STK Push and redirects to wait.php
 */

require 'config.php';

/* -------------------------------------------------
   1. FORCE CORRECT TIMEZONE (VERY IMPORTANT)
-------------------------------------------------- */

/* -------------------------------------------------
   2. BASIC INPUT VALIDATION
-------------------------------------------------- */
$phone  = trim($_POST['phone'] ?? '');
$amount = (int)($_POST['amount'] ?? 0);
$entity = ($_POST['entity'] ?? '');

if ($phone === '' || $amount <= 0) {
    die('Invalid payment details.');
}

/* Normalize phone number (2547XXXXXXXX) */
$phone = preg_replace('/\D/', '', $phone);
if (strlen($phone) === 10 && str_starts_with($phone, '07')) {
    $phone = '254' . substr($phone, 1);
}

if (!preg_match('/^2547\d{8}$/', $phone)) {
    die('Invalid phone number format.');
}

/* -------------------------------------------------
   3. GET ACCESS TOKEN
-------------------------------------------------- */
$credentials = base64_encode(CONSUMER_KEY . ':' . CONSUMER_SECRET);

$ch = curl_init('https://api.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials');
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Basic $credentials"],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 20
]);

$response = curl_exec($ch);
if ($response === false) {
    die('Unable to connect to M-Pesa.');
}
curl_close($ch);

$tokenData = json_decode($response, true);
$accessToken = $tokenData['access_token'] ?? null;

if (!$accessToken) {
    die('Failed to get access token.');
}

/* -------------------------------------------------
   4. GENERATE TIMESTAMP & PASSWORD (CORRECT)
-------------------------------------------------- */
$dt = new DateTime('now', new DateTimeZone('Africa/Nairobi'));
$timestamp = $dt->format('dmYHis');
$password = base64_encode(SHORTCODE . PASSKEY . $timestamp);


/* -------------------------------------------------
   5. PREPARE STK REQUEST
-------------------------------------------------- */
$accountReference = uniqid('ORD');
$payload = [
    "BusinessShortCode" => SHORTCODE,
    "Password" => $password,
    "Timestamp" => $timestamp,
    "TransactionType" => "CustomerBuyGoodsOnline",
    "Amount" => $amount,
    "PartyA" => $phone,
    "PartyB" => 5230103,
    "PhoneNumber" => $phone,
    "CallBackURL" => CALLBACK_URL,
    "AccountReference" => $accountReference,
    "TransactionDesc" => "Payment"
];

/* -------------------------------------------------
   6. SEND STK PUSH
-------------------------------------------------- */
$ch = curl_init('https://api.safaricom.co.ke/mpesa/stkpush/v1/processrequest');
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $accessToken",
        "Content-Type: application/json"
    ],
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode($payload),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30
]);

$response = curl_exec($ch);
if ($response === false) {
    die('STK request failed.');
}
curl_close($ch);

$responseData = json_decode($response, true);

/* -------------------------------------------------
   7. VERIFY RESPONSE
-------------------------------------------------- */
if (
    empty($responseData['CheckoutRequestID']) ||
    empty($responseData['MerchantRequestID'])
) {
    die('Failed to initiate payment.');
}

/* -------------------------------------------------
   8. SAVE TRANSACTION AS PENDING
-------------------------------------------------- */
$stmt = $pdo->prepare("
    INSERT INTO mpesa_payments
    (checkout_request_id, merchant_request_id, phone, amount, entity, status)
    VALUES (?, ?, ?, ?, ?, 'pending')
");

$stmt->execute([
    $responseData['CheckoutRequestID'],
    $responseData['MerchantRequestID'],
    $phone,
    $amount,
    $entity
]);

/* -------------------------------------------------
   9. REDIRECT TO WAITING PAGE
-------------------------------------------------- */
header(
    'Location: wait.php?checkout_id=' .
    urlencode($responseData['CheckoutRequestID'])
);
exit;
