<?php
/*
	
	osConcert, Online Seat Booking 
  	http://www.osconcert.com

  	Copyright (c) 2020-2025 osConcert

	Released under the GNU General Public License
*/

// file to handle the Stripe webhook

// Set flag that this is a parent file
	define( '_FEXEC', 1 );

require('includes/application_top.php');

require_once('./includes/modules/payment/stripesca.php');
// Hardcode English as no language session is available in the webhook
include_once('./includes/languages/english/modules/payment/stripesca.php');
require_once('./ext/modules/payment/stripesca/init.php');

error_log("STRIPE WEBHOOK START");

$stripesca = new stripesca;
\Stripe\Stripe::setApiKey($stripesca->secret);
\Stripe\Stripe::setApiVersion( '2019-12-03');


$payload = @file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];

$endpoint_secret = (MODULE_PAYMENT_STRIPESCA_TESTMODE == 'Test')
    ? MODULE_PAYMENT_STRIPESCA_TESTING_WEBHOOK_KEY
    : MODULE_PAYMENT_STRIPESCA_WEBHOOK_KEY;
	
	if (empty($endpoint_secret)) {
    error_log('[STRIPE WEBHOOK] Webhook signing secret is missing.');
    http_response_code(400);
    exit();
}

try {

    $event = \Stripe\Webhook::constructEvent(
        $payload,
        $sig_header,
        $endpoint_secret
    );
} catch(\UnexpectedValueException $e) {

    // Invalid payload
    error_log('[STRIPE WEBHOOK] Invalid payload');

    http_response_code(400);
    exit();

} catch(\Stripe\Exception\SignatureVerificationException $e) {

    // Invalid signature / wrong webhook secret
    error_log('[STRIPE WEBHOOK] Invalid webhook signing secret or signature');

    http_response_code(400);
    exit();

}

if ($event->type == "payment_intent.succeeded") {
    $intent = $event->data->object;
    //error_log("WH: Payment succeeded - " . $intent->id);
    release_order($intent->id, $intent);
    http_response_code(200);
    exit();
} elseif ($event->type === "payment_intent.canceled") {
    $intent = $event->data->object;
    $error_message = $intent->last_payment_error ? $intent->last_payment_error->message : "";	
    //error_log("WH: Payment canceled - " . $intent->id . " - " . $error_message);
	cancel_order($intent->id, $error_message);
	print  "Cancelled";
    http_response_code(200);
    exit();

	
} elseif ($event->type === "payment_intent.payment_failed") {
    $intent = $event->data->object;
    $error_message = $intent->last_payment_error ? $intent->last_payment_error->message : "";
    //error_log("WH: Payment failed - " . $intent->id . " - " . $error_message);
	note_order($intent->id, "Payment failed: ".$error_message);
    http_response_code(200);
    exit();
	

} elseif ($event->type === "checkout.session.completed") {
    $session_id = $event->data->object->id;
    $payment_id = $event->data->object->payment_intent;

    //error_log("WH: Checkout session completed, releasing order.");
	http_response_code(200);
    exit();
}

function cancel_order($payment_id, $note){
	global $stripesca;
	$order_query = tep_db_query("select orders_id from " . TABLE_ORDERS . " where payment_return2 = '" . $payment_id. "' LIMIT 1");	
	$order_result =tep_db_fetch_array($order_query);
	$order_id = $order_result['orders_id'];

    if (empty($order_id)){echo ('  Order ID not found  ');
	http_response_code(400);
	exit();}

    // if we have the order_id then do stuff
    if (tep_not_null($order_id)) {
		
		$stripesca->repopulate_cart($order_id,'','',"Webhook: ".MODULE_PAYMENT_STRIPESCA_CANCEL_ERROR);
            
       return false;
      
    }

}

function note_order($payment_id, $note){
	
	$order_query = tep_db_query("select orders_id from " . TABLE_ORDERS . " where payment_return2 = '" . $payment_id. "' LIMIT 1");	
	$order_result =tep_db_fetch_array($order_query);
	$this_order_id = $order_result['orders_id'];

    if (empty($this_order_id)){
	//echo ('  Order ID not found  ');
	http_response_code(500);
	exit();
	}
	
	//get current order status
	$order_status=tep_db_query("select orders_status from orders where orders_id='".$this_order_id."'");
	$order_result= tep_db_fetch_array($order_status);
	$status_orig = $order_result['orders_status'];	
	
 $sql_data_array = array('orders_id' => $this_order_id,
        'orders_status_id' => $status_orig,
        'date_added' => date('Y-m-d H:i:s',getServerDate(false)),
        'customer_notified' => 0,
        'comments' => $note );
        tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);
		
		return false;
	
}
	
function release_order($payment_id, $intent){
    global $FSESSION, $order;
	 
    $order_query = tep_db_query("select orders_id from " . TABLE_ORDERS . " where payment_return2 = '" . $payment_id. "' LIMIT 1");	
	$order_result =tep_db_fetch_array($order_query);
	$this_order_id = $order_result['orders_id'];

    if (empty($this_order_id)){
	//echo ('  Order ID not found  ');
	http_response_code(500);
	exit();}
	
	$status = MODULE_PAYMENT_STRIPESCA_COMP_ORDER_STATUS_ID;

    // Update order status
    tep_db_query("UPDATE " . TABLE_ORDERS . " SET orders_status = " . $status . " WHERE orders_id = " . $this_order_id);
    tep_db_query("UPDATE orders_products SET orders_products_status = " . $status . " WHERE orders_id = " . $this_order_id);
    tep_db_query("UPDATE orders SET date_paid = '" . getServerDate(true) . "' WHERE orders_id = " . $this_order_id);
				

    $delivered = '';

	if (isset($intent->status) && $intent->status === 'succeeded') {	
    $message = MODULE_PAYMENT_STRIPESCA_SUCCESS;
    $status  = MODULE_PAYMENT_STRIPESCA_COMP_ORDER_STATUS_ID;
    $delivered = 'yes';
	
	    // Payment succeeded, so activate all vouchers for this order
    $sql = "UPDATE " . TABLE_COUPONS . " 
            SET coupon_active = 'Y' 
            WHERE orders_id = " . (int)$this_order_id;
    tep_db_query($sql);
    
    // Optionally log this action:
   // error_log("Activated all vouchers for order " . $this_order_id);
	
} else {
    error_log("PaymentIntent status is not succeeded: " . print_r($intent, true));
    // Optionally, you can exit early or set a default status.
    exit(); // or return, to prevent further processing
}


	//error_log("WH:PaymentIntent status: " . $intent->status);

	//update order changing status if completed
	
	$order_status_query = tep_db_query("select orders_status from " . TABLE_ORDERS . " where orders_id = '" . (int)$this_order_id . "'");
$order_status_result = tep_db_fetch_array($order_status_query);
$status_orig = (int)$order_status_result['orders_status'];
	
	if ($status != $status_orig) {
    $sql_data_array = array('orders_status' => $status);
    tep_db_perform(TABLE_ORDERS, $sql_data_array, 'update', 'orders_id=' . $this_order_id);

    // Update orders_products using a non-empty $status
    //error_log("Updating orders_products with status: " . $status);
    tep_db_query("update orders_products set orders_products_status = " . $status . " where orders_id = " . $this_order_id);
    tep_db_query("update orders set date_paid = '" . getServerDate(true) . "' where orders_id = " . $this_order_id);

	
	try {

        if(function_exists('update_season_queue')){

            update_season_queue((int)$oID, $status );          

            }

        } catch (Exception $e) {

            unset($e);

        }
	
	}else{
		
		$status=$status_orig;
	}
	
	
	$sql_data_array = array('orders_id' => $this_order_id,
	'orders_status_id' => $status,
	'date_added' => date('Y-m-d H:i:s',getServerDate(false)),
	'customer_notified' => 1,
	 'comments' => $message);
	tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);
	
	tep_db_query("update orders_products set orders_products_status = ". $status . " where orders_id = " . $this_order_id);

//send order emails 

	// Set/check the sending email flag
	$sending_status = tep_db_query("SELECT email_sending FROM email_data WHERE order_id='" . $this_order_id . "'");
	$sending_result = tep_db_fetch_array($sending_status);
	if ($sending_result['email_sending'] == 0) {  // Email not yet sent

		// (a) Set the sending flag
		tep_db_query("UPDATE email_data SET email_sending = 1 WHERE order_id = " . $this_order_id);

		// (1) Calculate order_is_printable
		$order_is_printable = 0;
		if (!is_null($order->products) && is_array($order->products)) {
			for ($i = 0, $n = sizeof($order->products); $i < $n; $i++) {
				$order_is_printable += $order->products[$i]['is_printable'];
			}
		} else {
			$order_is_printable = 0;
		}

		// (2) If printable, setup ticket and generate PDFs for both eTickets and vouchers
		$filename = "";
		$vfilename = "";

		$is_eticket = false;
		$is_voucher = false;
		// Determine if order contains eTickets and/or vouchers (use your SKU definitions)
		foreach ($order->products as $product) {
			if ($product['sku'] == 6 || $product['sku'] == 8) { // Vouchers
				$is_voucher = true;
			}
			if ($product['sku'] == 1 || $product['sku'] == 9) { // eTickets
				$is_eticket = true;
			}
		}

		if (EMAIL_PDF_DELIVERED_ONLY == 'true' && E_TICKETS == 'true' && $status == E_TICKET_STATUS) {
			try {
				// Generate eTicket PDF if applicable
				if ($is_eticket) {
					require_once('includes/functions/products_ticket.php');
					$filename = create_checkout_pdf($this_order_id);  // Generate eTicket PDF
				}
				// Generate Voucher PDF if applicable
				if ($is_voucher) {
					require_once('includes/functions/voucher_ticket.php');
					$vfilename = create_voucher_checkout_pdf($this_order_id);  // Generate Voucher PDF
					// If needed, convert to absolute path:
					if ($vfilename && !file_exists($vfilename)) {
						$vfilename = DIR_FS_CATALOG . $vfilename;
					}
				}
			} catch (Exception $e) {
				error_log("Exception during PDF generation: " . $e->getMessage());
			}

			// Log file paths for debugging
			//error_log("eTicket file path: " . $filename);
			//error_log("Voucher file path: " . $vfilename);

			// Mark tickets as printed
			tep_db_query("UPDATE " . TABLE_ORDERS . " SET ticket_printed='Y' WHERE orders_id = " . $this_order_id);
		}


    try {
        $email_sent = tep_db_query("SELECT * FROM email_data WHERE order_id='" . $this_order_id . "'");
        while ($email_result = tep_db_fetch_array($email_sent)) {
            // Send email with both attachments: $filename (eTicket) and $vfilename (Voucher)
           


		   if (is_array($filename)) {
				$filename = $filename[0]; // Use the first element if it's an array
			}
			if (is_array($vfilename)) {
				$vfilename = $vfilename[0]; // Use the first element if it's an array
			}

			tep_send_default_email(
				"PRD",
				unserialize(base64_decode($email_result['merge_data'])),
				unserialize(base64_decode($email_result['send_data'])),
				$filename,
				$vfilename
			);
        }
    } catch (Exception $e) {
        error_log("Exception during email sending: " . $e->getMessage());
    }

		try {
			if (function_exists('update_season_queue')) {
				update_season_queue((int)$this_order_id, $status);
			}
		} catch (Exception $e) {
			unset($e);
		}
					
		// If delivered then delete email data from table
		if ($delivered == 'yes') {
			tep_db_query("DELETE FROM email_data WHERE order_id='" . $this_order_id . "'");
		}
	}
	
}
?>