<?php
/*
 * Plugin Name: Платёжный плагин TXPG
 * Plugin URI: https://compassplus.com
 * Description: Оплата картамы через TXPG
 * Author: Sergey Ivanov
 * Author URI: https://compassplus.com
 * Version: 1.0.0
 * Text Domain: txpg-gateway
 * Domain Path: /languages
 *
*/

add_action('plugins_loaded', 'txpg_gateway_class');

function txpg_gateway_class()
{
    class WC_Txpg_Gateway extends WC_Payment_Gateway
    {
        /**
         * Logger instance
         *
         * @var WC_Logger
         */
        private $log;

        /**
         * Test mode enabled
         *
         * @var bool
         */
        public $testmode;

        /**
         * HPP URL for API requests
         *
         * @var string
         */
        public $hpp_url;

        /**
         * Order type for TXPG
         *
         * @var string
         */
        public $order_type;

        /**
         * Publishable key for TXPG
         *
         * @var string
         */
        public $publishable_key;

        /**
         * Login owner type for HPP
         *
         * @var string
         */
        public $hpp_login_owner_type;

        /**
         * Login name for HPP
         *
         * @var string
         */
        public $hpp_login_name;

        /**
         * Password for HPP
         *
         * @var string
         */
        public $hpp_password;

        /**
         * Test login owner type for HPP
         *
         * @var string
         */
        public $test_hpp_login_owner_type;

        /**
         * Test login name for HPP
         *
         * @var string
         */
        public $test_hpp_login_name;

        /**
         * Test password for HPP
         *
         * @var string
         */
        public $test_hpp_password;

        public function __construct()
        {
            $this->id = 'txpg';
            $this->icon = '';
            $this->has_fields = true;
            $this->method_title = __('Платёжный шлюз TXPG', 'txpg-gateway');
            $this->method_description = __('Оплата с помощью TXPG', 'txpg-gateway');

            $this->supports = array(
                'products',
                'refunds'
            );

            $this->init_form_fields();

            $this->init_settings();
            $this->title = $this->get_option('title');
            $this->description = $this->get_option('description');
            $this->enabled = $this->get_option('enabled');
            $this->testmode = 'yes' === $this->get_option('testmode');
            $this->hpp_url = $this->testmode ? $this->get_option('hpp_url') : $this->get_option('hpp_url');
            $this->order_type = $this->get_option('order_type');
            $this->publishable_key = $this->testmode ? $this->get_option('test_publishable_key') : $this->get_option('publishable_key');

            $this->hpp_login_owner_type = $this->testmode ? $this->get_option('hpp_login_owner_type') : $this->get_option('hpp_login_owner_type');
            $this->hpp_login_name = $this->testmode ? $this->get_option('hpp_login_name') : $this->get_option('hpp_login_name');
            $this->hpp_password = $this->testmode ? $this->get_option('hpp_password') : $this->get_option('hpp_password');

            $this->test_hpp_login_owner_type = $this->testmode ? $this->get_option('test_hpp_login_owner_type') : $this->get_option('test_hpp_login_owner_type');
            $this->test_hpp_login_name = $this->testmode ? $this->get_option('test_hpp_login_name') : $this->get_option('test_hpp_login_name');
            $this->test_hpp_password = $this->testmode ? $this->get_option('test_hpp_password') : $this->get_option('test_hpp_password');

            $this->init();

            add_filter('woocommerce_order_data_store_cpt_get_orders_query', 'handle_order_txpg_id', 10, 2);
            add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
            add_action('woocommerce_api_txpg_handler', array($this, 'txpg_webhook'));
            // Removed capture_payment hooks to fix fatal error
            // add_action('woocommerce_order_status_processing', array($this, 'capture_payment'));
            // add_action('woocommerce_order_status_completed', array($this, 'capture_payment'));
        }

        public function init_form_fields()
        {
            $this->form_fields = array(
                'enabled' => array(
                    'title' => __('Включен/Выключен', 'woocommerce'),
                    'label' => __('Включить', 'woocommerce'),
                    'type' => 'checkbox',
                    'description' => '',
                    'default' => 'no'
                ),
                'title' => array(
                    'title' => __('Заголовок', 'woocommerce'),
                    'type' => 'text',
                    'description' => __('Это то, что пользователь увидит как название метода оплаты на странице оформления заказа', 'txpg-gateway'),
                    'default' => __('Оплатить картой', 'txpg-gateway'),
                    'desc_tip' => true,
                ),
                'description' => array(
                    'title' => __('Описание'),
                    'type' => 'textarea',
                    'description' => __('Описание этого метода оплаты, которое будет отображаться пользователю на странице оформления заказа', 'txpg-gateway'),
                    'default' => __('Оплатите при помощи карты легко и быстро', 'txpg-gateway'),
                ),
                'testmode' => array(
                    'title' => __('Тестовый режим', 'txpg-gateway'),
                    'label' => __('Включить тестовый режим', 'txpg-gateway'),
                    'type' => 'checkbox',
                    'description' => __('Хотите сначала протестировать с тестовыми ключами API?', 'txpg-gateway'),
                    'default' => 'yes',
                    'desc_tip' => true,
                ),
                'hpp_url' => array(
                    'title' => 'Url',
                    'type' => 'url'
                ),
                'order_type' => array(
                    'title' => __('Тип ордера', 'txpg-gateway'),
                    'type' => 'text'
                ),
                'hpp_login_owner_type' => array(
                    'title' => __('Тип логина', 'txpg-gateway'),
                    'type' => 'select',
                    'default' => 'TerminalSys',
                    'options' => array(
                        'TerminalSys' => 'TerminalSys'
                    )
                ),
                'hpp_login_name' => array(
                    'title' => __('Логин', 'woocommerce'),
                    'type' => 'text'
                ),
                'hpp_password' => array(
                    'title' => __('Пароль', 'woocommerce'),
                    'type' => 'password'
                ),
                'test_hpp_login_owner_type' => array(
                    'title' => __('Тестовый тип логина', 'txpg-gateway'),
                    'type' => 'select',
                    'default' => 'TerminalSys',
                    'options' => array(
                        'TerminalSys' => 'TerminalSys'
                    )
                ),
                'test_hpp_login_name' => array(
                    'title' => __('Тестовый логин', 'txpg-gateway'),
                    'type' => 'text'
                ),
                'test_hpp_password' => array(
                    'title' => __('Тестовый пароль', 'txpg-gateway'),
                    'type' => 'password'
                )
            );
        }

        /**
         * Process payment for an order
         *
         * @param int $order_id Order ID
         * @return array|void
         */
        public function process_payment($order_id)
        {
            $this->init();
            $order = wc_get_order($order_id);

            /** @var \OpenAPI\Client\Model\CreateOrderRequest $create_order_request_body Запрос создания ордера */
            $create_order_request_body = $this->prepareCreateOrderRequest($order);
            if (!$create_order_request_body) {
                $this->log('Invalid create order request', 'error');
                wc_add_notice(__('Ошибка формирования запроса к API', 'txpg-gateway'), 'error');
                return;
            }

            $args = array();
            $args['body'] = $create_order_request_body;

            /** @var string $login_owner_type */
            $login_owner_type = $this->hpp_login_owner_type;
            $login_name = $this->hpp_login_name;
            $password = $this->hpp_password;

            if ($this->testmode) {
                $login_owner_type = $this->test_hpp_login_owner_type;
                $login_name = $this->test_hpp_login_name;
                $password = $this->test_hpp_password;
            }

            $args['headers'] = array(
                'Content-Type' => 'application/json',
                'Authorization' => 'Basic ' . $this->auth_base64($login_owner_type, $login_name, $password)
            );

            $response = wp_remote_post($this->hpp_url . '/order', $args);

            if (is_wp_error($response)) {
                $this->log($response->get_error_message(), 'error');
                wc_add_notice(__('Ошибка подключения к API', 'txpg-gateway'), 'error');
                return;
            }

            $create_order_response = $this->getCreateOrderResponse($response['body']);

            if ($this->isCreateOrderPreparing($create_order_response)) {
                // Заказ создан. Перенаправление на hpp страницу
                update_post_meta($order->get_id(), '_txpg_order_id', $create_order_response->getOrder()->getId());
                update_post_meta($order->get_id(), '_txpg_order_status', $create_order_response->getOrder()->getStatus());
                update_post_meta($order->get_id(), '_txpg_order_password', $create_order_response->getOrder()->getPassword());
                update_post_meta($order->get_id(), '_txpg_order_payment_page_url', $this->get_hpp_redirect_url($create_order_response));

                WC()->cart->empty_cart();

                return array(
                    'result' => 'success',
                    'redirect' => $this->get_hpp_redirect_url($create_order_response)
                );
            }

            if ($create_order_response->getOrder()->getStatus() == \OpenAPI\Client\Model\OrderStatus::REFUSED) {
                wc_add_notice(__('Покупка отменена', 'txpg-gateway'), 'notice');
                return;
            }

            wc_add_notice(__('Оплата отклонена', 'txpg-gateway'), 'error');
        }

        /**
         * Retrieve order info from TXPG API
         *
         * @param string $txpg_order_id TXPG order ID
         * @return \OpenAPI\Client\Model\GetOrderResponse|null
         */
        private function get_order_info($txpg_order_id)
        {
            $login_owner_type = $this->hpp_login_owner_type;
            $login_name = $this->hpp_login_name;
            $password = $this->hpp_password;

            if ($this->testmode) {
                $login_owner_type = $this->test_hpp_login_owner_type;
                $login_name = $this->test_hpp_login_name;
                $password = $this->test_hpp_password;
            }

            $args['headers'] = array(
                'Content-Type' => 'application/json',
                'Authorization' => 'Basic ' . $this->auth_base64($login_owner_type, $login_name, $password)
            );

            $response = wp_remote_get($this->hpp_url . '/order/' . $txpg_order_id, $args);

            if (is_wp_error($response)) {
                $this->log("get_order_info error for TXPG order ID $txpg_order_id: " . $response->get_error_message(), 'error');
                return null;
            }

            $this->log("get_order_info response for TXPG order ID $txpg_order_id: " . print_r($response['body'], true), 'debug');

            $get_order_response = \OpenAPI\Client\ObjectSerializer::deserialize($response['body'], \OpenAPI\Client\Model\GetOrderResponse::class, []);
            return $get_order_response;
        }

        /**
         * Get the return URL (thank you page)
         *
         * @param WC_Order|null $order Order object
         * @return string
         */
        public function get_return_url($order = null)
        {
            return WC()->api_request_url('txpg_handler', is_ssl());
        }

        /**
         * Check if the gateway is available for use
         *
         * @return bool
         */
        public function is_available()
        {
            return parent::is_available();
        }

        /**
         * Check if the order can be refunded via this gateway
         *
         * @param WC_Order $order Order object
         * @return bool
         */
        public function can_refund_order($order)
        {
            return $order->is_paid() && parent::can_refund_order($order);
        }

        /**
         * Process refund
         *
         * @param int $order_id Order ID
         * @param float|null $amount Refund amount
         * @param string $reason Refund reason
         * @return bool|WP_Error
         */
        public function process_refund($order_id, $amount = null, $reason = '')
        {
            $order = wc_get_order($order_id);

            if (!$this->can_refund_order($order)) {
                return new WP_Error('error', __('Refund failed.', 'woocommerce'));
            }

            $txpg_order_id = get_post_meta($order_id, '_txpg_order_id')[0];

            $txpg_order_info = $this->get_order_info($txpg_order_id);
            if (!empty($txpg_order_info)) {
                $txpg_order_action_id = $txpg_order_info->getOrder()->getLastTran()->getActionId();
                $txpg_order_txn = $txpg_order_info->getOrder()->getLastTran()->getRidByAcquirer();
                if (!empty($txpg_order_action_id)) {
                    update_post_meta($order->get_id(), '_txpg_order_action_id', $txpg_order_action_id);
                }
                if (!empty($txpg_order_txn)) {
                    update_post_meta($order->get_id(), '_txpg_order_txn', $txpg_order_txn);
                }
            }

            if (empty($txpg_order_info) || empty($txpg_order_id) || empty($txpg_order_action_id) || empty($txpg_order_txn)) {
                return new WP_Error('error', __('Refund failed.', 'woocommerce'));
            }

            $txpg_order_info = $this->get_order_info($txpg_order_id);
            $txpg_order_status = $txpg_order_info->getOrder()->getStatus();

            // Reverse
            $requestTran = new \OpenAPI\Client\Model\ExecTranRequestTran();
            if ($txpg_order_status == \OpenAPI\Client\Model\OrderStatus::AUTHORIZED && $amount <= $order->get_total()) {
                $requestTran->setPhase(\OpenAPI\Client\Model\TranPhase::AUTH)
                    ->setAmount($amount);

                // Full
                if ($order->get_total() == $amount) {
                    $requestTran->setVoidKind(\OpenAPI\Client\Model\TranVoidKind::FULL);
                }

                // Partial
                if ($order->get_total() > $amount) {
                    $requestTran->setVoidKind(\OpenAPI\Client\Model\TranVoidKind::PARTIAL);
                }

                $links = new \OpenAPI\Client\Model\ExecTranRequestTranLinks();
                $voided_links = new \OpenAPI\Client\Model\ExecTranRequestTranLinksVoided();
                $voided_links->setTranActionId($txpg_order_action_id)
                    ->setRidByOriginator($txpg_order_txn);
                $links->setVoided($voided_links);
                $requestTran->setLinks($links);
            }

            // Refund
            $statuses_for_refund = [
                \OpenAPI\Client\Model\OrderStatus::FULLY_PAID,
                \OpenAPI\Client\Model\OrderStatus::CLOSED
            ];
            if (in_array($txpg_order_status, $statuses_for_refund) && $amount <= $order->get_total()) {
                $requestTran->setType(\OpenAPI\Client\Model\TranType::REFUND)
                    ->setPhase(\OpenAPI\Client\Model\TranPhase::SINGLE)
                    ->setAmount($amount);
            }

            if (empty($requestTran->getPhase())) {
                return new WP_Error('error', __('Refund failed.', 'woocommerce'));
            }

            $request = new \OpenAPI\Client\Model\ExecTranRequest(['tran' => $requestTran]);

            $json_body = json_encode($request->jsonSerialize(), true);

            $args = array();
            $args['body'] = $json_body;

            /** @var string $login_owner_type */
            $login_owner_type = $this->hpp_login_owner_type;
            $login_name = $this->hpp_login_name;
            $password = $this->hpp_password;

            if ($this->testmode) {
                $login_owner_type = $this->test_hpp_login_owner_type;
                $login_name = $this->test_hpp_login_name;
                $password = $this->test_hpp_password;
            }

            $args['headers'] = array(
                'Content-Type' => 'application/json',
                'Authorization' => 'Basic ' . $this->auth_base64($login_owner_type, $login_name, $password)
            );

            $response = wp_remote_post($this->hpp_url . '/order/' . $txpg_order_id . '/exec-tran', $args);

            if (is_wp_error($response)) {
                return new WP_Error('error', __('Refund failed.', 'woocommerce'));
            }

            /** @var \OpenAPI\Client\Model\ExecTranResponse $exec_tran_response */
            $exec_tran_response = \OpenAPI\Client\ObjectSerializer::deserialize($response['body'], \OpenAPI\Client\Model\ExecTranResponse::class, []);
            if (!empty($exec_tran_response->getErrorCode())) {
                return new WP_Error('error', __('Refund failed.', 'woocommerce'));
            }

            return true;
        }

        /**
         * Handle TXPG webhook callback
         */
        public function txpg_webhook()
        {
            // Validate GET parameters
            if (empty($_GET['ID']) || empty($_GET['STATUS'])) {
                $this->log('Webhook error: Missing ID or STATUS in GET parameters', 'error');
                status_header(400);
                wp_die('Missing required parameters', 'TXPG Webhook Error', ['response' => 400]);
            }

            $txpg_order_id = sanitize_text_field($_GET['ID']);
            $txpg_status = sanitize_text_field($_GET['STATUS']);

            // Map string status to OrderStatus enum
            $status_map = [
                'Authorized' => \OpenAPI\Client\Model\OrderStatus::AUTHORIZED,
                'FullyPaid' => \OpenAPI\Client\Model\OrderStatus::FULLY_PAID,
                'PartPaid' => \OpenAPI\Client\Model\OrderStatus::PART_PAID,
            ];

            if (!isset($status_map[$txpg_status])) {
                $this->log("Webhook error: Invalid STATUS value: $txpg_status", 'error');
                status_header(400);
                wp_die('Invalid STATUS value', 'TXPG Webhook Error', ['response' => 400]);
            }

            $mapped_status = $status_map[$txpg_status];
            $good_statuses = [
                \OpenAPI\Client\Model\OrderStatus::AUTHORIZED,
                \OpenAPI\Client\Model\OrderStatus::FULLY_PAID,
                \OpenAPI\Client\Model\OrderStatus::PART_PAID,
            ];

            // Get order info from TXPG API
            $order_info = $this->get_order_info($txpg_order_id);
            if (empty($order_info) || !$order_info->getOrder()) {
                $this->log("Webhook error: Failed to retrieve order info for TXPG order ID: $txpg_order_id", 'error');
                status_header(500);
                wp_die('Failed to retrieve order info', 'TXPG Webhook Error', ['response' => 500]);
            }

            // Verify order status from TXPG API
            $api_order_status = $order_info->getOrder()->getStatus();
            if (!in_array($api_order_status, $good_statuses)) {
                $this->log("Webhook error: Invalid TXPG order status: " . print_r($api_order_status, true), 'error');
                status_header(400);
                wp_die('Invalid order status', 'TXPG Webhook Error', ['response' => 400]);
            }

            // Check status consistency
            if ($mapped_status !== $api_order_status) {
                $this->log("Webhook error: Status mismatch. Webhook STATUS: $txpg_status, API status: " . print_r($api_order_status, true), 'error');
                status_header(400);
                wp_die('Status mismatch', 'TXPG Webhook Error', ['response' => 400]);
            }

            // Retrieve WooCommerce order
            $orders = wc_get_orders(['txpg_order_id' => $txpg_order_id, 'limit' => 1]);
            if (empty($orders)) {
                $this->log("Webhook error: No WooCommerce order found for TXPG order ID: $txpg_order_id", 'error');
                status_header(404);
                wp_die('Order not found', 'TXPG Webhook Error', ['response' => 404]);
            }

            $order = $orders[0];

            // Validate order object
            if (!($order instanceof WC_Order)) {
                $this->log("Webhook error: Invalid WooCommerce order object for TXPG order ID: $txpg_order_id", 'error');
                status_header(500);
                wp_die('Invalid order object', 'TXPG Webhook Error', ['response' => 500]);
            }

            // Check current order status to avoid redundant transitions
            if ($order->has_status(['processing', 'completed'])) {
                $this->log("Webhook info: Order {$order->get_id()} already processed or completed", 'info');
                wp_safe_redirect(parent::get_return_url($order));
                exit;
            }

            try {
                // Mark payment as complete
                $order->payment_complete();
                $this->log("Webhook success: Payment completed for order ID: {$order->get_id()}, TXPG order ID: $txpg_order_id", 'info');

                // Update stock and clear cart
                wc_reduce_stock_levels($order);
                WC()->cart->empty_cart();

                // Redirect to thank you page
                wp_safe_redirect(parent::get_return_url($order));
                exit;
            } catch (Exception $e) {
                $this->log("Webhook error: Exception during payment_complete for order ID: {$order->get_id()}. Error: " . $e->getMessage(), 'error');
                status_header(500);
                wp_die('Error processing payment', 'TXPG Webhook Error', ['response' => 500]);
            }
        }

        /**
         * Prepare create order request for TXPG API
         *
         * @param WC_Order $order WooCommerce order
         * @return false|string
         */
        private function prepareCreateOrderRequest($order)
        {
            $consumer = new \OpenAPI\Client\Model\Consumer();
            $consumer->setRid($order->get_customer_id());

            $wp_user = $order->get_user();
            if (!$wp_user) {
                $consumer->setName('Guest');
            } else {
                $consumer->setName($wp_user->display_name);
            }

            $consumer_browser = new \OpenAPI\Client\Model\ConsumerDeviceBrowser();
            $consumer_browser->setIp($order->get_customer_ip_address())
                ->setUserAgent($order->get_customer_user_agent());

            $consumer_device = new \OpenAPI\Client\Model\ConsumerDevice();
            $consumer_device->setBrowser($consumer_browser);

            $order_type = new \OpenAPI\Client\Model\OrderType();
            $order_type->setPaymentMethods(['any']);

            $cp_order = new \OpenAPI\Client\Model\Order();
            $cp_order->setAmount($order->get_total())
                ->setTypeRid($this->order_type)
                ->setCurrency($order->get_currency())
                ->setConsumer($consumer)
                ->setDescription(empty($order->get_customer_note()) ? '' : $order->get_customer_note())
                ->setType($order_type)
                ->setLanguage(substr(get_locale(), 0, 2))
                ->setHppRedirectUrl($this->get_return_url($order))
                ->setInitiationEnvKind(\OpenAPI\Client\Model\OrderInitiationEnvKind::BROWSER)
                ->setConsumerDevice($consumer_device);

            if ($wp_user) {
                $cp_order->setHppCofCapturePurposes(array(
                    \OpenAPI\Client\Model\CofUsage::CIT,
                    \OpenAPI\Client\Model\CofUsage::RECURRING));
            }

            $this->addItemsToCreateOrderRequest($order, $cp_order);

            $create_order_request = new \OpenAPI\Client\Model\CreateOrderRequest();
            $create_order_request->setOrder($cp_order);
            return json_encode($create_order_request->jsonSerialize(), true);
        }

        /**
         * Get HPP redirect URL
         *
         * @param \OpenAPI\Client\Model\CreateOrderResponse $response
         * @return string
         */
        private function get_hpp_redirect_url(\OpenAPI\Client\Model\CreateOrderResponse $response)
        {
            return $response->getOrder()->getHppUrl() . '/?' . http_build_query(array(
                    'id' => $response->getOrder()->getId(),
                    'password' => $response->getOrder()->getPassword()
                ));
        }

        /**
         * Add items to create order request
         *
         * @param WC_Order $order WooCommerce order
         * @param \OpenAPI\Client\Model\Order $cp_order TXPG order
         */
        private function addItemsToCreateOrderRequest($order, \OpenAPI\Client\Model\Order $cp_order)
        {
            $items = [];
            foreach ($order->get_items() as $order_item) {
                $item = new \OpenAPI\Client\Model\OfdReceiptContentItemsInner();
                $items[] = $item->setQuantity($order_item->get_quantity())
                    ->setDesc($order_item->get_name())
                    ->setProdCode($order_item->get_id())
                    ->setType($order_item->get_type());
            }

            $receipt_content = array();
            $receipt_content['items'] = $items;
            $cp_order->setReceipt(new \OpenAPI\Client\Model\OfdReceiptContent($receipt_content));
        }

        /**
         * Generate Base64 authorization string
         *
         * @param string $login_type Login type
         * @param string $login Login name
         * @param string $password Password
         * @return string
         */
        private function auth_base64($login_type, $login, $password)
        {
            return base64_encode($login_type . '/' . $login . ':' . $password);
        }

        /**
         * Initialize required files
         */
        private function init()
        {
            require_once dirname(__FILE__) . '/include' . '/ObjectSerializer.php';
            require_once dirname(__FILE__) . '/include' . '/Model/ModelInterface.php';

            foreach (scandir(dirname(__FILE__) . '/include/Model') as $filename) {
                $path = dirname(__FILE__) . '/include/Model/' . $filename;
                if (is_file($path)) {
                    require_once $path;
                }
            }
        }

        /**
         * Deserialize create order response
         *
         * @param string $body Response body
         * @return \OpenAPI\Client\Model\CreateOrderResponse
         */
        private function getCreateOrderResponse($body)
        {
            return \OpenAPI\Client\ObjectSerializer::deserialize($body, \OpenAPI\Client\Model\CreateOrderResponse::class, []);
        }

        /**
         * Check if order is in PREPARING status
         *
         * @param \OpenAPI\Client\Model\CreateOrderResponse $create_order_response
         * @return bool
         */
        private function isCreateOrderPreparing(\OpenAPI\Client\Model\CreateOrderResponse $create_order_response)
        {
            return $create_order_response->getErrorCode() === null &&
                $create_order_response->getOrder()->getStatus() == \OpenAPI\Client\Model\OrderStatus::PREPARING;
        }

        /**
         * Check if order is paid
         *
         * @param \OpenAPI\Client\Model\CreateOrderResponse $create_order_response
         * @return bool
         */
        private function isCreateOrderPaid(\OpenAPI\Client\Model\CreateOrderResponse $create_order_response)
        {
            $good_statuses = [
                \OpenAPI\Client\Model\OrderStatus::AUTHORIZED,
                \OpenAPI\Client\Model\OrderStatus::FULLY_PAID,
                \OpenAPI\Client\Model\OrderStatus::PART_PAID];
            $order_response_status = $create_order_response->getOrder()->getStatus();

            return $create_order_response->getErrorCode() === null &&
                in_array($order_response_status, $good_statuses);
        }

        /**
         * Logging method
         *
         * @param string $message Log message
         * @param string $level Log level (default: 'info')
         */
        private function log($message, $level = 'info')
        {
            if (empty($this->log)) {
                $this->log = wc_get_logger();
            }
            $this->log->log($level, $message, array('source' => 'txpg'));
        }
    }

    function txpg_register_gateway_class($gateways)
    {
        $gateways[] = 'WC_Txpg_Gateway';
        return $gateways;
    }

    function handle_order_txpg_id($query, $query_vars)
    {
        if (!empty($query_vars['txpg_order_id'])) {
            $query['meta_query'][] = array(
                'key' => '_txpg_order_id',
                'value' => esc_attr($query_vars['txpg_order_id']),
            );
        }

        return $query;
    }
}

add_filter('woocommerce_payment_gateways', 'txpg_register_gateway_class');