<?php
/**
 * This file is part of osCommerce ecommerce platform.
 * osCommerce the ecommerce
 *
 * @link https://www.oscommerce.com
 * @copyright Copyright (c) 2000-2022 osCommerce LTD
 *
 * Released under the GNU General Public License
 * For the full copyright and license information, please view the LICENSE.TXT file that was distributed with this source code.
 */
///2do paymentintent option (preauth)

namespace common\modules\orderPayment;

require_once('lib/billdesk.php');
require_once('lib/Billdesk/vendor/autoload.php');
require_once('lib/Billdesk/logger.php');
require_once(DIR_WS_FUNCTIONS . 'html_output.php');

use common\classes\modules\ModulePayment;
use common\classes\modules\ModuleStatus;
use common\classes\modules\ModuleSortOrder;
use common\helpers\OrderPayment as OrderPaymentHelper;
use common\helpers\Html;
use io\billdesk\client\hmacsha256\BillDeskJWEHS256Client;
use io\billdesk\client\hmacsha256\JWESymmetricHelper;
use io\billdesk\client\hmacsha256\Config;
use Monolog\Logger;
use OscBillDeskLogger;


class billdesk extends ModulePayment
{
    //2do PaymentTokensInterface, \common\classes\modules\TransactionSearchInterface
    var $code, $title, $description, $enabled;
    var $paid_status, $public_title, $sort_order, $order_status, $order_id;
    private $debug = true;

    protected $encrypted_keys = ['MODULE_PAYMENT_BILLDESK_CHECKOUT_SECRET_KEY'];

    protected $defaultTranslationArray = [
        'MODULE_PAYMENT_BILLDESK_CHECKOUT_TEXT_TITLE' => 'BillDesk',
        'MODULE_PAYMENT_BILLDESK_CHECKOUT_TEXT_PUBLIC_TITLE' => 'BillDesk',
        'MODULE_PAYMENT_BILLDESK_CHECKOUT_TEXT_DESCRIPTION' => '<a href="https://www.billde.com" target="_blank" style="text-decoration: underline; font-weight: bold;">Visit BillDesk Website</a>',
    ];

    public function __construct()
    {
        error_log("billdesk extends ModulePayment");
        parent::__construct();
        $this->code = 'billdesk';
        $this->title = MODULE_PAYMENT_BILLDESK_CHECKOUT_TEXT_TITLE;
        $this->public_title = MODULE_PAYMENT_BILLDESK_CHECKOUT_TEXT_PUBLIC_TITLE;
        $this->description = MODULE_PAYMENT_BILLDESK_CHECKOUT_TEXT_DESCRIPTION;
        $this->sort_order = defined('MODULE_PAYMENT_BILLDESK_CHECKOUT_SORT_ORDER') ? MODULE_PAYMENT_BILLDESK_CHECKOUT_SORT_ORDER : 0;
        $this->enabled = defined('MODULE_PAYMENT_BILLDESK_CHECKOUT_STATUS') && (MODULE_PAYMENT_BILLDESK_CHECKOUT_STATUS == 'True') ? true : false;
        $this->order_status = defined('MODULE_PAYMENT_BILLDESK_CHECKOUT_ORDER_STATUS_ID') && ((int) MODULE_PAYMENT_BILLDESK_CHECKOUT_ORDER_STATUS_ID > 0) ? (int) MODULE_PAYMENT_BILLDESK_CHECKOUT_ORDER_STATUS_ID : 0;
        $this->paid_status = defined('MODULE_PAYMENT_BILLDESK_CHECKOUT_COMPLETED_ORDER_STATUS_ID') && ((int) MODULE_PAYMENT_BILLDESK_CHECKOUT_COMPLETED_ORDER_STATUS_ID > 0) ? (int) MODULE_PAYMENT_BILLDESK_CHECKOUT_COMPLETED_ORDER_STATUS_ID : 0;
        /* $dir = dirname(dirname(dirname(dirname(dirname(__FILE__)))));
        require($dir."/includes/version.php");  */

        if ($this->enabled === true) {
            $this->update_status();
        }
    }

    function update_status()
    {
        error_log("update_status");
        $this->enabled = true;

    }
    function javascript_validation()
    {
        error_log("javascript_validation");
        return false;
    }

    function selection()
    {
        error_log("selection");
        return array(
            'id' => $this->code,
            'module' => $this->title,
        );
    }

    function pre_confirmation_check()
    {
        error_log("pre_confirmation_check");

    }

    function confirmation()
    {
        error_log("confirmation");
        $confirmation = array(
            'fields' => array(
                array(
                    'title' => $this->title,
                )
            )
        );
        return $confirmation;

    }
    function process_button()
    {

        error_log("process_button");
        return false;
    }
    function before_process()
    {
        error_log("before_process");
        $log = OscBillDeskLogger::logger("Transaction_Responce");

        if (isset($_REQUEST['transaction_status'])) {
            error_log("transaction_status");
            $transaction_response = $_REQUEST['transaction_status'];
            $log->info("Response received: " . $transaction_response);
            if ($transaction_response == 111) {
                tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, 'error_message=' . stripslashes("Payment was cancelled by the user. "), 'SSL'));
            }
        }
        if (isset($_REQUEST['transaction_response'])) {
            $transaction_data = $_REQUEST['transaction_response'];

            $this->after_process();
            $this->manager->clearAfterProcess();
            exit();

        }
        $bdcreateOrder_response = $this->billdesk_createOrder_response();
        error_log("CreateOrder_response: " . json_encode($bdcreateOrder_response) . PHP_EOL, 0);
        if ($bdcreateOrder_response['status'] == "500" || $bdcreateOrder_response['status'] == "401" || $bdcreateOrder_response['status'] == "422") {

            tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, 'error_message=' . stripslashes($bdcreateOrder_response['error_code']) . "\t\t " . ": " . stripslashes($bdcreateOrder_response['message']), 'SSL'));

        }
        $return_resp_url = tep_href_link('lib/common/modules/orderPayment/lib/Billdesk/response_billdesk.php', '', 'SSL');
        error_log("Return_resp_url: " . $return_resp_url . PHP_EOL, 0);

        $params = [];
        $params['order_id'] = $this->estimateOrderId();
        error_log("getCheckoutUrl order_id : " . $params['order_id'] . PHP_EOL, 0);
        //$newUrl = $this->getCheckoutUrl($params, self::PROCESS_PAGE);
        $newUrl = $this->getCheckoutUrl([], self::PROCESS_PAGE);

        ?>

        <script src="https://code.jquery.com/jquery-latest.min.js"></script>
        <?php
        error_log("MODULE_PAYMENT_BILLDESK_CHECKOUT_ENVIRONMENT: " . MODULE_PAYMENT_BILLDESK_CHECKOUT_ENVIRONMENT);
        if (MODULE_PAYMENT_BILLDESK_CHECKOUT_ENVIRONMENT == "UAT") { ?>
            <script type="module" src="https://uat1.billdesk.com/merchant-uat/sdk/dist/billdesksdk/billdesksdk.esm.js"
                src_type="url"></script>
            <script nomodule="" src="https://uat1.billdesk.com/merchant-uat/sdk/dist/billdesksdk/billdesksdk.js" src_type="url"></script>
            <link rel="stylesheet" href="https://uat1.billdesk.com/merchant-uat/sdk/dist/billdesksdk/billdesksdk.css" />

        <?php } else { ?>
            <script type="module" src="https://pay.billdesk.com/jssdk/v1/dist/billdesksdk/billdesksdk.esm.js"
                src_type="url"></script>
            <script nomodule="" src="https://pay.billdesk.com/jssdk/v1/dist/billdesksdk/billdesksdk.js" src_type="url"></script>
            <link rel="stylesheet" href="https://pay.billdesk.com/jssdk/v1/dist/billdesksdk/billdesksdk.css" />

        <?php } ?>
        <script type="text/javascript">
            jQuery(document).ready(function () {
                executed = true;
                var mercid = '<?php echo $bdcreateOrder_response['mercid'] ?>';
                var flowtype = "payments";

                const flowConfig = {
                    merchantId: '<?php echo $bdcreateOrder_response['mercid'] ?>',
                    bdOrderId: '<?php echo $bdcreateOrder_response['bdorderid'] ?>',
                    authToken: '<?php echo $bdcreateOrder_response['links'][1]['headers']['authorization'] ?>',
                }
                var childwindow = '<?php echo MODULE_PAYMENT_BILLDESK_CHECKOUT_UPDATE_CHILD_WINDOW ?>';
                var retrycount = '<?php echo MODULE_PAYMENT_BILLDESK_CHECKOUT_RETRY_COUNT ?>';
                var payment_category = '<?php echo MODULE_PAYMENT_BILLDESK_CHECKOUT_PAYMENT_CATEGORIES ?>';
                var env = '<?php echo MODULE_PAYMENT_BILLDESK_CHECKOUT_ENVIRONMENT ?>';

                var redirectUrl = '<?php echo $newUrl; ?>';
                console.log("RedirectUrl: ", redirectUrl);

                if (childwindow == "True") {
                    flowConfig.childWindow = true;
                } else {
                    flowConfig.childWindow = false;
                }
                flowConfig.retryCount = Number(retrycount);
                console.log("Flowconfig: ", flowConfig);

                var onSdkModalClosed = function (response) {
                    console.log("Transaction response: ", response);

                    if (response.status === 111) {
                        const form = document.createElement('form');
                        form.method = 'POST';
                        form.action = redirectUrl;
                        const hiddenField = document.createElement('input');
                        hiddenField.type = 'hidden';
                        hiddenField.name = 'transaction_status';
                        hiddenField.value = response.status;
                        form.appendChild(hiddenField);

                        document.body.appendChild(form);
                        form.submit();
                    } else {
                        console.log("Inside Else: ");
                        console.log("SDK Modal closed: ", response);
                        const form = document.createElement('form');
                        form.method = 'POST';
                        form.action = redirectUrl;
                        const hiddenField = document.createElement('input');
                        hiddenField.type = 'hidden';
                        hiddenField.name = 'transaction_response';

                        console.log('Terminal state from response: ', response.txnResponse.terminal_state);
                        console.log('Transation response from response: ', response.txnResponse.transaction_response);

                        hiddenField.value = response.txnResponse.transaction_response;

                        form.appendChild(hiddenField);

                        document.body.appendChild(form);
                        form.submit();

                        return true;
                    }
                }

                var sdkConfig = {
                    responseHandler: onSdkModalClosed,
                    merchantLogo: '<?php echo MODULE_PAYMENT_BILLDESK_CHECKOUT_LOGO ?>',
                    flowConfig: flowConfig,
                    flowType: flowtype,
                }
                console.log("env", env);

                if ('<?php echo MODULE_PAYMENT_BILLDESK_CHECKOUT_ENVIRONMENT ?>' == 'UAT') {
                    var script = document.createElement('script');
                    script.type = "module";
                    script.src = 'https://uat1.billdesk.com/merchant-uat/sdk/dist/billdesksdk/billdesksdk.esm.js';
                    document.body.appendChild(script);

                    var script1 = document.createElement('script');
                    script1.nomodule = "";
                    script1.src = 'https://uat1.billdesk.com/merchant-uat/sdk/dist/billdesksdk/billdesksdk.js';
                    document.body.appendChild(script1);

                    var head = document.getElementsByTagName('HEAD')[0];
                    var link = document.createElement('link');
                    link.rel = 'stylesheet';
                    link.type = 'text/css';
                    link.href = 'https://uat1.billdesk.com/merchant-uat/sdk/dist/billdesksdk/billdesksdk.css';
                    head.appendChild(link);
                } else {
                    var script = document.createElement('script');
                    script.type = "module";
                    script.src = 'https://pay.billdesk.com/jssdk/v1/dist/billdesksdk/billdesksdk.esm.js';
                    document.body.appendChild(script);

                    var script1 = document.createElement('script');
                    script1.nomodule = "";
                    script1.src = 'https://pay.billdesk.com/jssdk/v1/dist/billdesksdk/billdesksdk.js';
                    document.body.appendChild(script1);

                    var head = document.getElementsByTagName('HEAD')[0];
                    var link = document.createElement('link');
                    link.rel = 'stylesheet';
                    link.type = 'text/css';
                    link.href = 'https://pay.billdesk.com/jssdk/v1/dist/billdesksdk/billdesksdk.css';
                    head.appendChild(link);
                }
                console.log("SDK config: ", sdkConfig);
                //loadBillDeskSdk(sdkConfig);
                function sleep(ms) {
                    return new Promise(resolve => setTimeout(resolve, ms));
                }
                sleep(1000).then(() => {
                    loadBillDeskSdk(sdkConfig);
                });
            })
        </script>
        <?php
    }

   

        function billdesk_createOrder_response()
        {
        $log = OscBillDeskLogger::logger("BillDesk Create order");

        // Get order & environment data
        $order = $this->manager->getOrderInstance();
        $orderId = $this->estimateOrderId();
        $currency_code = $order->info['currency'];
        $amount = (float) $order->info['total'];
        $userAgent = $_SERVER['HTTP_USER_AGENT'];
        $ip = getenv('HTTP_CLIENT_IP') ?:
            getenv('HTTP_X_FORWARDED_FOR') ?:
            getenv('HTTP_X_FORWARDED') ?:
            getenv('HTTP_FORWARDED_FOR') ?:
            getenv('HTTP_FORWARDED') ?:
            getenv('REMOTE_ADDR');
        $ipaddress = strtok($ip, ",");

        // Currency mapping
        $currencyMap = [
            'INR' => '356', 'USD' => '840', 'EUR' => '978',
            'JPY' => '392', 'AUD' => '036', 'HKD' => '344',
            'MYR' => '458', 'SGD' => '702', 'NZD' => '554'
        ];
        $currency = $currencyMap[$currency_code] ?? '356';

        // Return URL
        $returnUrl = (MODULE_PAYMENT_BILLDESK_CHECKOUT_UPDATE_CHILD_WINDOW === "True")
            ? tep_href_link('lib/common/modules/orderPayment/lib/Billdesk/autoclose.php', '', 'SSL')
            : $this->getCheckoutUrl([], self::PROCESS_PAGE);

        // Plugin version info
        $bd_platform = 'platform,oscommerce_' . PROJECT_VERSION_MAJOR . PROJECT_VERSION_MINOR . PROJECT_VERSION_PATCH;
        $bd_version = "pluginv,1.0.4";

        $log->debug("osccommerce_version: $bd_platform");
        $log->debug("bd_version: $bd_version");
        $log->debug("Initializing Config object for BillDesk");

        // Load config values
      // Sanitize config values from constants (trim + safe fallback)
        $merchantId          = trim((string)MODULE_PAYMENT_BILLDESK_CHECKOUT_MERCHANT_ID);
        $itemCode            = trim((string)MODULE_PAYMENT_BILLDESK_CHECKOUT_ITEM_CODE);
        $clientId            = trim((string)MODULE_PAYMENT_BILLDESK_CHECKOUT_CLIENT_ID);
        $signingKeyId        = "AES_DIR";
        $encryptionKeyId     = trim((string)MODULE_PAYMENT_BILLDESK_CHECKOUT_KEY_ID);//"HMAC";

        // Do not use sanitize_text_field() — not available in osCommerce
        // Instead, trim and validate base64 manually
        $signingKeyBase64    = trim((string)MODULE_PAYMENT_BILLDESK_JOSE_SIGNING_KEY);
        $encryptionKeyBase64 = trim((string)MODULE_PAYMENT_BILLDESK_JOSE_ENCRYPTION_KEY);

        // Basic base64 validation
        function is_valid_base64($str) {
            $decoded = base64_decode($str, true);
            return $decoded !== false && base64_encode($decoded) === $str;
        }

        // Log identifiers
        $log->debug("Merchant ID: " . substr($merchantId, 0, 6) . "...");
        $log->debug("Client ID: " . substr($clientId, 0, 6) . "...");
        $log->debug("Signing Key ID: $signingKeyId");
        $log->debug("Encryption Key ID: $encryptionKeyId");

        // Log key lengths only if valid
        if (is_valid_base64($signingKeyBase64)) {
            $log->debug("Decoded signing key length: " . strlen(base64_decode($signingKeyBase64)));
        } else {
            $log->error("Signing key is not valid base64");
        }

        if (is_valid_base64($encryptionKeyBase64)) {
            $log->debug("Decoded encryption key length: " . strlen(base64_decode($encryptionKeyBase64)));
        } else {
            $log->error("Encryption key is not valid base64");
        }

        // Setup config
        try {
            $config = new Config();
            $config->setMerchantId($merchantId);
            $config->setClientId($clientId);
            $config->setEncryptionKeyBase64($encryptionKeyBase64);
            $config->setSigningKeyBase64($signingKeyBase64);
            $config->setEncryptionKeyId($encryptionKeyId);
            $config->setSigningKeyId($signingKeyId);


            $log->debug("Config object initialized");
        } catch (\Throwable $e) {
            $log->error("Error in config setup: " . $e->getMessage());
            return [
                "status" => "500",
                "message" => "Failed during config setup",
                "error_code" => $e->getMessage()
            ];
        }

        // Initialize client
        try {
            $endpoint = (MODULE_PAYMENT_BILLDESK_CHECKOUT_ENVIRONMENT === 'UAT')
                ? "https://uat1.billdesk.com/u2"
                : "https://api.billdesk.com";

            $log->debug("About to instantiate BillDeskJWEHS256Client");
            $client = new BillDeskJWEHS256Client($config, $endpoint);
            $client->setLogger($log);
            
            $log->debug("Client initialized with endpoint: $endpoint");
        } catch (\Throwable $e) {
            $log->error("Throwable during client initialization: " . $e->getMessage());
            return [
                "status" => "500",
                "message" => "BillDesk client init failed",
                "error_code" => $e->getMessage()
            ];
        }

        // Build and send createOrder request
        try {
            $request = [
                'mercid' => $merchantId,
                'orderid' => uniqid(),
                'amount' => $amount,
                'order_date' => (new \DateTime())->format(DATE_W3C),
                'currency' => $currency,
                'ru' => $returnUrl,
                'itemcode' => $itemCode,
                'device' => [
                    'init_channel' => 'internet',
                    'ip' => $ipaddress,
                    'user_agent' => $userAgent,
                ],
                'additional_info' => [
                    'additional_info1' => $orderId,
                    'additional_info7' => "$bd_platform-$bd_version",
                ]
            ];

            $log->debug("Sending createOrder request", ['request' => $request]);

                $response = $client->createOrder($request);
                $results = $response->getResponse();  // raw object/array returned from SDK

                $log->info("Create order response received", ['response' => $results]);

                return is_array($results) ? $results : json_decode(json_encode($results), true);


            //return $res;
        } catch (Exception $exp) {
                $log->error("Failed to create order: " . $exp->getMessage());
                print("Failed to create order: " . $exp->getMessage());
                return true;
        }
    }




    function after_process()
    {
        $log = OscBillDeskLogger::logger("Transaction_Responce");
        $customer_id = $this->manager->getCustomerAssigned();
        error_log(" customer_id : " . $customer_id . PHP_EOL, 0);
        $query_order = tep_db_query("SELECT orders_id FROM " . TABLE_ORDERS . " WHERE customers_id = " . intval($customer_id) . " ORDER BY orders_id DESC LIMIT 1");
        $orderid = tep_db_fetch_array($query_order);
        $order_id = $orderid['orders_id'];
        error_log("order : " . $order_id . PHP_EOL, 0);
        $transaction_response = $_REQUEST['transaction_response'];
        $deferred = 0;
        error_log("transaction response : " . $transaction_response . PHP_EOL, 0);
       
        $client_id            = MODULE_PAYMENT_BILLDESK_CHECKOUT_CLIENT_ID;
        $encryption_key_base64 = MODULE_PAYMENT_BILLDESK_JOSE_ENCRYPTION_KEY;
        $signing_key_base64    = MODULE_PAYMENT_BILLDESK_JOSE_SIGNING_KEY;
        $encryption_key_id     = MODULE_PAYMENT_BILLDESK_CHECKOUT_KEY_ID;
        $signing_key_id        = "AES_DIR";

        // Optional: Log key lengths or masked keys
        $log->debug("Client ID: $client_id");
        $log->debug("Encryption Key ID: $encryption_key_id");
        $log->debug("Signing Key ID: $signing_key_id");

        // Instantiate the JOSE helper using Woo-style constructor
        $client = new JWESymmetricHelper(
            $encryption_key_base64,
            $client_id,
            $encryption_key_id,
            $log, // assuming you're using a PSR-3 compatible logger
            $signing_key_base64,
            $signing_key_id
        );

        // Capture and decrypt transaction response
        $log->debug("Raw transaction_response: $transaction_response");
        $jws = $client->verifyAndDecrypt($transaction_response);

        // Decode the payload (either as object or array)
        $txn = json_decode($jws, true);
        $log->debug("Decoded transaction: " . print_r($txn, true));

        $oscorderid = $txn['additional_info']['additional_info1'];
        $txnAmount  = $txn['amount'];
        $order = $this->manager->getOrderInstance();
        $orderAmount = $order->info['total_inc_tax'] ;
        $txnAmount  = number_format((float)$txnAmount, 2, '.', '');
        $orderAmount = number_format((float)$order->info['total_inc_tax'], 2, '.', '');
        error_log("oID order : " . json_encode($order) . PHP_EOL, 0);

         $txnAmount = number_format((float)$txnAmount, 2, '.', '');
        $orderAmount = number_format((float)$order->info['total_inc_tax'], 2, '.', '');

        error_log("Normalized txnAmount: $txnAmount");
        error_log("Normalized orderAmount: $orderAmount");
        error_log("order_id: $order_id | oscorderid: $oscorderid");

        if ((string)$order_id === (string)$oscorderid && $txnAmount === $orderAmount) {
            error_log("Condition passed. Proceeding with payment success logic...");
           if ($txn['auth_status'] === '0300') {
                $this->order_status = $this->paidOrderStatus();

                $sql_data_array = array(
                    'payment_id' => '',
                    'order_id' => $order_id,
                    'billdesk_order_id' => $txn['orderid'],
                    'transaction_id' => $txn['transactionid'],
                    'transaction_date' => $txn['transaction_date'],
                    'currency' => $txn['currency'],
                    'amount' => $txn['amount'],
                    't_status' => $txn['transaction_error_desc'],
                );
                tep_db_perform('payment_billdesk', $sql_data_array);

                $invoiceId = $order_id . '-e-' . date('ymdHis');
                error_log("invoiceId : " . $invoiceId . PHP_EOL, 0);

                $comment = 'Customer\'s payment ' . $order->info['currency'] . $txn['amount'] . ", Transaction Id: " . $txn['transactionid'];
                $order_status = MODULE_PAYMENT_BILLDESK_CHECKOUT_COMPLETED_ORDER_STATUS_ID;
                error_log("BILLDESK order_status : " . $order_status . PHP_EOL, 0);

                \common\helpers\Order::setStatus($oscorderid, (int) $order_status, [
                    'customer_notified' => 0,
                ]);

                $order->update_piad_information(true);
                $order->save_details();

                $statusCode = OrderPaymentHelper::OPYS_SUCCESSFUL;
                $tm = $this->manager->getTransactionManager($this);
                error_log("Afer TM : " . json_encode($txn) . PHP_EOL, 0);

                $ret = $tm->updatePaymentTransaction(
                    $txn['transactionid'],
                    [
                        'fulljson' => json_encode($txn),
                        'status_code' => $statusCode,
                        'status' => $order_status,
                        'amount' => $txn['amount'],
                        'comments' => $comment,
                        'date' => date('Y-m-d H:i:s'),
                        'suborder_id' => $invoiceId,
                        'orders_id' => $oscorderid,
                        'deferred' => $deferred,
                    ]
                );

                parent::updatePaidTotalsAndNotify();

                $sql_data_array = array(
                    'orders_id' => $oscorderid,
                    'orders_status_id' => $order_status,
                    'date_added' => 'now()',
                    'customer_notified' => '0',
                    'comments' => $comment
                );
                error_log("SQL ARRAY : " . json_encode($sql_data_array) . PHP_EOL, 0);

                tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);

                error_log("Payment Successful Before Process : " . $txn['auth_status'] . PHP_EOL, 0);
                tep_redirect(tep_href_link(FILENAME_CHECKOUT_SUCCESS, 'order_id=' . $oscorderid, 'SSL'));

            } else if ($txn['auth_status'] === '0399') {
                $log->info("failure_reason : " . $txn['transaction_error_desc']);
                tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, 'error_message=' . stripslashes($txn['transaction_error_desc']), 'SSL'));
            }

        } else
            tep_redirect(tep_href_link(FILENAME_SHOPPING_CART, 'error_message=' . stripslashes("Mismatch between Purchase Order and Amount Causes Receiving Transaction Error"), 'SSL'));

    }

    function isPartlyPaid()
    {
        $billdesk_session = $this->manager->get('billdesk_session');
        return (parent::isPartlyPaid() || $billdesk_session['pay_order_id'] > 0);
    }

    function getCheckoutUrl(array $params, int $checkoutPage = 0)
    {
        $billdesk_session = $this->manager->get('billdesk_session');
        if (!isset($params['order_id']) && $billdesk_session['pay_order_id'] > 0) {
            $params['order_id'] = $billdesk_session['pay_order_id'];
            error_log("getCheckoutUrl order_id : " . $params['order_id'] . PHP_EOL, 0);

        }
        return parent::getCheckoutUrl($params, $checkoutPage);
    }

    function describe_status_key()
    {
        return new ModuleStatus('MODULE_PAYMENT_BILLDESK_CHECKOUT_STATUS', 'True', 'False');
    }

    function describe_sort_key()
    {
        return new ModuleSortOrder('MODULE_PAYMENT_BILLDESK_CHECKOUT_SORT_ORDER');
    }

    function configure_keys()
    {
        $status_id_b = defined('MODULE_PAYMENT_BILLDESK_CHECKOUT_ORDER_STATUS_ID') ? MODULE_PAYMENT_BILLDESK_CHECKOUT_ORDER_STATUS_ID : $this->getDefaultOrderStatusId();
        $status_id_s = defined('MODULE_PAYMENT_BILLDESK_CHECKOUT_COMPLETED_ORDER_STATUS_ID') ? MODULE_PAYMENT_BILLDESK_CHECKOUT_COMPLETED_ORDER_STATUS_ID : $this->getDefaultOrderStatusId();
        $status_id_c = defined('MODULE_PAYMENT_BILLDESK_CHECKOUT_CANCELLED_ORDER_STATUS_ID') ? MODULE_PAYMENT_BILLDESK_CHECKOUT_CANCELLED_ORDER_STATUS_ID : $this->getDefaultOrderStatusId();
        $params = array(
            'MODULE_PAYMENT_BILLDESK_CHECKOUT_STATUS' => array(
                'title' => 'Enable BillDesk Module',
                'description' => 'Do you want to accept BillDesk payments?',
                'value' => 'True',
                'set_function' => 'tep_cfg_select_option(array(\'True\', \'False\'), '
            ),

            'MODULE_PAYMENT_BILLDESK_CHECKOUT_UPDATE_CHILD_WINDOW' => array(
                'title' => 'Child Window',
                'value' => 'False',
                'description' => 'Enable or disable child window.',
                'set_function' => 'tep_cfg_select_option(array(\'True\', \'False\'), ',
            ),
            'MODULE_PAYMENT_BILLDESK_CHECKOUT_MERCHANT_ID' => array(
                'title' => 'Merchant Id *',
                'description' => 'Enter The Billdesk Merchant id to use.',
                'value' => ''
            ),
           'MODULE_PAYMENT_BILLDESK_CHECKOUT_CLIENT_ID' => array(
                'title' => 'Client Id *',
                'description' => 'Enter The Billdesk Client Id to use.',
                'value' => ''
            ),
            'MODULE_PAYMENT_BILLDESK_CHECKOUT_KEY_ID' => array(
                'title' => 'Key Id *',
                'description' => 'Enter The Billdesk Key Id to use.',
                'value' => ''
            ), 
         'MODULE_PAYMENT_BILLDESK_JOSE_ENCRYPTION_KEY' => array(
             'title' => 'Encryption Password*',
             'description' => 'Enter the base64-encoded AES encryption key.',
             'value' => '',
         ),
         'MODULE_PAYMENT_BILLDESK_JOSE_SIGNING_KEY' => array(
             'title' => 'Signing Password*',
             'description' => 'Enter the base64-encoded HMAC signing key.',
             'value' => '',
         ),


            'MODULE_PAYMENT_BILLDESK_CHECKOUT_ITEM_CODE' => array(
                'title' => 'Item Code',
                'description' => 'Enter The Billdesk Item Code to use.',
                'value' => ''
            ),
            'MODULE_PAYMENT_BILLDESK_CHECKOUT_LOGO' => array(
                'title' => 'Merchant Logo',
                'description' => 'Enter The Billdesk Logo to use.',
                'value' => ''
            ),
            'MODULE_PAYMENT_BILLDESK_CHECKOUT_PAYMENT_CATEGORIES' => array(
                'title' => 'Payment Categories',
                'description' => 'Enter The Billdesk Payment Categories to use.',
                'value' => ''
            ),
            'MODULE_PAYMENT_BILLDESK_CHECKOUT_RETRY_COUNT' => array(
                'title' => 'Retry Count',
                'description' => 'Enter The Billdesk Retry Count to use.',
                'value' => ''
            ),
            'MODULE_PAYMENT_BILLDESK_CHECKOUT_ENVIRONMENT' => array(
                'title' => 'Environment',
                'description' => 'Select The Billdesk Environment to use',
                'value' => 'UAT',
                'set_function' => 'multiOption(\'dropdown\', array(\'UAT\', \'PROD\'), '
            ),
            'MODULE_PAYMENT_BILLDESK_CHECKOUT_ORDER_STATUS_ID' => array(
                'title' => 'Set Order Status Before Payment',
                'description' => 'Set the status of orders before redirect to Gateway',
                'value' => $status_id_b,
                'use_function' => '\\common\\helpers\\Order::get_order_status_name',
                'set_function' => 'tep_cfg_pull_down_order_statuses('
            ),
            'MODULE_PAYMENT_BILLDESK_CHECKOUT_COMPLETED_ORDER_STATUS_ID' => array(
                'title' => 'Set Order Status Completed Payment',
                'description' => 'Set the status of orders completed successfully',
                'value' => $status_id_s,
                'set_function' => 'tep_cfg_pull_down_order_statuses(',
                'use_function' => '\\common\\helpers\\Order::get_order_status_name'
            ),
            'MODULE_PAYMENT_BILLDESK_CHECKOUT_CANCELLED_ORDER_STATUS_ID' => array(
                'title' => 'Set Order Status Cancelled Payment',
                'description' => 'Set the status of orders cancelled',
                'value' => $status_id_c,
                'set_function' => 'tep_cfg_pull_down_order_statuses(',
                'use_function' => '\\common\\helpers\\Order::get_order_status_name'
            ),
            'MODULE_PAYMENT_BILLDESK_CHECKOUT_UPDATE_STOCK_BEFORE_PAYMENT' => array(
                'title' => 'Update Stock Before Payment',
                'value' => 'False',
                'description' => 'Should Products Stock be updated even when the payment is not yet COMPLETED?',
                'set_function' => 'tep_cfg_select_option(array(\'True\', \'False\'), ',
            ),
            'MODULE_PAYMENT_BILLDESK_ZONE' => array(
                'title' => 'Payment Zone',
                'value' => '0',
                'description' => 'If a zone is selected, only enable this payment method for that zone.',
                'sort_order' => '25',
                'use_function' => '\\common\\helpers\\Zones::get_zone_class_title',
                'set_function' => 'tep_cfg_pull_down_zone_classes(',
            ),
            'MODULE_PAYMENT_BILLDESK_CHECKOUT_DEBUG_EMAIL' => array(
                'title' => 'Debug E-Mail Address',
                'description' => 'All parameters of an invalid transaction will be sent to this email address.'
            ),
            'MODULE_PAYMENT_BILLDESK_CHECKOUT_SORT_ORDER' => array(
                'title' => 'Sort order of display.',
                'description' => 'Sort order of display. Lowest is displayed first.',
                'value' => '0'
            ),
        );
       return $params;
    }

    function install($platform_id)
    {
        tep_db_query("CREATE TABLE IF NOT EXISTS `payment_billdesk` (              
            `payment_id` int NOT NULL AUTO_INCREMENT,
             `order_id` varchar(30) DEFAULT NULL,
             `billdesk_order_id` varchar(30) DEFAULT NULL,
             `transaction_id` varchar(40) DEFAULT NULL,
             `transaction_date` varchar(255) DEFAULT NULL,
             `currency` varchar(20) DEFAULT NULL,
             `amount` varchar(100) DEFAULT NULL,
             `t_status` varchar(40) NOT NULL DEFAULT '1',
             PRIMARY KEY (`payment_id`)
           ) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
        return parent::install($platform_id);

    }

    function getSubmitCheckoutJavascript()
    {
        $order = $this->manager->getOrderInstance();
        return $order;
    }

    function isOnline()
    {
        return true;
    }


}
