<?php
require_once DIR_SYSTEM . "library" . DIRECTORY_SEPARATOR . "iyzico" . DIRECTORY_SEPARATOR . "IyzipayBootstrap.php";
class ControllerExtensionPaymentIyzicoCheckoutForm extends Controller {

    private $base_url = "https://api.iyzipay.com";
    private $order_prefix = "PSIYZICO_";
    private $valid_currency = array("TRY", "GBP", "USD", "EUR", "IRR");
    private $iyzico_version = "v5";
    public function index() {

        $this->load->language('extension/payment/iyzico_checkout_form');
        $this->load->model('checkout/order');
        $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
        $cart_total_amount = round($order_info['total'] * $order_info['currency_value'], 2);
        $data['cart_total'] = $cart_total_amount;
        $data['code'] = $this->language->get('code');
        $data['form_class'] = $this->config->get('iyzico_checkout_form_form_class');
        $data['text_credit_card'] = $this->language->get('text_credit_card');
        $data['text_wait'] = $this->language->get('text_wait');
        $data['button_confirm'] = $this->language->get('button_confirm');
        $data['continue'] = $this->url->link('checkout/success');
        $data['error_page'] = $this->url->link('checkout/error');



        if(file_exists(DIR_LOCAL_TEMPLATE . $this->config->get('theme_default_directory') .'/template/extension/payment/iyzico_checkout_form.tpl')){
            return $this->load->view( DIR_LOCAL_TEMPLATE . $this->config->get('theme_default_directory') .'/template/extension/payment/iyzico_checkout_form', $data);
        }else{
            return $this->load->view(DIR_TEMPLATE . 'default/template/extension/payment/iyzico_checkout_form', $data);
        }


    }

    public function gettoken() {

        try {

            $setCookie = $this->setcookieSameSite("PHPSESSID",$_COOKIE['PHPSESSID'], time() + 86400, "/", $_SERVER['SERVER_NAME'],true, true);
            $setCookie = $this->setcookieSameSite("default",$_COOKIE['default'], time() + 86400, "/", $_SERVER['SERVER_NAME'],true, true);

            IyzipayBootstrap::init();

            $data['checkout_form_content'] = '';
            $data['error'] = '';
            $data['form_class'] = $this->config->get('iyzico_checkout_form_form_class');
            $data['continue'] = $this->url->link('checkout/success');
            $data['error_page'] = $this->url->link('checkout/error');
            $data['display_direct_confirm'] = 'no';

            $route_url = 'extension/payment/iyzico_checkout_form/callback';
            $callback_url = $this->getSiteUrl() . 'index.php?route=' . $route_url;

            $order_id = $this->session->data['order_id'];
            $unique_conversation_id = uniqid($this->order_prefix) . "_" . $order_id;

            $merchant_api_id = $this->config->get('iyzico_checkout_form_api_id_live');
            $merchant_secret_key = $this->config->get('iyzico_checkout_form_secret_key_live');

            $options = new \Iyzipay\Options();
            $options->setApiKey($merchant_api_id);
            $options->setSecretKey($merchant_secret_key);
            $options->setBaseUrl($this->base_url);

            $this->load->language('extension/payment/iyzico_checkout_form');

            if(file_exists(DIR_LOCAL_TEMPLATE . $this->config->get('theme_default_directory') .'/template/extension/payment/iyzico_checkout_form.tpl')){
                $this->template = DIR_LOCAL_TEMPLATE . $this->config->get('theme_default_directory') . '/template/extension/payment/iyzico_checkout_form';
            }else{
                $this->template = DIR_TEMPLATE . 'default/template/extension/payment/iyzico_checkout_form';
            }

            $this->load->model('checkout/order');
            $this->load->model('catalog/product');
            $this->load->model('catalog/category');
            $this->load->model('account/customer');
            $this->load->model('extension/extension');
            $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);

            if (!in_array($order_info['currency_code'], $this->valid_currency)) {
                throw new \Exception($this->language->get('error_invalid_currency'));
            }

            $cart_total_amount = round($order_info['total'] * $order_info['currency_value'], 2);

            if ($cart_total_amount == 0) {
                $data['display_direct_confirm'] = 'yes';
                $this->response->addHeader('Content-Type: application/json');
                $this->response->setOutput(json_encode($data));
                return true;
            }
            $locale = \Iyzipay\Model\Locale::EN;
            $siteLang = explode('-', $order_info['language_code']);
            if($siteLang[0] == 'tr'){
                $locale = \Iyzipay\Model\Locale::TR;
            }
            $request = new \Iyzipay\Request\CreateCheckoutFormInitializeRequest();
            $request->setLocale($locale);
            $request->setConversationId($unique_conversation_id);

            // * 0.90
            // %10 İndirim
            // if($this->config->get('promotion')['discount_percent']){
            //     //if(isset($this->session->data['user_id'])) {
            //         $cart_total_amount *= 0.90;
            //     //}
            // }
            $request->setPaidPrice($cart_total_amount);
            $request->setBasketId($unique_conversation_id);
            $request->setPaymentGroup(\Iyzipay\Model\PaymentGroup::PRODUCT);
            $request->setPaymentSource("PIYERSOFT-" . $this->iyzico_version);
            $request->setCallbackUrl($callback_url);
            $request->setCurrency($this->getCurrencyConstant($order_info['currency_code']));

            $customer_address = trim($order_info['payment_address_1'] . " " . $order_info['payment_address_2']);
            $customer_address = !empty($customer_address) ? $customer_address : "NOT PROVIDED";

            $buyer = new \Iyzipay\Model\Buyer();
            $buyer->setId($order_info['customer_id']);

            $order_info_firstname = !empty($order_info['firstname']) ? $order_info['firstname'] : "NOT PROVIDED";
            $order_info_lastname = !empty($order_info['lastname']) ? $order_info['lastname'] : "NOT PROVIDED";
            $order_info_telephone = !empty($order_info['telephone']) ? $order_info['telephone'] : "NOT PROVIDED";
            $order_info_email = !empty($order_info['email']) ? $order_info['email'] : "NOT PROVIDED";

            $buyer->setName($order_info_firstname);
            $buyer->setSurname($order_info_lastname);
            $buyer->setGsmNumber($order_info_telephone);
            $buyer->setEmail($order_info_email);
            $buyer->setRegistrationAddress($customer_address);

            $order_info_payment_zone = !empty($order_info['payment_zone']) ? $order_info['payment_zone'] : "NOT PROVIDED";
            $order_info_payment_city = !empty($order_info['payment_city']) ? $order_info['payment_city'] : $order_info_payment_zone;
            $order_info_payment_country = !empty($order_info['payment_country']) ? $order_info['payment_country'] : "NOT PROVIDED";
            $order_info_payment_postcode = !empty($order_info['payment_postcode']) ? $order_info['payment_postcode'] : "NOT PROVIDED";
            $order_info_ip = !empty($order_info['ip']) ? $order_info['ip'] : "NOT PROVIDED";

            $buyer->setCity($order_info_payment_zone);
            $buyer->setCountry($order_info_payment_country);
            $buyer->setZipCode($order_info_payment_postcode);
            $buyer->setIp($order_info_ip);

            $customer_identity_number = str_pad($order_info['customer_id'], 11, '0', STR_PAD_LEFT);
            $buyer->setIdentityNumber($customer_identity_number);

            if ($order_info['customer_id'] > 0) {
                $customer_query = $this->db->query("SELECT * FROM ps_customer WHERE customer_id = '" . (int) $this->session->data['customer_id'] . "' AND status = '1'");
                $added_date = !empty($customer_query->row['date_added']) ? $customer_query->row['date_added'] : "NOT PROVIDED";
                $buyer->setRegistrationDate($added_date);
            }
            $request->setBuyer($buyer);

            $billing_address = new \Iyzipay\Model\Address();
            $billing_address->setContactName($order_info_firstname);
            $billing_address->setCity($order_info_payment_zone);
            $billing_address->setCountry($order_info_payment_country);
            $billing_address->setAddress($customer_address);
            $billing_address->setZipCode($order_info_payment_postcode);
            $request->setBillingAddress($billing_address);

            $customer_shipping_address1 = !empty($order_info['shipping_address_1']) ? $order_info['shipping_address_1'] : $order_info['payment_address_1'];
            $customer_shipping_address2 = !empty($order_info['shipping_address_2']) ? $order_info['shipping_address_2'] : $order_info['payment_address_2'];
            $customer_shipping_address = trim($customer_shipping_address1 . " " . $customer_shipping_address2);
            $customer_shipping_address = !empty($customer_shipping_address) ? $customer_shipping_address : "NOT PROVIDED";
            $shipping_name = !empty($order_info['shipping_firstname']) ? $order_info['shipping_firstname'] : $order_info_firstname;
            $shipping_zone = !empty($order_info['shipping_zone']) ? $order_info['shipping_zone'] : $order_info_payment_zone;
            $shipping_city = !empty($order_info['shipping_city']) ? $order_info['shipping_city'] : $shipping_zone;
            $shipping_country = !empty($order_info['shipping_country']) ? $order_info['shipping_country'] : $order_info_payment_country;
            $shipping_zip_code = !empty($order_info['shipping_postcode']) ? $order_info['shipping_postcode'] : $order_info_payment_postcode;

            $shipping_address = new \Iyzipay\Model\Address();
            $shipping_address->setContactName($shipping_name);
            $shipping_address->setCity($shipping_city);
            $shipping_address->setCountry($shipping_country);
            $shipping_address->setAddress($customer_shipping_address);
            $shipping_address->setZipCode($shipping_zip_code);
            $request->setShippingAddress($shipping_address);

            $results = $this->model_extension_extension->getExtensions('total');

            foreach ($results as $key => $value) {
                $sort_order[$key] = $this->config->get($value['code'] . '_sort_order');
            }

            array_multisort($sort_order, SORT_ASC, $results);
            $allowed_order_total_extensions = array(
                'reward',
                'shipping',
                'coupon',
                'voucher'
            );
            $allowed_order_total_extensions_sort = array();

            foreach ($results as $result) {
                if ($this->config->get($result['code'] . '_status') && in_array($result['code'], $allowed_order_total_extensions)) {
                    $allowed_order_total_extensions_sort[] = $result['code'];
                }
            }

            $items = array();
            $products = $this->cart->getProducts();
            $product_prices = $total_discounts = $voucher_amount = $voucher_per_item = $applied_voucher_amount = 0;
            $shipping_amount = $total_shipping_charge = $points_total = 0;
            $has_coupon = $has_voucher = $has_rewards = $has_shipping =  false;
            $coupon_info = $voucher_info = $shipping_info = array();
            $purchase_voucher_amount = 0;


            $sub_total = $this->cart->getSubTotal();

            if (isset($this->session->data['coupon'])) {
                $has_coupon = true;
                $coupon = $this->session->data['coupon'];

                $this->load->model('extension/total/coupon');
                $coupon_info = $this->model_extension_total_coupon->getCoupon($coupon);

                if ($coupon_info['type'] == 'F') {
                    $coupon_info['discount'] = min($coupon_info['discount'], $sub_total);
                }
            }

            if (isset($this->session->data['voucher'])) {
                $has_voucher = true;

                $voucher = $this->session->data['voucher'];
                if (VERSION <= '2.0.3.1'){
                    $this->load->model('checkout/voucher');
                    $voucher_info = $this->model_checkout_voucher->getVoucher($voucher);
                } else {
                    $this->load->model('extension/total/voucher');
                    $voucher_info = $this->model_extension_total_voucher->getVoucher($voucher);
                }

                $voucher_info['amount'] = min($voucher_info['amount'], $sub_total);
            }

            $points = $this->customer->getRewardPoints();

            if (isset($this->session->data['reward']) && $this->session->data['reward'] <= $points) {
                $has_rewards = true;
                foreach ($this->cart->getProducts() as $product) {
                    if ($product['points']) {
                        $points_total += $product['points'];
                    }
                }
            }

            if ($this->cart->hasShipping() && isset($this->session->data['shipping_method'])) {
                $has_shipping = true;
                $shipping_info = $this->session->data['shipping_method'];
                $shipping_amount = $shipping_info['cost'];
                if ($shipping_info['tax_class_id']) {
                    $shipping_info['tax'] = $this->tax->getRates($shipping_info['cost'], $shipping_info['tax_class_id']);
                }

            }

            if (!empty($this->session->data['vouchers'])) {
                foreach ($this->session->data['vouchers'] as $key => $voucher) {
                    $purchase_voucher_amount = round($voucher['amount'], 2);
                    $item = new \Iyzipay\Model\BasketItem();
                    $item->setId($key);
                    $item->setName($voucher['description']);
                    $item->setItemType(\Iyzipay\Model\BasketItemType::VIRTUAL);
                    $item->setCategory1("GIFT VOUCHERS");
                    $total_product_price = $voucher['amount'];
                    $total_product_price *= $order_info['currency_value'];
                    $total_product_price = round($total_product_price, 2);
                    $product_prices += $total_product_price;
                    $item->setPrice($total_product_price);
                    $items[] = $item;
                }
            }





            $log = new Log("IyzicoRequestLog.txt");

            $product_name = '';
            $product_id = array();

            foreach ($products as $product) {
                $product_id[] = !empty($product['product_id']) ? $product['product_id'] : 0;
                $product_name = !empty($product['name']) ? $product['name'] : "NOT PROVIDED";
            }

            $exchange_rate = $this->currency->getValue($order_info['currency_code']);
            $tax_total = $this->cart->getTaxes();
            foreach($tax_total as $value){
                $sub_total += $value;
            }


            $sub_total += $shipping_amount * 1.08;
            $sub_total -= $total_discounts;
            $sub_total += $purchase_voucher_amount;
            $sub_total *= $exchange_rate;
            $sub_total = round($sub_total, 2);


            // %10 İndirim
            // if($this->config->get('promotion')['discount_percent']){
            //     //if(isset($this->session->data['user_id'])) {
            //         $sub_total = $sub_total * 0.90;
            //     //}
            // }
            //$sub_total = $sub_total * 0.90;

            //$this->product->dump($sub_total);

            $item = new \Iyzipay\Model\BasketItem();
            $item->setId(implode(',', $product_id));
            $item->setPrice($sub_total);
            $item->setName($product_name);
            $item->setCategory1('NOT PROVIDED');
            $item->setItemType(\Iyzipay\Model\BasketItemType::PHYSICAL);

            $items[] = $item;

            $items = array_values($items);
            $request->setPrice($sub_total);
            $request->setBasketItems($items);



            if (function_exists('curl_version')) {

                $this->load->model('extension/payment/iyzico_checkout_form');
                $save_data_array = array(
                    'order_id' => $order_id,
                    'item_id' => 0,
                    'transaction_status' => 'in process',
                    'date_created' => date('Y-m-d H:i:s'),
                    'date_modified' => date('Y-m-d H:i:s'),
                    'api_request' => $request->toJsonString(),
                    'api_response' => '',
                    'request_type' => 'payment_form_initialization',
                    'note' => ''
                );
                $create_order_entry_id = $this->model_extension_payment_iyzico_checkout_form->createOrderEntry($save_data_array);

                $response = \Iyzipay\Model\CheckoutFormInitialize::create($request, $options);

                $update_data_array = array(
                    'date_modified' => date('Y-m-d H:i:s'),
                    'api_response' => $response->getRawResult(),
                    'transaction_status' => $response->getStatus(),
                    'processing_timestamp' => date('Y-m-d H:i:s', $response->getSystemTime() / 1000)
                );

                $this->model_extension_payment_iyzico_checkout_form->updateOrderEntry($update_data_array, $create_order_entry_id);

                $data['siteUrl'] = $this->getSiteUrl();

                if ($response->getStatus() == "success") {
                    $data['checkout_form_content'] = $response->getCheckoutFormContent();
                } else {
                    $data['error'] = !is_null($response->getErrorMessage()) ? $response->getErrorMessage() : $response->getErrorCode();
                    $log->write("Hata: ----------------- ");
                    $log->write($data['error']);
                }
            } else {
                $data['error'] = $this->language->get("Error_message_curl");
                $log->write("Hata: ----------------- ");
                $log->write($data['error']);
            }
        } catch (\Exception $exc) {
            $data['error'] = $exc->getMessage();
            $log->write("Hata: ----------------- ");
            $log->write($data['error']);
        }

        $this->response->addHeader('Content-Type: application/json');
        $this->response->setOutput(json_encode($data));
    }

    public function getSiteUrl() {
        if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) {
            $site_url = is_null($this->config->get('config_ssl')) ? HTTPS_SERVER : $this->config->get('config_ssl');
        } else {
            $site_url = is_null($this->config->get('config_url')) ? HTTP_SERVER : $this->config->get('config_url');
        }
        return $site_url;
    }

    public function getServerConnectionSlug() {
        if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) {
            $connection = 'SSL';
        } else {
            $connection = 'NONSSL';
        }

        return $connection;
    }

    public function callback() {

        //$order_id = $this->session->data['order_id'];

        $server_conn_slug = $this->getServerConnectionSlug();
        $this->load->language('extension/payment/iyzico_checkout_form');
        $this->load->model('extension/payment/iyzico_checkout_form');
        $this->load->model('checkout/order');
        $postData = $this->request->post;

        $message = '';
        $get_auth_table_id = 0;

        try {

            IyzipayBootstrap::init();

            $merchant_api_id = $this->config->get('iyzico_checkout_form_api_id_live');
            $merchant_secret_key = $this->config->get('iyzico_checkout_form_secret_key_live');

            $options = new \Iyzipay\Options();
            $options->setApiKey($merchant_api_id);
            $options->setSecretKey($merchant_secret_key);
            $options->setBaseUrl($this->base_url);

            $request = new \Iyzipay\Request\RetrieveCheckoutFormRequest();
            $request->setLocale(\Iyzipay\Model\Locale::TR);
            $request->setToken($postData['token']);

            $response = \Iyzipay\Model\CheckoutForm::retrieve($request, $options);

            $transaction = array();

            $basketId = $response->getBasketId();
            $paymentId = $response->getPaymentId();

            $explode_basket_id = explode("_", $basketId);
            $response_order_id = end($explode_basket_id);

            $order_id = $response_order_id;

            if (empty($postData['token'])) {
                throw new \Exception($this->language->get('invalid_request'));
            }

            $log = new Log('iyzico/'.$order_id . "_IyzicoCallbackPostDataLogs.txt");

            $log->write($order_id . " callback başladı ");

            $log->write($order_id . " Try bloğuna girildi ");

            $log->write($postData);
            $log->write($order_id . " Iyzicodan gelen post verileri yazdırılıldı ");

            $save_data_array = array(
                'order_id' => 0,
                'transaction_status' => '',
                'date_created' => date('Y-m-d H:i:s'),
                'date_modified' => date('Y-m-d H:i:s'),
                'api_request' => '',
                'api_response' => json_encode($postData),
                'request_type' => 'post_callback',
                'processing_timestamp' => date('Y-m-d H:i:s'),
                'note' => 'callback'
            );
            $post_callback_id = $this->model_extension_payment_iyzico_checkout_form->createOrderEntry($save_data_array);

            $log->write($order_id . " ps_iyzico_order tablosuna veri yazıldı ID: " . $post_callback_id);

            $this->load->model('extension/payment/iyzico_checkout_form');

            $save_data_array = array(
                'order_id' => 0,
                'item_id' => 0,
                'transaction_status' => 'in process',
                'date_created' => date('Y-m-d H:i:s'),
                'date_modified' => date('Y-m-d H:i:s'),
                'api_request' => $request->toJsonString(),
                'api_response' => '',
                'request_type' => 'get_auth',
                'note' => 'callback'
            );
            $get_auth_table_id = $this->model_extension_payment_iyzico_checkout_form->createOrderEntry($save_data_array);

            $log->write($order_id . " ps_iyzico_order tablosuna 2. veri yazıldı ID: " . $get_auth_table_id);

            $response = \Iyzipay\Model\CheckoutForm::retrieve($request, $options);

            $log->write($order_id . " CheckoutForm::retrieve sonucu aşağıdadır ");
            $log->write($response);
            $log->write($order_id . " CheckoutForm::retrieve sonucu yukarıdadır ");

            $update_data_array = array(
                'date_modified' => date('Y-m-d H:i:s'),
                'api_response' => $response->getRawResult(),
                'transaction_status' => $response->getStatus(),
                'processing_timestamp' => date('Y-m-d H:i:s', $response->getSystemTime() / 1000)
            );
            $this->model_extension_payment_iyzico_checkout_form->updateOrderEntry($update_data_array, $get_auth_table_id);

            $log->write($order_id . " ps_iyzico_order tablosunda veri güncellendi ID: " . $get_auth_table_id);

            if ($response->getStatus() == "failure") {
                $log->write($order_id . " sonuç : failure ");
                $log->write($response->getErrorMessage());
                throw new \Exception($response->getErrorMessage());
            }

            if ($response->getPaymentStatus() == "FAILURE") {
                $log->write($order_id . " sonuç : FAILURE ");
                $log->write($response->getErrorMessage());
                throw new \Exception($response->getErrorMessage());
            }

            $basketId = $response->getBasketId();
            $paymentId = $response->getPaymentId();

            if (!empty($paymentId)) {
                $message .= 'Payment ID: ' . $paymentId . "\n";
            }

            $explode_basket_id = explode("_", $basketId);
            $response_order_id = end($explode_basket_id);

            $update_data_array = array(
                'order_id' => $response_order_id,
                'date_modified' => date('Y-m-d H:i:s'),
                'processing_timestamp' => date('Y-m-d H:i:s', $response->getSystemTime() / 1000)
            );
            $this->model_extension_payment_iyzico_checkout_form->updateOrderEntry($update_data_array, $get_auth_table_id);
            $log->write($order_id . " ps_iyzico_order tablosunda get_auth_table_id numarasına göre güncelleme yapıldı ID: " . $get_auth_table_id);

            $this->model_extension_payment_iyzico_checkout_form->updateOrderEntry($update_data_array, $post_callback_id);
            $log->write($order_id . " ps_iyzico_order tablosunda post_callback_id numarasına göre güncelleme yapıldı ID: " . $post_callback_id);

            if (empty($response_order_id) || $response_order_id != $order_id) {
                throw new \Exception($this->language->get('invalid_order'));
            }

            $order_info = $this->model_checkout_order->getOrder($response_order_id);

            $log->write($order_id . " Sipariş detayı çekildi ");
            $log->write($order_info);

            if (!empty($order_info['order_status_id']) && $order_info['order_status'] != null) {
                throw new \Exception($this->language->get('order_already_exists'));
            }


            $installment = $response->getInstallment();
            if ($installment > 1) {
                $log->write($order_id . " Taksitli işlem için kayıt başladı");

                $this->load->model('checkout/order');
                $order_total = (array) $this->db->query("SELECT * FROM ps_order_total WHERE order_id = '" . (int) $order_id . "' AND code = 'total' ");
                $last_sort_value = $order_total['row']['sort_order'] - 1;
                $exchange_rate = $this->currency->getValue($order_info['currency_code']);
                $new_amount = str_replace(',', '', $response->getPaidPrice());
                $old_amount = str_replace(',', '', $order_info['total'] * $order_info['currency_value']);
                $installment_fee_variation = ($new_amount - $old_amount) / $exchange_rate;
                $this->db->query("INSERT INTO ps_order_total SET order_id = '" .
                    (int) $order_id . "',code = '" . $this->db->escape('iyzico_checkout_form_fee') .
                    "',  title = '" . $this->db->escape($this->language->get('installment_charge')) . "' , `value` = '" .
                    (float) $installment_fee_variation . "', sort_order = '" . (int) $last_sort_value . "'");


                $log->write($order_id . " ps_order_total tablosuna kayıt girildi ");

                //$order_total_data = (array) $this->db->query("SELECT * FROM ps_order_total WHERE order_id = '" . (int) $order_id . "' AND code != 'total' ");
                $order_total_data = (array) $this->db->query("SELECT * FROM ps_order_total 
                                WHERE order_id = '" . (int) $order_id . "' 
                                AND code != 'total'
                                AND code != 'coupon'
                                AND code != 'campaign_price_total' ");
                $calculate_total = 0;
                foreach ($order_total_data['rows'] as $row) {
                    $calculate_total += $row['value'];
                }

                $log->write($order_id . " Taksitli işlem için sipariş toplamları eklendi");

                $this->db->query("UPDATE ps_order_total SET  `value` = '" . (float) $calculate_total . "' WHERE order_id = '$order_id' AND code = 'total' ");

                $this->db->query("UPDATE ps_order SET total = '" . $calculate_total . "' WHERE order_id = '" . (int) $order_id . "'");

                $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $this->config->get('iyzico_checkout_form_order_status_id'), $message, false);

                $log->write($order_id . " Taksitli işlem için sipariş geçmişi eklendi");

                $comment = $response->getCardFamily() . ' - ' . $response->getInstallment() . '  Taksit';
                $this->db->query("INSERT INTO ps_order_history SET order_id = '" . (int) $order_id . "', order_status_id = '" .
                    $this->config->get('iyzico_checkout_form_order_status_id') . "', notify = '0', comment = '" .
                    $this->db->escape($comment) . "', date_added = NOW()");

                $log->write($order_id . " ps_order_history tablosuna kayıt girildi ");
            } else {
                $log->write($order_id . " Tek çekim için işlem başladı");
                $retres = $this->model_checkout_order->addOrderHistory($response_order_id, $this->config->get('iyzico_checkout_form_order_status_id'), $message, false);
                $log->write($order_id . " Tek çekim için sipariş geçmişi eklendi");
            }

            $item_transactions = $response->getPaymentItems();

            $log->write($order_id . " Iyzicodan işlem sonucu geldi aşağıdadır. ");
            $log->write($item_transactions);

            foreach ($item_transactions as $item_transaction) {
                $item_data_array = array(
                    'order_id' => $order_id,
                    'paid_price' => $item_transaction->getPaidPrice(),
                    'item_id' => $item_transaction->getItemId(),
                    'payment_transaction_id' => $item_transaction->getPaymentTransactionId(),
                    'total_refunded' => 0
                );
                $this->model_extension_payment_iyzico_checkout_form->createRefundItemEntry($item_data_array);
            }

            $log->write($order_id . " Success sayfasına yönleniyoruz ");
            $this->response->redirect($this->url->link('checkout/success', '', $server_conn_slug));

        } catch (\Exception $ex) {

            $log->write($order_id . " Catch bloğuna girildi ");

            $resp_msg = $ex->getMessage();

            $log->write($order_id . " resp_msg bilgisi aşağıdadır ");
            $log->write($resp_msg);

            $resp_msg = !empty($resp_msg) ? $resp_msg : $this->language->get('invalid_request');
            if (!empty($get_auth_table_id)) {
                $update_data_array = array(
                    'note' => $resp_msg . ' Callback',
                    'date_modified' => date('Y-m-d H:i:s'),
                );
                $this->model_extension_payment_iyzico_checkout_form->updateOrderEntry($update_data_array, $get_auth_table_id);
            }

            $this->session->data['error'] = $resp_msg;

            $this->session->data['iyzico_fail_message'] = $resp_msg;
            $log->write($order_id . " sorun oluştuğu için tekrar ödeme sayfanına yönleniyoruz " . $resp_msg);

            $this->response->redirect($this->url->link('checkout/checkout', '', $server_conn_slug));
        }

        $log->write($order_id . " try ve catch bloklarına girilemedi error sayfasına gidiyoruz ");

        $this->response->redirect($this->url->link('checkout/error', '', $server_conn_slug));
    }

    public function webhooks()
    {

        //https://www.deercase.com/index.php?route=extension/payment/iyzico_checkout_form/webhooks


        $param = array_merge($_POST, (array) json_decode(file_get_contents('php://input')));


        if($param){


            $paymentConversationId = explode('_', $param['paymentConversationId']);

            $order_id = $paymentConversationId[2];

            $log = new Log("iyzico_webhooks/". $order_id ."_IyzicoWebHookLog.txt");
            $log->write($param);

            $server_conn_slug = $this->getServerConnectionSlug();
            $this->load->language('extension/payment/iyzico_checkout_form');
            $this->load->model('extension/payment/iyzico_checkout_form');
            $this->load->model('checkout/order');
            $postData = $param;
            $message = '';
            $get_auth_table_id = 0;
            try {

                $save_data_array = array(
                    'order_id' => 0,
                    'transaction_status' => '',
                    'date_created' => date('Y-m-d H:i:s'),
                    'date_modified' => date('Y-m-d H:i:s'),
                    'api_request' => '',
                    'api_response' => json_encode($postData),
                    'request_type' => 'post_callback',
                    'processing_timestamp' => date('Y-m-d H:i:s'),
                    'note' => 'webhooks'
                );
                $post_callback_id = $this->model_extension_payment_iyzico_checkout_form->createOrderEntry($save_data_array);

                if (empty($postData['token'])) {
                    throw new \Exception($this->language->get('invalid_request'));
                }

                $this->load->model('extension/payment/iyzico_checkout_form');

                IyzipayBootstrap::init();

                $merchant_api_id = $this->config->get('iyzico_checkout_form_api_id_live');
                $merchant_secret_key = $this->config->get('iyzico_checkout_form_secret_key_live');

                $options = new \Iyzipay\Options();
                $options->setApiKey($merchant_api_id);
                $options->setSecretKey($merchant_secret_key);
                $options->setBaseUrl($this->base_url);

                $request = new \Iyzipay\Request\RetrieveCheckoutFormRequest();
                $request->setLocale(\Iyzipay\Model\Locale::TR);
                $request->setToken($postData['token']);

                $save_data_array = array(
                    'order_id' => 0,
                    'item_id' => 0,
                    'transaction_status' => 'in process',
                    'date_created' => date('Y-m-d H:i:s'),
                    'date_modified' => date('Y-m-d H:i:s'),
                    'api_request' => $request->toJsonString(),
                    'api_response' => '',
                    'request_type' => 'get_auth',
                    'note' => 'webhooks'
                );
                $get_auth_table_id = $this->model_extension_payment_iyzico_checkout_form->createOrderEntry($save_data_array);

                $response = \Iyzipay\Model\CheckoutForm::retrieve($request, $options);

                $update_data_array = array(
                    'date_modified' => date('Y-m-d H:i:s'),
                    'api_response' => $response->getRawResult(),
                    'transaction_status' => $response->getStatus(),
                    'processing_timestamp' => date('Y-m-d H:i:s', $response->getSystemTime() / 1000)
                );
                $this->model_extension_payment_iyzico_checkout_form->updateOrderEntry($update_data_array, $get_auth_table_id);


                if ($response->getStatus() == "failure") {
                    throw new \Exception($response->getErrorMessage());
                }

                if ($response->getPaymentStatus() == "FAILURE") {
                    throw new \Exception($response->getErrorMessage());
                }

                $basketId = $response->getBasketId();
                $paymentId = $response->getPaymentId();

                if (!empty($paymentId)) {
                    $message .= 'Payment ID: ' . $paymentId . "\n";
                }

                $explode_basket_id = explode("_", $basketId);
                $response_order_id = end($explode_basket_id);

                $update_data_array = array(
                    'order_id' => $response_order_id,
                    'date_modified' => date('Y-m-d H:i:s'),
                    'processing_timestamp' => date('Y-m-d H:i:s', $response->getSystemTime() / 1000)
                );

                $this->model_extension_payment_iyzico_checkout_form->updateOrderEntry($update_data_array, $get_auth_table_id);

                $this->model_extension_payment_iyzico_checkout_form->updateOrderEntry($update_data_array, $post_callback_id);

                if (empty($response_order_id) || $response_order_id != $order_id) {
                    throw new \Exception($this->language->get('invalid_order'));
                }

                $order_info = $this->model_checkout_order->getOrder($response_order_id);

                if (!empty($order_info['order_status_id']) && $order_info['order_status'] != null) {
                    throw new \Exception($this->language->get('order_already_exists'));
                }

                $installment = $response->getInstallment();
                if ($installment > 1) {

                    $this->load->model('checkout/order');
                    $order_total = (array) $this->db->query("SELECT * FROM ps_order_total WHERE order_id = '" . (int) $order_id . "' AND code = 'total' ");
                    $last_sort_value = $order_total['row']['sort_order'] - 1;
                    $exchange_rate = $this->currency->getValue($order_info['currency_code']);
                    $new_amount = str_replace(',', '', $response->getPaidPrice());
                    $old_amount = str_replace(',', '', $order_info['total'] * $order_info['currency_value']);
                    $installment_fee_variation = ($new_amount - $old_amount) / $exchange_rate;
                    $this->db->query("INSERT INTO ps_order_total SET order_id = '" .
                        (int) $order_id . "',code = '" . $this->db->escape('iyzico_checkout_form_fee') .
                        "',  title = '" . $this->db->escape($this->language->get('installment_charge')) . "' , `value` = '" .
                        (float) $installment_fee_variation . "', sort_order = '" . (int) $last_sort_value . "'");


                    $order_total_data = (array) $this->db->query("SELECT * FROM ps_order_total 
                                WHERE order_id = '" . (int) $order_id . "' 
                                AND code != 'total'
                                AND code != 'coupon'
                                AND code != 'campaign_price_total' ");
                    $calculate_total = 0;
                    foreach ($order_total_data['rows'] as $row) {
                        $calculate_total += $row['value'];
                    }


                    $this->db->query("UPDATE ps_order_total SET  `value` = '" . (float) $calculate_total . "' WHERE order_id = '$order_id' AND code = 'total' ");
                    $this->db->query("UPDATE ps_order SET total = '" . $calculate_total . "' WHERE order_id = '" . (int) $order_id . "'");
                    $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $this->config->get('iyzico_checkout_form_order_status_id'), $message, false);

                    $comment = $response->getCardFamily() . ' - ' . $response->getInstallment() . '  Taksit';
                    $this->db->query("INSERT INTO ps_order_history SET order_id = '" . (int) $order_id . "', order_status_id = '" .
                        $this->config->get('iyzico_checkout_form_order_status_id') . "', notify = '0', comment = '" .
                        $this->db->escape($comment) . "', date_added = NOW()");

                } else {
                    $this->model_checkout_order->addOrderHistory($response_order_id, $this->config->get('iyzico_checkout_form_order_status_id'), $message, false);
                }

                $item_transactions = $response->getPaymentItems();


                foreach ($item_transactions as $item_transaction) {
                    $item_data_array = array(
                        'order_id' => $order_id,
                        'paid_price' => $item_transaction->getPaidPrice(),
                        'item_id' => $item_transaction->getItemId(),
                        'payment_transaction_id' => $item_transaction->getPaymentTransactionId(),
                        'total_refunded' => 0
                    );
                    $this->model_extension_payment_iyzico_checkout_form->createRefundItemEntry($item_data_array);
                }

                $this->response->redirect($this->url->link('checkout/success', '', $server_conn_slug));

            } catch (\Exception $ex) {

                $resp_msg = $ex->getMessage();

                $resp_msg = !empty($resp_msg) ? $resp_msg : $this->language->get('invalid_request');
                if (!empty($get_auth_table_id)) {
                    $update_data_array = array(
                        'note' => $resp_msg . ' Webhooks',
                        'date_modified' => date('Y-m-d H:i:s'),
                    );
                    $this->model_extension_payment_iyzico_checkout_form->updateOrderEntry($update_data_array, $get_auth_table_id);
                }

                $this->session->data['error'] = $resp_msg;

                $this->response->redirect($this->url->link('checkout/checkout', '', $server_conn_slug));
            }


            $this->response->redirect($this->url->link('checkout/error', '', $server_conn_slug));


        }




        if (isset($this->request->server['HTTP_ORIGIN'])) {
            $this->response->addHeader('Access-Control-Allow-Origin: ' . $this->request->server['HTTP_ORIGIN']);
            $this->response->addHeader('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
            $this->response->addHeader('Access-Control-Max-Age: 1000');
            $this->response->addHeader('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
        }
        
    }

    public function error() {

        if(isset($this->session->data['order_id'])){
            $order_id = $this->session->data['order_id'];
            $log = new Log('iyzico/'.$order_id . "_IyzicoErrorPostDataLogs.txt");
            $log->write($order_id . " hataya düşmüş sipariş ");
        }else{
            $log = new Log('iyzico/'."_IyzicoErrorPostDataLogs.txt");
            $log->write("Hataya düşen işlem.");
        }


        $this->language->load('extension/payment/iyzico_checkout_form');
        $this->document->setTitle($this->language->get('heading_title'));
        $data['breadcrumbs'] = array();
        $data['breadcrumbs'][] = array(
            'text' => $this->language->get('text_home'),
            'href' => $this->url->link('common/home'),
            'separator' => false
        );

        if (isset($this->request->get['route'])) {
            $data = $this->request->get;
            unset($data['_route_']);
            $route = $data['route'];
            unset($data['route']);
            $url = '';
            if ($data) {
                $url = '&' . urldecode(http_build_query($data, '', '&'));
            }

            $connection = $this->getServerConnectionSlug();
            $data['breadcrumbs'][] = array(
                'text' => $this->language->get('heading_title'),
                'href' => $this->url->link($route, $url, $connection),
                'separator' => $this->language->get('text_separator')
            );
        }

        if (!empty($error['response']['state']) && $error['response']['state'] == 'failed') {
            $data['heading_title'] = "Payment error...";
            $data['text_error'] = $error['response']['error_message'];
        }

        if (VERSION >= '2.2.0.0'){
            $template_url = 'error/not_found.tpl';
        } else {
            $template_url = 'default/template/error/not_found.tpl';
        }

        $data['button_continue'] = $this->language->get('button_continue');
        $this->response->addHeader($this->request->server['SERVER_PROTOCOL'] . '/1.1 404 Not Found');
        $data['continue'] = $this->url->link('checkout/checkout');

        if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/error/not_found.tpl')) {
            $this->template = $this->config->get('config_template') . '/template/error/not_found.tpl';
        } else {
            $this->template = $template_url;
        }

        $this->children = array(
            'common/column_left',
            'common/column_right',
            'common/content_top',
            'common/content_bottom',
            'common/footer',
            'common/header'
        );

        if(file_exists(DIR_LOCAL_TEMPLATE . $this->config->get('theme_default_directory') .'/template/error/not_found.tpl')){
            $this->response->setOutput($this->load->view( DIR_LOCAL_TEMPLATE . $this->config->get('theme_default_directory') .'/template/error/not_found', $data));
        }else{
            $this->response->setOutput($this->load->view(DIR_TEMPLATE . 'default/template/error/not_found', $data));
        }


    }

    public function confirm() {

        $order_id = $this->session->data['order_id'];

        $log = new Log('iyzico/'.$order_id . "_IyzicoConfirmPostDataLogs.txt");

        $log->write($order_id . " confirm başladı ");

        $server_conn_slug = $this->getServerConnectionSlug();
        if ($this->session->data['payment_method']['code'] == 'iyzico_checkout_form') {
            if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {

                $this->load->model('checkout/order');
                $this->load->model('extension/payment/iyzico_checkout_form');
                $order_id = $this->session->data['order_id'];
                $order_info = $this->model_checkout_order->getOrder($order_id);

                if (!empty($order_info['order_status_id']) && $order_info['order_status'] != null) {
                    throw new \Exception($this->language->get('order_already_exists'));
                }

                $cart_total_amount = round($order_info['total'] * $order_info['currency_value'], 2);
                if ($cart_total_amount == 0) {
                    $save_data_array = array(
                        'order_id' => $order_id,
                        'item_id' => 0,
                        'transaction_status' => 'success',
                        'date_created' => date('Y-m-d H:i:s'),
                        'date_modified' => date('Y-m-d H:i:s'),
                        'processing_timestamp' => date('Y-m-d H:i:s'),
                        'api_request' => '',
                        'api_response' => '',
                        'request_type' => 'get_auth',
                        'note' => 'Confirm'
                    );
                    $this->model_extension_payment_iyzico_checkout_form->createOrderEntry($save_data_array);

                    $this->model_checkout_order->addOrderHistory($order_id, $this->config->get('iyzico_checkout_form_order_status_id'));

                    $log->write($save_data_array);

                    echo true;
                } else {
                    echo false;
                }
            } else {
                $server_conn_slug = $this->getServerConnectionSlug();
                $this->response->redirect($this->url->link('checkout/error', '', $server_conn_slug));
            }
        } else {
            $this->response->redirect($this->url->link('checkout/error', '', $server_conn_slug));
        }
        exit();
    }

    private function getCurrencyConstant($currencyCode){
        $currency = \Iyzipay\Model\Currency::TL;
        switch($currencyCode){
            case "TRY":
                $currency = \Iyzipay\Model\Currency::TL;
                break;
            case "USD":
                $currency = \Iyzipay\Model\Currency::USD;
                break;
            case "GBP":
                $currency = \Iyzipay\Model\Currency::GBP;
                break;
            case "EUR":
                $currency = \Iyzipay\Model\Currency::EUR;
                break;
            case "IRR":
                $currency = \Iyzipay\Model\Currency::IRR;
                break;
        }
        return $currency;
    }

    private function setcookieSameSite($name, $value, $expire, $path, $domain, $secure, $httponly) {

        if (PHP_VERSION_ID < 70300) {

            setcookie($name, $value, $expire, "$path; samesite=None", $domain, $secure, $httponly);
        }
        else {
            setcookie($name, $value, [
                'expires' => $expire,
                'path' => $path,
                'domain' => $domain,
                'samesite' => 'None',
                'secure' => $secure,
                'httponly' => $httponly,
            ]);


        }
    }

}
