146 lines
6.2 KiB
PHP
146 lines
6.2 KiB
PHP
<?php
|
|
/**
|
|
* PayPal Checkout - Create Order Endpoint
|
|
*
|
|
* Called by the PayPal JS SDK when user clicks the PayPal button.
|
|
* Creates a PayPal order with amount from session/database (server-side validation).
|
|
*
|
|
* Returns JSON: { "id": "PAYPAL_ORDER_ID" } or { "error": "message" }
|
|
*/
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
// Start session if not already started
|
|
if (session_status() === PHP_SESSION_NONE) {
|
|
session_start();
|
|
}
|
|
|
|
// Include database and required files
|
|
// Adjust this path if your db.php is elsewhere
|
|
if (file_exists(__DIR__ . '/db.php')) {
|
|
require_once __DIR__ . '/db.php';
|
|
}
|
|
|
|
require_once __DIR__ . '/paypal_checkout_api.php';
|
|
|
|
try {
|
|
// =========================================================================
|
|
// IMPORTANT: Get amount from SERVER-SIDE (database/session), NOT from client
|
|
// This prevents users from tampering with the payment amount
|
|
// =========================================================================
|
|
|
|
// Method 1: If you have school_num and user_num in session (like your existing flow)
|
|
// Only use this branch if the db helpers are available in the current app.
|
|
if (
|
|
isset($_SESSION['UserInfo']['record_num']) &&
|
|
isset($_SESSION['SchoolInfo']['record_num']) &&
|
|
function_exists('db_getVal') &&
|
|
function_exists('db_query') &&
|
|
function_exists('db_num_rows') &&
|
|
function_exists('db_fetch_array') &&
|
|
(function_exists('db_fetch_assoc') || function_exists('db_fetch_array')) &&
|
|
function_exists('db_insert_id')
|
|
) {
|
|
$user_num = intval($_SESSION['UserInfo']['record_num']);
|
|
$school_num = intval($_SESSION['SchoolInfo']['record_num']);
|
|
|
|
// Get balance from database (same query as payment_form.php)
|
|
$balance = db_getVal("SELECT SUM(transaction_amount) as balance FROM user_account WHERE school_num = $school_num AND user_num = $user_num AND (deleted != 'Y' OR deleted IS NULL)");
|
|
if (!$balance) $balance = 0.00;
|
|
|
|
// Get school record for PayPal settings
|
|
// Some codebases use db_fetch_assoc, others use db_fetch_array
|
|
$schoolQuery = db_query("SELECT * FROM schools WHERE record_num = $school_num");
|
|
if (function_exists('db_fetch_assoc')) {
|
|
$school_record = db_fetch_assoc($schoolQuery);
|
|
} else {
|
|
$school_record = db_fetch_array($schoolQuery);
|
|
}
|
|
|
|
// Calculate transaction fee (same as payment_form.php)
|
|
$trx_fee = intval($balance * $school_record['paypal_percentage']) / 100 + $school_record['paypal_fee'];
|
|
$owing = $balance + $trx_fee;
|
|
|
|
// Get or create TRX number (same logic as payment_form.php)
|
|
$now = time();
|
|
$trx_time = date("Y-m-d H:i:s", $now);
|
|
|
|
$query = "SELECT * FROM user_online_payments WHERE school_num = $school_num AND user_num = $user_num AND status = 'Pending'";
|
|
$results = db_query($query);
|
|
|
|
if (db_num_rows($results) > 0) {
|
|
$row = db_fetch_array($results);
|
|
$trxnum = $row['record_num'];
|
|
$query = "UPDATE user_online_payments SET user_account_balance = $balance, transaction_fee = $trx_fee, balance_owing = $owing, transaction_datetime = '$trx_time', transaction_time = $now WHERE school_num = $school_num AND user_num = $user_num AND status = 'Pending'";
|
|
db_query($query);
|
|
} else {
|
|
$query = "INSERT INTO user_online_payments (school_num, user_num, transaction_datetime, transaction_time, user_account_balance, transaction_fee, balance_owing, status) VALUES ($school_num, $user_num, '$trx_time', $now, $balance, $trx_fee, $owing, 'Pending')";
|
|
db_query($query);
|
|
$trxnum = db_insert_id();
|
|
}
|
|
|
|
$currency = $school_record['paypal_currency'] ?: PAYPAL_CURRENCY;
|
|
$description = $school_record['school_name'] . " Order Payment";
|
|
|
|
}
|
|
// Method 2: Fallback - use session variables if set directly
|
|
else if (isset($_SESSION['paypal_checkout_amount']) && isset($_SESSION['paypal_checkout_trxnum'])) {
|
|
$owing = floatval($_SESSION['paypal_checkout_amount']);
|
|
$trxnum = intval($_SESSION['paypal_checkout_trxnum']);
|
|
$currency = $_SESSION['paypal_checkout_currency'] ?? PAYPAL_CURRENCY;
|
|
$description = $_SESSION['paypal_checkout_description'] ?? 'Order Payment';
|
|
}
|
|
// Method 3: For testing/demo - use POST data (NOT recommended for production)
|
|
else if (isset($_POST['amount']) && isset($_POST['trxnum'])) {
|
|
// WARNING: In production, ALWAYS validate this against your database
|
|
$owing = floatval($_POST['amount']);
|
|
$trxnum = intval($_POST['trxnum']);
|
|
$currency = $_POST['currency'] ?? PAYPAL_CURRENCY;
|
|
$description = $_POST['description'] ?? 'Order Payment';
|
|
|
|
// You should validate that this trxnum exists and the amount matches!
|
|
// This is just for demo purposes
|
|
}
|
|
else {
|
|
throw new Exception('No payment information found. Please ensure you are logged in.');
|
|
}
|
|
|
|
// Validate amount
|
|
if ($owing <= 0) {
|
|
throw new Exception('Invalid payment amount: ' . $owing);
|
|
}
|
|
|
|
// Create PayPal order
|
|
$paypal = new PayPalCheckoutAPI();
|
|
$order = $paypal->createOrder($owing, $currency, $description, strval($trxnum));
|
|
|
|
// Store order ID in session for verification during capture
|
|
$_SESSION['paypal_order_id'] = $order['id'];
|
|
$_SESSION['paypal_order_trxnum'] = $trxnum;
|
|
$_SESSION['paypal_order_amount'] = $owing;
|
|
|
|
// Approve link — where the redirect-based button sends the buyer to
|
|
// log in to PayPal and approve the payment (not used by the JS SDK
|
|
// button flow, which drives approval in its own popup/iframe instead).
|
|
$approveUrl = '';
|
|
foreach (($order['links'] ?? []) as $link) {
|
|
if (($link['rel'] ?? '') === 'approve') {
|
|
$approveUrl = $link['href'];
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Return order ID (used by the PayPal JS SDK button) and approve URL
|
|
// (used by the plain themed button's redirect flow)
|
|
echo json_encode([
|
|
'id' => $order['id'],
|
|
'approveUrl' => $approveUrl
|
|
]);
|
|
|
|
} catch (Exception $e) {
|
|
http_response_code(500);
|
|
echo json_encode([
|
|
'error' => $e->getMessage()
|
|
]);
|
|
}
|