<?php

/**
 *  2checkout Payment Gateway.
 *
 * Provides a 2checkout Payment Gateway.
 *
 * @class       KKART_Gateway_2Checkout
 * @extends 	KKART_Payment_Gateway
 * @version     1.0.0
 * @package     Kkart\Classes\Payment
 * @author 		Kkart
 */

if ( ! defined( 'ABSPATH' ) )
{
    exit; // Exit if accessed directly
}

class KKART_Gateway_2Checkout extends KKART_Payment_Gateway {
	
	protected $_version = KKART_VERSION;	
	protected $merchant_code;
	protected $secret_key;
	protected $buy_link_secret_word;
	protected $debug;
	protected $demo;
	protected $icon_style;
	protected $icon_width;
	protected $api;
	protected $log;


	public function __construct() {
		$this->includes();
		$this->id                 = '2checkout';
		$this->icon               = KKART_2CO_IMAGES_URI . '/2checkout-dark.svg';
		$this->has_fields         = false;
		$this->method_title       = esc_html__( '2Checkout Payment Gateway', 'kkart' );
		$this->method_description = esc_html__( '2Checkout accept mobile and online payments from customers worldwide.', 'kkart' );

		// Load the form fields.
		$this->init_form_fields();

		// Load the settings.
		$this->init_settings();

		// Define user set variables.
		$this->title                = $this->get_option( 'title', esc_html__( '2Checkout', 'kkart' ) );
		$this->description          = $this->get_option( 'description', esc_html__( 'Pay via 2Checkout. Accept Credit Cards, Debit Cards and more.', 'kkart' ) );
		$this->order_button_text    = $this->get_option( 'order_button_text', esc_html__( 'Proceed to 2Checkout', 'kkart' ) );
		$this->merchant_code        = $this->get_option( 'merchant_code' );
		$this->secret_key           = htmlspecialchars_decode( $this->get_option( 'secret_key' ) );
		$this->buy_link_secret_word = htmlspecialchars_decode( $this->get_option( 'buy_link_secret_word' ) );
		$this->debug                = kkart_string_to_bool( $this->get_option( 'debug', 'no' ) );
		$this->demo                 = kkart_string_to_bool( $this->get_option( 'demo', 'yes' ) );
		$this->icon_style           = $this->get_option( 'icon_style', 'dark' );
		$this->icon_width           = $this->get_option( 'icon_width', '50' );

		//  Init 2co api

		$this->admin_notices();

		// Will return to site/?kkart-api=kkart-2checkout-gateway-return
		// Will return to site/?kkart-api=kkart-2checkout-ipn-response
		// Will return to site/?kkart-api=kkart-2checkout-lcn-response
		// Will return to site/?kkart-api=kkart-2checkout-ins-response

		add_action( 'kkart_api_kkart-2checkout-gateway-return', array( $this, 'process_gateway_return' ) );
		add_action( 'kkart_api_kkart-2checkout-ipn-response', array( $this, 'process_ipn_response' ) );
		add_action( 'kkart_update_options_payment_gateways_'.$this->id, array(
			$this,
			'process_admin_options'
		) );

		$this->api = new KKART_2Checkout_Gateway_API( $this->merchant_code, $this->secret_key );

		do_action( 'kkart_2checkout_gateway_init', $this );
	}
	
	public function includes() {
		require_once dirname(__FILE__) . '/includes/class-kkart-2checkout-gateway-api.php';		
		
		if(!defined( 'KKART_2CO_IMAGES_URI' )){
			define( 'KKART_2CO_IMAGES_URI', trailingslashit( plugin_dir_url( __FILE__ ) . 'images' ) );
		}
	}
	
	public function get_api() {

		if ( is_object( $this->api ) ) {
			return $this->api;
		}

		$this->api = new KKART_2Checkout_Gateway_API( $this->merchant_code, $this->secret_key );

		return $this->api;
	}

	public function get_icon() {

		// Override Icon
		$icon_url = apply_filters( 'kkart_2checkout_icon', KKART_2CO_IMAGES_URI . sprintf( '/2checkout-%s.svg', $this->icon_style ) );

		$icons_str = sprintf( '<img  class="kkart-2checkout-gateway-pay-image" alt="%s" src="%s" style="width: %d%%" />', esc_attr( $this->order_button_text ), esc_url( $icon_url ), absint( $this->icon_width ) );

		return apply_filters( 'kkart_gateway_icon', $icons_str, $this->id, $this );
	}

	public function init_form_fields() {

		$this->form_fields = array();

		$this->form_fields['enabled'] = array(
			'title'   => esc_html__( 'Enable/Disable', 'kkart' ),
			'type'    => 'checkbox',
			'label'   => esc_html__( 'Enable 2Checkout Payment Gateway', 'kkart' ),
			'default' => 'no'
		);

		$this->form_fields['title'] = array(
			'title'       => esc_html__( 'Title', 'kkart' ),
			'type'        => 'text',
			'description' => esc_html__( 'This controls the title which the user sees during checkout.', 'kkart' ),
			'default'     => esc_html__( '2Checkout', 'kkart' ),
			'desc_tip'    => true
		);

		$this->form_fields['description'] = array(
			'title'       => esc_html__( 'Description', 'kkart' ),
			'type'        => 'textarea',
			'description' => esc_html__( 'This controls the description which the user sees during checkout.', 'kkart' ),
			'default'     => esc_html__( 'Pay via 2Checkout. Accept Credit Cards, PayPal and Debit Cards', 'kkart' )
		);

		$this->form_fields['order_button_text'] = array(
			'title'       => esc_html__( 'Order button text', 'kkart' ),
			'type'        => 'text',
			'description' => esc_html__( 'Checkout order button text.', 'kkart' ),
			'default'     => esc_html__( 'Proceed to 2Checkout', 'kkart' ),
			'desc_tip'    => true
		);

		$this->form_fields['webhook'] = array(
			'title'       => esc_html__( 'Read How to Setup', 'kkart' ),
			'type'        => 'title',
			/* translators: webhook URL */
			'description' => sprintf( __( '<strong>Webhook endpoint: </strong> <code style="background-color:#ddd;">%s</code> to your <a href="https://secure.2checkout.com/cpanel/ipn_settings.php" target="_blank">2Checkout IPN settings</a>', 'kkart' ), $this->get_ipn_response_url() ),
		);

		$this->form_fields['merchant_code'] = array(
			'title'       => esc_html__( 'Merchant Code', 'kkart' ),
			'type'        => 'text',
			'default'     => '',
			'desc_tip'    => false,
			'description' => sprintf( __( 'Please enter 2Checkout <strong>Merchant Code</strong> from <a target="_blank" href="%s">Integrations > Webhooks &amp; API > API Section</a>.', 'kkart' ), 'https://secure.2checkout.com/cpanel/webhooks_api.php' )
		);

		$this->form_fields['secret_key'] = array(
			'title'       => esc_html__( 'Secret Key', 'kkart' ),
			'type'        => 'text',
			'description' => sprintf( __( 'Please enter 2Checkout <strong>Secret Key</strong> from <a target="_blank" href="%s">Integrations > Webhooks &amp; API > API Section</a>', 'kkart' ), 'https://secure.2checkout.com/cpanel/webhooks_api.php' ),
			'default'     => '',
			'desc_tip'    => false
		);

		$this->form_fields['buy_link_secret_word'] = array(
			'title'       => esc_html__( 'Buy Link Secret Word', 'kkart' ),
			'type'        => 'text',
			'description' => sprintf( __( 'Please enter 2Checkout <strong>Buy link secret word</strong> from <a target="_blank" href="%s">Integrations > Webhooks &amp; API > Secret word</a> section', 'kkart' ), 'https://secure.2checkout.com/cpanel/webhooks_api.php' ),
			'default'     => '',
			'desc_tip'    => false
		);

		$this->form_fields['demo'] = array(
			'title'       => esc_html__( 'Demo Mode', 'kkart' ),
			'type'        => 'checkbox',
			'label'       => esc_html__( 'Enable Demo Mode', 'kkart' ),
			'default'     => 'yes',
			'description' => esc_html__( 'This mode allows you to test your setup to make sure everything works as expected without take real payment.', 'kkart' )
		);

		$this->form_fields['debug'] = array(
			'title'       => esc_html__( 'Debug Log', 'kkart' ),
			'type'        => 'checkbox',
			'label'       => esc_html__( 'Enable Logging', 'kkart' ),
			'default'     => 'no',
			'description' => sprintf( __( 'Log 2Checkout events, <strong>DON\'T ALWAYS ENABLE THIS.</strong> You can check this log in %s.', 'kkart' ), '<a target="_blank" href="' . esc_url( admin_url( 'admin.php?page=kkart-status&tab=logs&log_file=' . esc_attr( $this->id ) . '-' . sanitize_file_name( wp_hash( $this->id ) ) . '.log' ) ) . '">' . esc_html__( 'System Status &gt; Logs', 'kkart' ) . '</a>' )
		);

		$this->form_fields['icon_style'] = array(
			'title'   => esc_html__( 'Gateway Icon Style', 'kkart' ),
			'type'    => 'select',
			'class'   => 'kkart-enhanced-select',
			'label'   => esc_html__( 'Choose Gateway a Icon Style', 'kkart' ),
			'options' => array(
				'dark'  => esc_html__( 'Dark', 'kkart' ),
				'light' => esc_html__( 'Light', 'kkart' ),
			),
			'default' => 'dark'
		);

		$this->form_fields['icon_width'] = array(
			'title'             => esc_html__( 'Gateway Icon Width', 'kkart' ),
			'type'              => 'number',
			'description'       => esc_html__( 'Gateway Icon Width in %. Limit: 1-100', 'kkart' ),
			'default'           => '50',
			'desc_tip'          => false,
			'custom_attributes' => array(
				'min'  => '1',
				'max'  => '100',
				'size' => '3',
			)
		);

		$this->form_fields = apply_filters( 'kkart_2checkout_admin_form_fields', $this->form_fields );
	}


	public static function get_ipn_response_url() {
		return KKART()->api_request_url( 'kkart-2checkout-ipn-response' );
	}

	public function admin_notices() {
		if ( is_admin() ) {
			// Checks if account number and secret is not empty
			if ( kkart_string_to_bool( $this->get_option( 'enabled' ) ) && ( empty( $this->merchant_code ) || empty( $this->secret_key ) || empty( $this->buy_link_secret_word ) ) ) {
				add_action( 'admin_notices', array( $this, 'plugin_not_configured_message' ) );
			}

			// Checks that the currency is supported
			if ( ! $this->using_supported_currency() ) {
				add_action( 'admin_notices', array( $this, 'currency_not_supported_message' ) );
			}
		}
	}

	public function using_supported_currency() {

		// https://knowledgecenter.2checkout.com/Documentation/07Commerce/Checkout-links-and-options/Order-interface-currencies

		$kkart_currency = get_kkart_currency();
		$supported_currencies = apply_filters( 'kkart_2checkout_supported_currencies', array(
			'AED', 'AFN', 'ALL', 'ARS', 'AUD', 'AZN', 'BBD', 'BDT', 'BGN', 'BHD', 'BMD', 'BND', 'BOB', 'BRL', 'BSD', 'BWP', 'BYN', 'BZD', 'CAD', 'CHF', 'CLP', 'CNY', 'COP', 'CRC', 'CZK', 'DKK', 'DOP', 'DZD', 'EGP', 'EUR', 'FJD', 'GBP', 'GTQ', 'HKD', 'HNL', 'HRK', 'HTG', 'HUF', 'IDR', 'ILS', 'INR', 'JMD', 'JOD', 'JPY', 'KES', 'KRW', 'KWD', 'KZT', 'LAK', 'LBP', 'LKR', 'LRD', 'MAD', 'MDL', 'MMK', 'MOP', 'MRO', 'MUR', 'MVR', 'MXN', 'MYR', 'NAD', 'NGN', 'NIO', 'NOK', 'NPR', 'NZD', 'OMR', 'PAB', 'PEN', 'PGK', 'PHP', 'PKR', 'PLN', 'PYG', 'QAR', 'RON', 'RSD', 'RUB', 'SAR', 'SBD', 'SCR', 'SEK', 'SGD', 'SVC', 'SYP', 'THB', 'TND', 'TOP', 'TRY', 'TTD', 'TWD', 'UAH', 'USD', 'UYU', 'VEF', 'VND', 'VUV', 'WST', 'XCD', 'XOF', 'YER', 'ZAR',) 
		);

		return ! ! in_array( $kkart_currency, $supported_currencies );

	}

	public function is_available() {
		// Test if is valid for use.
		return parent::is_available() && ! empty( $this->merchant_code ) && ! empty( $this->secret_key ) && ! empty( $this->buy_link_secret_word ) && $this->using_supported_currency();
	}

	public function process_payment( $order_id ) {

		$order = kkart_get_order( $order_id );
		$args  = $this->payment_args( $order );

		return array(
			'result'   => 'success',
			'redirect' => $this->get_api()->convertplus_buy_link( $args, $this->merchant_code, $this->buy_link_secret_word ),
		);
	}
	
	public function log( $message, $level = 'info' ) {
		if ( $this->debug ) {
			if ( is_null( $this->log ) ) {
				$this->log = kkart_get_logger();
			}

			$context = array( 'source' => $this->id );
			// $this->log->info( $message, $context );

			$this->log->log( $level, $message, $context );
		}
	}

	public function shop_language() {
		$lang = apply_filters( 'kkart_2checkout_shop_language', '' );

		if ( '' !== $lang ) {
			return $lang;
		}

		$_lang = explode( '_', ( get_locale() ? get_locale() : get_option( 'WPLANG' ) ) );
		$lang  = $_lang[0];
		if ( 'es' == $lang ) {
			$lang = 'es_ib';
		}

		$available = array('zh', 'da', 'nl', 'fr', 'gr', 'el', 'it', 'jp', 'no', 'pt', 'sl', 'es_ib', 'es_la', 'sv', 'en');

		if ( ! in_array( $lang, $available ) ) {
			return 'en';
		}

		return $lang;
	}

	public function format_item_price( $price ) {
		return (float) number_format( (float) $price, kkart_get_price_decimals(), kkart_get_price_decimal_separator(), '' );
	}

	public function format_item_name( $item_name ) {
		return trim( html_entity_decode( kkart_trim_string( $item_name ? wp_strip_all_tags( $item_name ) : esc_html__( 'Item', 'kkart' ), 127 ), ENT_NOQUOTES, 'UTF-8' ) );
	}

	public function payment_args( $order ) {

		$args            = array();
		$args['dynamic'] = true;

		// Billing information
		$args['email'] = $order->get_billing_email();
		$args['name']  = $order->get_formatted_billing_full_name();

		if ( $order->get_billing_phone() ) {
			$args['phone'] = $order->get_billing_phone();
		}

		if ( $order->get_billing_company() ) {
			$args['company-name'] = $order->get_billing_company();
		}

		if ( $order->get_billing_country() ) {
			$args['country'] = $order->get_billing_country();
		}

		if ( $order->get_billing_city() ) {
			// $args['state'] = $order->get_billing_state();
			$args['city'] = esc_html( $order->get_billing_city() );
		}

		if ( $order->get_billing_state() ) {
			// $args['state'] = $order->get_billing_state();
			$args['state'] = esc_html( KKART()->countries->get_states( $order->get_billing_country() )[ $order->get_billing_state() ] );
		}

		if ( $order->get_billing_state() ) {
			$args['state'] = $order->get_billing_state();
		}

		if ( $order->has_billing_address() ) {
			$args['address']  = $order->get_billing_address_1();
			$args['address2'] = $order->get_billing_address_2();
		}

		if ( $order->get_billing_postcode() ) {
			$args['zip'] = $order->get_billing_postcode();
		}

		// Delivery/Shipping information
		// $order->needs_shipping_address()  /  KKART()->cart->needs_shipping_address()
		if ( $order->needs_shipping_address() ) {

			$ship_to_different_address = ! empty( $_POST['ship_to_different_address'] ) && ! kkart_ship_to_billing_address_only();

			$args['ship-email'] = $order->get_billing_email();
			$args['ship-phone'] = $order->get_billing_phone();
			$args['ship-name']  = $ship_to_different_address ? $order->get_formatted_shipping_full_name() : $order->get_formatted_billing_full_name();

			if ( $order->get_shipping_country() || $order->get_billing_country() ) {
				$args['ship-country'] = $ship_to_different_address ? $order->get_shipping_country() : $order->get_billing_country();
			}

			if ( $order->get_shipping_city() ) {
				$args['ship-city'] = esc_html( $order->get_shipping_city() );
			}

			if ( $order->get_shipping_state() || $order->get_billing_state() ) {
				$ship_state         = $ship_to_different_address ? $order->get_shipping_state() : $order->get_billing_state();
				$args['ship-state'] = esc_html( KKART()->countries->get_states( $order->get_shipping_country() )[ $ship_state ] );
			}

			if ( $order->has_billing_address() || $order->has_shipping_address() ) {
				$args['ship-address']  = $ship_to_different_address ? $order->get_shipping_address_1() : $order->get_billing_address_1();
				$args['ship-address2'] = $ship_to_different_address ? $order->get_shipping_address_2() : $order->get_billing_address_2();
			}

			if ( $order->get_shipping_postcode() || $order->get_billing_postcode() ) {
				$args['ship-zip'] = $ship_to_different_address ? $order->get_shipping_postcode() : $order->get_billing_postcode();
			}
		}

		// Product information
		$product_info                 = array();
		$product_info['prod']         = array();
		$product_info['opt']          = array();
		$product_info['price']        = array();
		$product_info['qty']          = array();
		$product_info['tangible']     = array();
		$product_info['type']         = array();
		$product_info['item-ext-ref'] = array();

		// Products
		if ( count( $order->get_items() ) > 0 ) {
			foreach ( $order->get_items() as $item ) {

				// $item = new KKART_Order_Item_Product(); // KKART_Order_Item

				$product = $item->get_product();

				if ( ! $product ) {
					continue;
				}
	
				$product_info['type'][]  = 'PRODUCT';
				$product_info['prod'][]  = $this->format_item_name( $item->get_name() );
				$product_info['price'][] = $this->format_item_price( $order->get_item_total( $item ) );
				$product_info['qty'][]   = $item->get_quantity(); // get_item_total

				if ( $product->is_downloadable() && $product->is_virtual() ) {
					$product_info['tangible'][] = '0';
				} else {
					$product_info['tangible'][] = '1';
				}

				$product_info['item-ext-ref'][] = $product->get_id();
			}
		}

		// Tax.
		if ( kkart_tax_enabled() && 0 < $order->get_total_tax() ) {

			if ( get_option( 'kkart_tax_total_display' ) == 'itemized' ) {
				foreach ( $order->get_tax_totals() as $tax ) {
					$product_info['type'][]         = 'TAX';
					$product_info['prod'][]         = esc_html( $tax->label );
					$product_info['price'][]        = $this->format_item_price( $tax->amount );
					$product_info['qty'][]          = 1;
					$product_info['tangible'][]     = '0';
					$product_info['item-ext-ref'][] = '';
				}
			} else {
				$product_info['type'][]         = 'TAX';
				$product_info['prod'][]         = esc_html( KKART()->countries->tax_or_vat() );
				$product_info['price'][]        = $this->format_item_price( $order->get_total_tax() );
				$product_info['qty'][]          = 1;
				$product_info['tangible'][]     = '0';
				$product_info['item-ext-ref'][] = '';
			}
		}

		// Support Custom Fees. Add custom fee from "kkart_cart_calculate_fees" hook
		if ( 0 < count( $order->get_fees() ) ) {
			foreach ( $order->get_fees() as $item ) {

				//  new KKART_Order_Item_Fee()

				$product_info['type'][]         = 'TAX';
				$product_info['prod'][]         = $this->format_item_name( $item->get_name() );
				$product_info['price'][]        = $this->format_item_price( $item->get_total() );
				$product_info['qty'][]          = 1;
				$product_info['tangible'][]     = '0';
				$product_info['item-ext-ref'][] = '';
			}
		}

		// Shipping
		if ( kkart_shipping_enabled() && 0 < $order->get_shipping_total() ) {

			$shipping_name = $this->format_item_name( sprintf( esc_html__( 'Shipping via %s', 'kkart' ), $order->get_shipping_method() ) );

			$product_info['type'][]         = 'SHIPPING';
			$product_info['prod'][]         = $shipping_name;
			$product_info['price'][]        = $this->format_item_price( $order->get_shipping_total() );
			$product_info['qty'][]          = 1;
			$product_info['tangible'][]     = '0';
			$product_info['item-ext-ref'][] = '';
		}

		$args['return-url']       = KKART()->api_request_url( 'kkart-2checkout-gateway-return' );
		$args['return-type']      = 'redirect'; // link
		$args['currency']         = get_kkart_currency();
		$args['language']         = $this->shop_language();
		$args['customer-ext-ref'] = $order->get_customer_id();
		$args['order-ext-ref']    = $order->get_id();
		$args['tpl']              = 'default'; // one-column

		if ( $this->demo ) {
			$args['test'] = true;
		}

		$args['prod'] = implode( ';', $product_info['prod'] );
		// $args[ 'opt' ]          = implode( ';', $product_info[ 'opt' ] );
		$args['price']        = implode( ';', $product_info['price'] );
		$args['qty']          = implode( ';', $product_info['qty'] );
		$args['tangible']     = implode( ';', $product_info['tangible'] );
		$args['type']         = implode( ';', $product_info['type'] );
		$args['item-ext-ref'] = implode( ';', $product_info['item-ext-ref'] );

		return apply_filters( 'kkart_2checkout_payment_args', $args, $product_info, $order, $this );
	}

	public function get_checkout_order_received_url( $order ) {
		$order_received_url = kkart_get_endpoint_url( 'downloads', $order->get_id(), kkart_get_page_permalink( 'my-account' ) );

		if ( 'yes' === get_option( 'kkart_force_ssl_checkout' ) || is_ssl() ) {
			$order_received_url = str_replace( 'http:', 'https:', $order_received_url );
		}

		$order_received_url = add_query_arg( 'key', $order->get_order_key(), $order_received_url );

		return apply_filters( 'kkart_get_checkout_order_received_url', $order_received_url, $order );
	}

	public function process_gateway_return() {

		$data = $this->sanitize_text_field_deep( $_GET );

		if ( isset( $data['refno'] ) && ! empty( $data['refno'] ) ) {

			$order_id       = absint( sanitize_text_field( $data['order-ext-ref'] ) );
			$order          = kkart_get_order( $order_id );
			$transaction_id = sanitize_text_field( $data['refno'] );
			$this->log( "Gateway Return Response \n" . print_r( $data, true ), 'info' );
			if ( ! $order ) {
				wp_die( sprintf( 'Order# %d is not available.', $order_id ), '2Checkout Request', array( 'response' => 404 ) );
			}

			$this->log( "Gateway Signatures \n" . print_r( array(
					'generated' => $this->get_api()->generate_return_signature( $data, $this->buy_link_secret_word ),
					'returned'  => $data['signature'],
				), true ) );

			if ( ! $this->get_api()->is_valid_return_signature( $data, $this->buy_link_secret_word ) ) {
				$order->update_status( 'failed', 'Order failed due to 2checkout signature mismatch.' );
				kkart_add_notice( "Order failed due to 2checkout signature mismatch.", 'error' );
				do_action( 'kkart_2checkout_payment_signature mismatch', $data, $this );
				// wp_redirect( $order->get_cancel_order_url_raw() );
				wp_redirect( kkart_get_checkout_url() );
				exit;
			}


			$real_price = number_format( (float) $order->get_total(), 2, '.', '' );
			$paid_price = number_format( (float) $data['total'], 2, '.', '' );

			// If it is demo Purchase.
			if ( $this->demo || ( isset( $data['test'] ) && $data['test'] ) ) {
				$order->update_status( 'on-hold', 'Payment received and it was demo purchase.' );
				$order->add_order_note( 'Payment received and it was demo purchase.', true );
				update_post_meta( $order->get_id(), '_transaction_id', $transaction_id );
				KKART()->cart->empty_cart();
				do_action( 'kkart_2checkout_payment_demo_success', $order, $this );
				wp_redirect( $this->get_return_url( $order ) );
				exit;
			}

			// If User Change Price using developer tools
			if ( $real_price !== $paid_price ) {
				$order->update_status( 'failed', 'Order failed for fraud pricing changes. Real Price was: ' . $real_price . '. Paid Price was: ' . $paid_price );
				kkart_add_notice( "Order failed due to fraud pricing changes.", 'error' );
				do_action( 'kkart_2checkout_payment_price_fraud', $data, $this );
				// wp_redirect( $order->get_cancel_order_url_raw() );
				wp_redirect( kkart_get_checkout_url() );
				exit;
			}

			// Order
			$order->update_status( 'on-hold', 'Payment received and waiting for 2Checkout IPN response.' );
			$order->add_order_note( 'Payment received and waiting for 2Checkout validate.', true );
			update_post_meta( $order->get_id(), '_transaction_id', $transaction_id );
			KKART()->cart->empty_cart();
			do_action( 'kkart_2checkout_payment_processing', $order, $data, $this );
			wp_redirect( $this->get_return_url( $order ) );
			exit;

		} else {
			wp_die( '2Checkout Gateway Return Failure', '2Checkout Request', array( 'response' => 200 ) );
		}
	}
	
	public function process_ins_response() {
		$data = $this->sanitize_text_field_deep( $_POST );
		$this->log( "INS Response: \n" . print_r( $data, true ), 'info' );
		do_action( 'kkart_2checkout_gateway_process_ins_response', $data, $this );
	}

	public function sanitize_text_field_deep( $value ) {
		return map_deep( wp_unslash( $value ), 'sanitize_text_field' );
	}

	public function process_ipn_response() {

		$data = $this->sanitize_text_field_deep( $_POST );

		do_action( 'kkart_2checkout_gateway_process_ipn_response', $data, $this );

		$transaction_id = sanitize_text_field( $data['REFNO'] );
		$ipn_receipt    = $this->get_api()->ipn_receipt_response( $data );

		if ( $ipn_receipt ) {

			$this->log( "IPN Response: \n" . print_r( $data, true ), 'info' );

			$order_id = absint( sanitize_text_field( $data['REFNOEXT'] ) );

			$order = kkart_get_order( $order_id );

			if ( ! $order ) {
				echo $ipn_receipt;
				$this->log( sprintf( 'Order# %d is not available.', $order_id ), 'error' );
				exit;
			}

			$order_status = $order->get_status();

			// Test Payment
			if ( isset( $data['TEST_ORDER'] ) && $data['TEST_ORDER'] ) {
				$order->add_order_note( 'IPN Response Received as Test Order' );
			}

			if ( isset( $data['ORDERSTATUS'] ) ) {
				switch ( $data['ORDERSTATUS'] ) {

					// Payment Authorized
					case 'PAYMENT_AUTHORIZED':
						if ( ! in_array( $order_status, array( 'processing', 'completed' ) ) ) {
							$order->update_status( 'on-hold', 'Order PAYMENT AUTHORIZED by 2Checkout IPN.' );
							do_action( 'kkart_2checkout_ipn_response_order_processing', $data['ORDERSTATUS'], $order, $data, $this );
						}
						break;

					// Completed Order
					case 'COMPLETE':
						if ( ! in_array( $order_status, array( 'processing', 'completed' ) ) ) {
							$this->log( "IPN Response: ORDERSTATUS = COMPLETE \n" . print_r( $data, true ), 'info' );
							$order->payment_complete( $transaction_id );
							do_action( 'kkart_2checkout_ipn_response_order_complete', $data['ORDERSTATUS'], $order, $data, $this );
						}
						break;

					// Cancel Order
					case 'CANCELED':
						$this->log( "IPN Response: ORDERSTATUS = CANCELED \n" . print_r( $data, true ), 'info' );
						$order->update_status( 'cancelled', 'Order CANCELED by 2Checkout IPN' );
						do_action( 'kkart_cancelled_order', $order->get_id() );
						do_action( 'kkart_2checkout_ipn_response_order_canceled', $data['ORDERSTATUS'], $order, $data, $this );
						break;

					//  Refund Order
					case 'REFUND':
						if ( $order_status !== 'refunded' ) {
							$this->log( "IPN Response: ORDERSTATUS = REFUND \n" . print_r( $data, true ), 'info' );
							$order->update_status( 'refunded', 'Order REFUND by 2Checkout IPN' );
							do_action( 'kkart_2checkout_ipn_response_order_refund', $data['ORDERSTATUS'], $order, $data, $this );
						}
						break;

					default:
						$this->log( sprintf( "IPN Response: ORDERSTATUS = %s \n", $data['ORDERSTATUS'] ) . print_r( $data, true ), 'info' );
						break;
				}
			}

			echo $ipn_receipt;
			exit();
		} else {
			$this->log( 'No IPN Receipt Response Code Generated.', 'error' );
		}
	}

	public function plugin_not_configured_message() {
		$id = '2checkout';

		if ( ! empty( $this->get_option( 'merchant_code' ) ) && ! empty( $this->get_option( 'secret_key' ) ) && ! empty( $this->get_option( 'buy_link_secret_word' ) ) ){
			return;
		}

		echo '<div class="error"><p><strong>' . esc_html__( 'Payment Gateway - 2Checkout for Kkart disabled', 'kkart' ) . '</strong>: ' . esc_html__( 'You must fill the "Merchant Code" and the "Secret Key" and "Buy Link Secret Word" fields.', 'kkart' ) . '</p></div>';
	}

	public function currency_not_supported_message() {
		echo '<div class="error"><p><strong>' . esc_html__( 'Payment Gateway - 2Checkout for Kkart disabled', 'kkart' ) . '</strong>: ' . esc_html__( '2Checkout does not support your store currency.', 'kkart' ) . '</p></div>';
	}

	public function payment_fields() {

		$description = $this->get_description();

		if ( $this->demo ) {
			$description .= '.<br />' . sprintf( __( '<strong>DEMO MODE ENABLED.</strong> Use a %s', 'kkart' ), '<a target="_blank" href="https://knowledgecenter.2checkout.com/Documentation/09Test_ordering_system/01Test_payment_methods">test payment cards</a>' );
		}
		if ( $description ) {
			echo wpautop( wptexturize( trim( $description ) ) );
		}
	}
}