<?php

/**
 * WC_Gateway_Bankful Plugin Class
 *
 * @package Bankful with WooCommerce Payment on hosted checkout.
 * @since   2.0.0
 */

/**
 * The class itself, please note that it is inside plugins_loaded action hook
 */
class WC_Gateway_Bankful extends WC_Payment_Gateway {
	use Bankful_Security_Checks_Trait;

	/**
	 * API endpoint
	 *
	 * @var string
	 */
	public $version = '3.0.4';

	/**
	 * API endpoint
	 *
	 * @var string
	 */
	public $api_endpoint;

	/**
	 * API endpoint for recurring payment
	 *
	 * @var string
	 */
	public $api_endpoint_subscription;

	/**
	 * API endpoint fot REFUND Transaction
	 *
	 * @var string
	 */
	public $api_endpoint_refund;

	/**
	 * API endpoint for Tokenize Card
	 *
	 * @var string
	 */
	public $api_endpoint_token;

	/**
	 * API endpoint for Redirect Hosted Payment URL
	 *
	 * @var string
	 */
	public $api_endpoint_payment;

	/**
	 * Whether or not logging is enabled
	 *
	 * @var bool
	 */
	public static $log_enabled = false;

	/**
	 * Logger instance
	 *
	 * @var WC_Logger
	 */
	public static $log = false;

	/**
	 * Whether the debug mode is enabled.
	 *
	 * @var bool
	 */
	public $debug;

	/**
	 * API username for merchant
	 *
	 * @var string
	 */
	public $req_username;

	/**
	 * API password for merchant
	 *
	 * @var string
	 */
	public $req_password;

	/**
	 * Whether or not Test server is enabled
	 *
	 * @var bool
	 */
	public $testEnv;

	/**
	 * Return Url to update order status on WooCommerce
	 *
	 * @var bool
	 */
	public $notify_url;

	/**
	 * Whether the Order is Subscription order or not.
	 *
	 * @var bool
	 */
	public $is_subscription = false;

	/**
	 * Class constructor
	 */
	public function __construct() {
		global $WP_SITE_URL;
		global $SANDBOX_API_SRV;
		global $LIVE_API_SRV;

		$this->id = 'bankful_hosted_gateway'; // payment gateway plugin ID
		
		/**
		 * Filter hook to modify Bankful Icon
		 * 
		 * @since version 2.0.0
		 */
		$this->icon = apply_filters('woocommerce_bankful_hosted_icon', plugins_url() . '/bankful/assets/img/bankful_logo_whitebg.svg');
		$this->has_fields = false;
		$this->method_title = 'Bankful Payment Gateway';
		$this->order_button_text = __('Proceed to Bankful', 'bankful');
		$this->method_description = 'Pay securely with Bankful Payment Gateway.'; // will be displayed on the options page

		// gateway supports subscriptions, saved payment methods,
		$this->supports = array(
			'products',
			'subscriptions',
			'subscription_cancellation',
			'subscription_suspension',
			'subscription_reactivation',
			'subscription_amount_changes',
			'subscription_date_changes',
			'subscription_payment_method_change',
			'subscription_payment_method_change_customer',
			'subscription_payment_method_change_admin',
			'multiple_subscriptions',
			'refunds',
		);

		// Method with all the options fields
		$this->init_form_fields();

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

		$this->title             = $this->get_option('title');
		$this->description       = $this->get_option('description');
		$this->enabled           = $this->get_option('enabled');

		$bankful_options = get_option('bankful_options');
		
		$this->testEnv = ( strtolower($bankful_options['bankful_field_environment'])==strtolower('Test') );
		
		$this->debug          = 'yes' === $this->get_option('debug', 'no');
		$this->req_username   = isset( $bankful_options[ 'bankful_field_live_username' ] ) ? $bankful_options[ 'bankful_field_live_username' ] : 'sandbox-test@bankful.com';
		$this->req_password   = isset( $bankful_options[ 'bankful_field_live_password' ] ) ? $bankful_options[ 'bankful_field_live_password' ] : 'tuMcC7m333J4VMsb';
		$this->notify_url     = $WP_SITE_URL . '/wp-json/bankful/v1/order-updated';

		$this->api_endpoint   = $LIVE_API_SRV . 'front-calls/go-in/woocommerce-hosted-page';

		$this->api_endpoint_refund = $LIVE_API_SRV . 'api/woocommerce-v2/transaction';

		$this->api_endpoint_subscription = $LIVE_API_SRV . 'api/woocommerce-v2/transaction';

		$this->api_endpoint_token = $LIVE_API_SRV . 'api/woocommerce-v2/save-woo-card-tokenize';

		$this->api_endpoint_payment = $LIVE_API_SRV . 'api/woocommerce-v2/generate-redirect-url';

		self::$log_enabled = $this->debug;

		// This action hook saves the settings
		add_action('woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ));

		// This action hook shows the receipt of order
		add_action('woocommerce_receipt_' . $this->id, array( $this, 'receipt_page' ));

		// This action hook shows Thankyou order page
		add_filter('woocommerce_thankyou_order_received_text', array( $this, 'order_received_text' ), 10, 2);

		add_action('woocommerce_scheduled_subscription_payment_' . $this->id, array( $this, 'scheduled_subscription_payment' ), 10, 2);
		add_filter('woocommerce_subscription_payment_meta', array( $this, 'add_bankful_subscription_payment_meta' ), 20, 2 );
		add_action('woocommerce_subscription_payment_method_change_' . $this->id, array( $this, 'change_payment_method' ), 10, 2);
		add_action('woocommerce_review_order_before_payment', array( $this, 'maybe_override_has_fields' ));
		// Adding Stylesheet
		wp_enqueue_style('bf-style', plugins_url() . '/bankful/assets/css/bf-style.css', array(), $this->version);
	}

	/**
	 * Return whether or not this gateway still requires setup to function.
	 *
	 * When this gateway is toggled on via AJAX, if this returns true a
	 * redirect will occur to the settings page instead.
	 *
	 * @since 2.0.0
	 * @return bool
	 */
	public function needs_setup() {
		return !is_email($this->req_username);
	}

	// Function to handle changing payment method
	public function change_payment_method( $subscription_id, $new_payment_method ) {
		$subscription = wcs_get_subscription($subscription_id);
		if ($subscription) {
			$subscription->update_payment_method($subscription, $new_payment_method);
		}
	}

	private function is_subscription_change_payment_method() {
		if (function_exists('wcs_is_subscription') && function_exists('wcs_order_contains_subscription')) {
			// Check if we're on the pay page and there's a "change_payment_method" parameter
			return is_wc_endpoint_url('order-pay') && isset($_GET['change_payment_method']);
		}
		return false;
	}

	public function maybe_override_has_fields() {
		if ($this->is_subscription_change_payment_method()) {
			$this->has_fields = true;
		}
	}

	public function add_bankful_subscription_payment_meta( $payment_meta, $subscription ) {
		$bankful_customer_id       = $subscription->get_meta( '_bankful_customer_id', true );

		$payment_meta[ $this->id ] = array(
			'post_meta' => array(
				'_bankful_customer_id'   => array(
					'value' => $bankful_customer_id,
					'label' => 'Bankful Customer Vault ID',
				),
			),
		);

		return $payment_meta;
	}

	/**
	 * Logging method.
	 *
	 * @param string $message Log message.
	 * @param string $level Optional. Default 'info'. Possible values:
	 *                      emergency|alert|critical|error|warning|notice|info|debug.
	 */
	public static function log( $message, $level = 'info' ) {
		if (self::$log_enabled) {
			if (empty(self::$log)) {
				self::$log = wc_get_logger();
			}
			self::$log->log($level, $message, array( 'source' => 'bankful_gateway' ));
		}
	}

	/**
	 * Order received message.
	 *
	 * @param string $text Text to show on THank you page.
	 * @param object $order Order to process
	 * 
	 * @return string Thankyou message
	 */
	public function order_received_text( $text, $order ) {
		if ($order && $this->id === $order->get_payment_method()) {
			return esc_html__('Thank you for your payment. Your transaction has been completed, and a receipt for your purchase has been emailed to you.', 'bankful');
		}

		return $text;
	}

	/**
	 * Processes and saves options.
	 * If there is an error thrown, will continue to save and validate fields, but will leave the erroring field out.
	 *
	 * @return bool was anything saved?
	 */
	public function process_admin_options() {
		$saved = parent::process_admin_options();

		// Maybe clear logs.
		if ('yes' !== $this->get_option('debug', 'no')) {
			if (empty(self::$log)) {
				self::$log = wc_get_logger();
			}
			self::$log->clear('bankful_gateway');
		}

		return $saved;
	}

	/**
	 * Plugin options
	 */
	public function init_form_fields() {
		$this->form_fields = array(
			'enabled' => array(
				'title' => __('Enable/Disable', 'bankful'),
				'type' => 'checkbox',
				'label' => ( ( !empty($this->get_option('enabled')) && 'yes' == $this->get_option('enabled') ) ? 'Disable Bankful Gateway (Bankful Hosted)' : 'Enable Bankful Gateway (Bankful Hosted)' ),
				'default' => 'yes',
			),
			'title' => array(
				'title' => __('Title', 'bankful'),
				'type' => 'text',
				'description' => __('This controls the title which the user sees during checkout.', 'bankful'),
				'default' => __('Bankful', 'bankful'),
				'desc_tip'      => true,
			),
			'description' => array(
				'title' => __('Description', 'bankful'),
				'type' => 'textarea',
				'description' => __('This controls the description which the user sees during checkout.', 'bankful'),
				'default' => __('Pay with Bankful Hosted Payment Gateway', 'bankful'),
			),
			'debug' => array(
				'title'       => __('Debug Log', 'bankful'),
				'type'        => 'checkbox',
				'label'       => __('Enable logging', 'bankful'),
				'default'     => 'no',
				'description' => sprintf(__('Log Bankful Payment Gateway Events', 'bankful')),
			),
		);
	}

	/**
	 * Get Bankful Payment Gateway Args
	 *
	 * @param object $order
	 * 
	 * @return array
	 */
	public function get_bf_checkout_args( $order ) {
		global $WP_SITE_URL;
		global $woocommerce;
		global $wp_version;
		global $BF_PLUGIN_SOURCE;
		
		$order_id = $order->get_id();

		if ('yes' == $this->debug) {
			$this->log('Generating payment form for order ' . $order->get_order_number());
		}
		
		$is_subscription = false;
		if (function_exists('wcs_get_subscriptions_for_order') && function_exists('wcs_order_contains_subscription') && wcs_order_contains_subscription($order_id)) {
			$subscriptions = wcs_get_subscriptions_for_order($order_id);
			$is_subscription = true;
		} elseif (function_exists('wcs_get_subscriptions_for_renewal_order') && function_exists('wcs_order_contains_renewal') && wcs_order_contains_renewal($order_id)) {
			$subscriptions = wcs_get_subscriptions_for_renewal_order($order_id);
			$is_subscription = true;
		} else {
			$is_subscription = false;
		}
		
		$merchant_info  = $this->merchant_credential_new();
		$signature = md5($this->req_password);
		$bf_checkout_args = array();

		$transaction_mode = $this->testEnv ? 'sandbox' : 'live';
		$bf_checkout_args['transaction_mode']   = $transaction_mode;
		$bf_checkout_args['cartName']           = 'WooCommerce-Hosted-Page';
		$bf_checkout_args['order_id']           = $order_id;
		$bf_checkout_args['request_amount']     = $order->get_total();
		$bf_checkout_args['x_url_cancel']       = $order->get_cancel_order_url();
		$bf_checkout_args['callback_url']       = $this->notify_url;
		$bf_checkout_args['redirect_success']   = $WP_SITE_URL . '/wp-json/bankful/v1/redirect-pending/';
		$bf_checkout_args['x_url_failed']       = $WP_SITE_URL . '/wp-json/bankful/v1/redirect-pending/';

		$bf_checkout_args['x_url_complete']     = $this->get_return_url( $order );
		$bf_checkout_args['request_currency']   = get_woocommerce_currency();
		$bf_checkout_args['cust_fname']         = sanitize_text_field($order->get_billing_first_name());
		$bf_checkout_args['cust_lname']         = sanitize_text_field($order->get_billing_last_name());
		$bf_checkout_args['bill_addr']          = sanitize_text_field($order->get_billing_address_1());
		$bf_checkout_args['bill_addr_2']        = sanitize_text_field($order->get_billing_address_2());
		$bf_checkout_args['bill_addr_city']     = sanitize_text_field($order->get_billing_city());
		$bf_checkout_args['bill_addr_state']    = sanitize_text_field($order->get_billing_state());
		$bf_checkout_args['bill_addr_country']  = sanitize_text_field($order->get_billing_country());
		$bf_checkout_args['bill_addr_zip']      = sanitize_text_field($order->get_billing_postcode());
		$bf_checkout_args['cust_phone']         = sanitize_text_field($order->get_billing_phone());
		$bf_checkout_args['cust_email']         = sanitize_text_field($order->get_billing_email());
		$bf_checkout_args['remote_ip']          = $order->get_customer_ip_address();
		$bf_checkout_args['save_card_on_file']  = $is_subscription ? 'Y' : 'N';

		$bf_checkout_args['woo_version']        = sanitize_text_field($woocommerce->version);
		$bf_checkout_args['wp_version']         = $wp_version;
		$bf_checkout_args['php_version']        = phpversion();
		$bf_checkout_args['bf_plugin_version']  = $this->version;
		$bf_checkout_args['bf_plugin_name']     = sanitize_text_field('Bankful Payments Hosted');
		$bf_checkout_args['bf_plugin_source']   = $BF_PLUGIN_SOURCE; // bankful_direct || woo_market

		
		if ($is_subscription) {
			$site_id = get_option( 'bankful_options_site_id' );
			$subscription_products = array();
			$fetchObj = new stdClass(); 
			if ($site_id && !empty($subscriptions)) {

				foreach ($subscriptions as $subscription) {
					$subscription_id = $subscription->get_id();

					// Get subscription items
					$subscription_items = $subscription->get_items();

					foreach ($subscription_items as $item) {
						$product_id = $item->get_product_id();
						$quantity = $item->get_quantity();
						$subscription_products[] = array(
							'subscription_id' => $subscription_id,
							'product_id' => $product_id,
							'quantity' => $quantity,
						);
					}

				}

				$req_url_exp = explode('/api/', $this->api_endpoint_subscription, -1);
				$pre_req_url = $req_url_exp[0] . '/api/handle-webhook/cart/woocommerce/verify_rulesV2';

				$fetchObj->site_id = $site_id;
				$fetchObj->products = $subscription_products;
				$fetchObj->cart_id = 10006;

				$params = (array) $fetchObj;
				
				
				$args = array(
					'method'    => 'POST',
					'body'      => wp_json_encode( $fetchObj ),
					'headers'   => array(
						'Content-Type'  => 'application/json',
						'Authorization' => 'Bearer ' . $merchant_info['bf_access_token'],
					),
				);

				$response = bankful_remote_post($pre_req_url, $args);

				if (!is_wp_error($response)) {

					$body = wp_remote_retrieve_body($response);

					$body_pre = json_decode($body);
				
					if ($body_pre && $body_pre->allRecurringProducts) {

						$bf_checkout_args['site_id'] = $fetchObj->site_id;
						$bf_checkout_args['products_set'] = wp_json_encode($body_pre->allRecurringProducts);

					} else {
						$subscription->add_order_note('Product Rules not configured correctly, subscription created and charged successfully but subscription not synced to bankful portal, you can ignore this message if you are not using subscriptions from bankful directly.');
					}

				}

			}
		}

		/**
		 * Filter hook to modify Bankful checkout Arguments to pass to bankful hosted page
		 * 
		 * @since version 2.0.0
		 */
		$bf_checkout_args = apply_filters('woocommerce_bankful_hosted_args', $bf_checkout_args);

		return $bf_checkout_args;
	}

	/**
	 * Generate the bf_checkout button link
	 *
	 * @param string $order_id
	 * 
	 */
	public function generate_bf_checkout_form( $order_id ) {

		// Block checkout form generation on insecure connections and redirect to cart.
		if ( ! bankful_is_secure_connection() ) {
			self::log( 'Checkout form blocked for order ' . $order_id . ': insecure connection.', 'error' );
			wc_add_notice( __( 'Payment cannot be processed over an insecure (HTTP) connection. Please contact the store administrator to enable HTTPS.', 'bankful' ), 'error' );
			wp_safe_redirect( wc_get_cart_url() );
			exit;
		}

		$order = new WC_Order($order_id);

		$merchant_info  = $this->merchant_credential_new();
		$bf_checkout_args = $this->get_bf_checkout_args($order);

		$args = array(
			'method'    => 'POST',
			'body'      => wp_json_encode( $bf_checkout_args ),
			'headers'   => array(
				'Content-Type'  => 'application/json',
				'Authorization' => 'Bearer ' . $merchant_info['bf_access_token'],
			),
		);

		$url      = $this->api_endpoint_payment;
		$response = bankful_remote_post($url, $args);
		
		if (!is_wp_error($response)) {
			$body   = wp_remote_retrieve_body($response);
			$result = json_decode($body);
			wp_redirect( $result->redirect_url );
			exit;
		}
	}

	public function is_bankful_subscriptions_enabled() {
		return class_exists( 'WC_Subscriptions' ) || class_exists('WC_Subscriptions_Core_Plugin');
	}

	public function has_bankful_subscription( $order_id ) {
		return ( function_exists( 'wcs_order_contains_subscription' ) && ( wcs_order_contains_subscription( $order_id ) || wcs_is_subscription( $order_id ) || wcs_order_contains_renewal( $order_id ) ) );
	}

	public function is_changing_payment_method_for_bankful_subscription() {
		if ( isset( $_GET['change_payment_method'] ) && function_exists( 'wcs_is_subscription' ) ) { // phpcs:ignore WordPress.Security.NonceVerification
			return wcs_is_subscription( wc_clean( wp_unslash( $_GET['change_payment_method'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification
		}
		return false;
	}

	public function maybe_change_subscription_payment_method_bankful( $order_id ) {
		return (
			$this->is_bankful_subscriptions_enabled() &&
			$this->has_bankful_subscription( $order_id ) &&
			$this->is_changing_payment_method_for_bankful_subscription()
		);
	}

	/**
	 * Process the payment and return the result.
	 *
	 * @param  int $order_id Order ID.
	 * @return array
	 */
	public function process_payment( $order_id ) {

		// Block payment processing on insecure connections.
		$ssl_check = $this->enforce_secure_connection( $order_id );
		if ( $ssl_check ) {
			return $ssl_check;
		}

		if ( $this->maybe_change_subscription_payment_method_bankful( $order_id ) ) {
			return $this->process_change_bankful_subscription_payment_method( $order_id );
		}

		$order          = wc_get_order($order_id);

		return array(
			'result'   => 'success',

			/**
			 * Filter hook to modify Bankful redirect params before redirecting
			 * 
			 * @since version 2.0.0
			 */
			'redirect' => apply_filters('process_payment_redirect', $order->get_checkout_payment_url(true), $order),
		);
	}

	/**
	 * Maybe display fields for subscription payment method change.
	 */
	public function maybe_display_fields_for_subscription( $subscription ) {
		if ( is_wc_endpoint_url( 'change-payment-method' ) ) {
			$this->has_fields = true;
		} else {
			$this->has_fields = false;
		}
	}

	/**
	 * If There are no payment fields show the description if set.
	 */
	public function payment_fields() {
		$allowed_html = array(
			'p' => array(),
		);
		if ( $this->has_fields || $this->get_description() ) {
			if ($this->testEnv) {
				$this->description .= '<p>TEST ENVIRONMENT ENABLED. In test mode, you can use Test card numbers.</p>';
				$this->description  = trim($this->description);
			}
			// display the description with <p> tags etc.
			echo '<p>' . wp_kses(wpautop( wptexturize( $this->description ) ), $allowed_html) . '</p>';
		}

		if ( $this->has_fields || $this->is_subscription_change_payment_method() ) {
			
			echo '<fieldset id="wc-' . esc_attr($this->id) . '-cc-form" class="wc-credit-card-form wc-payment-form" style="background:transparent;">';

			/**
			 * To add something before Bankful Credit card form.
			 *
			 * @since bankful version 2.0.0
			 */
			do_action('woocommerce_credit_card_form_start', $this->id);

			$form_nonce = wp_create_nonce('bf_cc_form_nonce');

			$allowed_html = array(
				'option' => array(
					'value' => array(),
					'selected' => array(),
				),
			);

			echo '<div class="fb_full_row form-row form-row-wide">
						<label class="bf_cc_labels">Card Number <span class="required">*</span></label>
						<input class="cc_input_full" id="bfws_cc_number" name="bfws_cc_number" type="text" autocomplete="off" pattern="[0-9]{12,19}" placeholder="Please enter valid Card Number">
					</div>
					<div class="fb_half_row form-row form-row-first validate-required">
						<label class="bf_cc_labels" for="bfws_expiration">Expiry Date <span class="required">*</span></label>
						<select id="cc-exp-month" class="txt" name="bfws_exp_month" class="cc_input_half">
							' . wp_kses($this->generateMonthOptions(), $allowed_html) . '
						</select>
						<select id="cc-exp-year" class="txt" name="bfws_exp_year" class="cc_input_half">
							' . wp_kses($this->generateYearOptions(20), $allowed_html) . '
						</select>
					</div>
					<div class="fb_half_row form-row form-row-last">
						<label class="bf_cc_labels">Card Code (CVV) <span class="required">*</span></label>
						<input id="bfws_cvv" name="bfws_cvv" type="password" maxlength="4" size="4" pattern="[0-9]+" required autocomplete="off" placeholder="CVV" class="cc_input_full">
					</div>
					<input type="hidden" value="' . esc_attr($form_nonce) . '" name="bf_cc_nonce" >
					<div class="clear"></div>';

			/**
			 * To add something after Bankful Credit card form.
			 *
			 * @since bankful version 2.0.0
			 */
			do_action('woocommerce_credit_card_form_end', $this->id);

			echo '<div class="clear"></div></fieldset>';
		}
	}


	public function generateMonthOptions() {
		$months = array(
			'Jan' => '01',
			'Feb' => '02',
			'Mar' => '03',
			'Apr' => '04',
			'May' => '05',
			'Jun' => '06',
			'Jul' => '07',
			'Aug' => '08',
			'Sep' => '09',
			'Oct' => '10',
			'Nov' => '11',
			'Dec' => '12',
		);

		$currentMonthNumber = gmdate('m');

		$output = '';
	
		foreach ($months as $monthName => $monthNumber) {
			$output .= '<option ' . ( $currentMonthNumber === $monthNumber ? 'selected' : '' ) . ' value="' . esc_attr($monthNumber) . '">' . esc_html($monthName) . '</option>';
		}
	
		return $output;
	}

	public function generateYearOptions( $numYears = 20 ) {
		$currentYear = gmdate('Y');
		$endYear = $currentYear + $numYears;
	
		$output = '';
	
		for ($year = $currentYear; $year <= $endYear; $year++) {
			$output .= '<option value="' . esc_attr($year) . '">' . esc_html($year) . '</option>';
		}
	
		return $output;
	}

	/**
	 * Output for the order received page.
	 *
	 * @return void
	 */
	public function receipt_page( $order ) {

		echo '<p>Thank you for your order, please click the button below to pay with Bankful.</p>';
		
		// ./vendor/bin/phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo wp_kses(
			$this->generate_bf_checkout_form($order),
			array(
				'form'  => array(
					'action' => true,
					'method' => true,
					'id' => true,
					'target' => true,
				),
				'a'   => array(
					'class' => true,
					'href' => true,
				),
				'input' => array(
					'type' => true,
					'name' => true,
					'value' => true,
					'id' => true,
					'class' => true,
				),
			)
		);
	}

	/**
	 * Process the payment and return the result.
	 *
	 * @param int $order_id Order ID.
	 * @param int $amount Order ID.
	 * 
	 * @return bool
	 */
	public function process_refund( $order_id, $amount = null, $reason = '' ) {
		global $woocommerce;
		global $wp_version;
		global $BF_PLUGIN_SOURCE;

		$order  = wc_get_order($order_id);
		
		// If it's something else such as a WC_Order_Refund, we don't want that.
		if (!is_a($order, 'WC_Order')) {
			return new WP_Error('wc-order', __('Provided ID is not a WC Order', 'bankful'));
		}

		$bf_order_id = $order->get_meta('_transaction_id');

		if (empty($bf_order_id)) {
			return new WP_Error('wc-order', __('Bankful Provided Transaction ID not found.', 'bankful'));
		}

		if ('refunded' == $order->get_status()) {
			return new WP_Error('wc-order', __('Order has been already refunded', 'bankful'));
		}

		$options = get_option( 'bankful_options' );
		$transaction_mode = $this->testEnv ? 'sandbox' : 'live';

		$params = array(
			'transaction_type' => 'REFUND',
			'amount' => $amount,
			'request_ref_po_id' => $bf_order_id,
			'transaction_mode'  => $transaction_mode,
			'woo_version'       => $woocommerce->version,
			'wp_version'        => $wp_version,
			'php_version'       => phpversion(),
			'bf_plugin_version' => $this->version,
			'bf_plugin_name'    => 'Bankful Payments Hosted',
			'bf_plugin_source'  => $BF_PLUGIN_SOURCE,
			'callback_url'	=> $this->notify_url
		);

		$merchant_info = $this->merchant_credential_new();
		$payloadHash   = generateSignatureHash($params, $merchant_info['bf_hash_salt']);
		$url           = $this->api_endpoint_refund;
		$args          = array(
			'body'    => http_build_query($params),
			'headers' => array(
				'Content-Type'          => 'application/x-www-form-urlencoded',
				'Authorization'         => 'Bearer ' . $merchant_info['bf_access_token'],
				'X-Bankful-Hmac-SHA256' => $payloadHash,
			),
		);
		
		$response = bankful_remote_post($url, $args);
		if (!is_wp_error($response)) {
			$body = wp_remote_retrieve_body($response);
			$bodyArr = $body;
			$body = json_decode($body, false);
			$bodyArr = json_decode($bodyArr, true);
			if (verifyHashSignatureFromRequest($bodyArr)) {
				if (
					isset($body->TRANS_STATUS_NAME)
					&& 'APPROVED' == $body->TRANS_STATUS_NAME
				) {

					$this->log('====================== process_payment PAYMENT APPROVED for Order: ' . $order_id, 'info');

					$order->add_order_note( 'Bankful Payment refund completed. Refund Transaction ID:-' . $body->TRANS_RECORD_ID );

					// Redirect
					return true;
				}else if (
					isset($body->TRANS_STATUS_NAME)
					&& 'PENDING' == $body->TRANS_STATUS_NAME
				) {
					$order->update_status('on-hold', sprintf(__('Payment pending with Bankful and Transaction ID:%s', 'bankful'), $order_id));
					$this->log('====================== process_payment PAYMENT PENDING for Order: ' . $order_id, 'info');

					// Add order note
					$order->add_order_note(' Payment pending with Bankful and Transaction ID:' . $body->TRANS_RECORD_ID);
					$order->add_meta_data( '_transaction_id', $body->TRANS_RECORD_ID, true );

					$body->TRANS_VALUE = floatval($body->TRANS_VALUE);

					// $order->payment_complete($body->TRANS_ORDER_ID);
					wc_reduce_stock_levels($order->get_id());

					$order->save();

					// Redirect
					return true;
				} else if (!empty($body->ERROR_MESSAGE) || !empty($body->API_ADVICE)) {

					$error_message = 'Order already refunded or something went wrong';

					// Add note.
					/* translators: %s: Transaction ID */
					$order->add_order_note(sprintf(__('Refund Failed Transaction Order ID %s', 'bankful'), $body->TRANS_ORDER_ID));

					$order->add_meta_data( '_transaction_id', $body->TRANS_ORDER_ID, true );
					
					return new WP_Error('wc-order', __($error_message, 'bankful'));
				}
			} else {
				$error_message = 'Order already refunded or something went wrong';

				// Add note.
				/* translators: %s: Transaction ID */
				$order->add_order_note(sprintf(__('Refund Failed Transaction Order ID %s', 'bankful'), $body->TRANS_ORDER_ID));

				$order->add_meta_data( '_transaction_id', $body->TRANS_ORDER_ID, true );
				
				return new WP_Error('wc-order', __($error_message, 'bankful'));
			}
		} else { 
			wc_add_notice('Connection error.', 'error');
			return new WP_Error('wc-order', __('Connection error.', 'bankful'));
		}
		return false;
	}

	/**
	 * Process the Subscription payment and return the result.
	 */
	public function process_subscription_payment( $amount_to_charge, $renewal_order ) {
		$this->log('====================== process_subscription_payment RECURRING PAYMENT', 'info');
		global $woocommerce;
		global $wp_version;

		$order = $renewal_order;

		try {

			if (function_exists('wcs_order_contains_renewal') && wcs_order_contains_renewal($order)) {
				$this->is_subscription = true;
			} else {
				throw new Exception(__('Order has no Subscription to process', 'bankful'));
			}
			$order_id = $order->get_id();
			if (function_exists('wcs_get_subscriptions_for_renewal_order')) {
				$subscriptions = wcs_get_subscriptions_for_renewal_order($order);
				$subscription = reset($subscriptions);
	
				$customer_id = $subscription->get_meta('_bankful_customer_id', true);
	
				if (empty($customer_id)) {
					$order->add_order_note('No Customer ID Found.');
					$subscription->add_order_note('No Customer Found for this transaction, Contact Bankful Support');
					$subscription->save();
					throw new Exception(__('No Customer Found for this transaction', 'bankful'));
				}
			}

			$transaction_mode = $this->testEnv ? 'sandbox' : 'live';

			$order_param = array(
				'request_currency'  => $order->get_currency(),
				'cust_fname'        => $order->get_billing_first_name(),
				'cust_lname'        => $order->get_billing_last_name(),
				'cust_email'        => $order->get_billing_email(),
				'bill_addr'         => $order->get_billing_address_1() . ' ' . $order->get_billing_address_2(),
				'bill_addr_zip'     => $order->get_billing_postcode(),
				'bill_addr_city'    => $order->get_billing_city(),
				'bill_addr_state'   => $order->get_billing_state(),
				'bill_addr_country' => $order->get_billing_country(),
				'cart_name'         => 'WooCommerce',
				'order_id'          => $order_id,
				'xtl_order_id'      => $order_id,
				'request_action'    => 'CCAUTHCAP',
				'customer_vault_id' => $customer_id,
				'amount'            => $amount_to_charge,
				'woo_version'       => $woocommerce->version,
				'wp_version'        => $wp_version,
				'transaction_mode'  => $transaction_mode,
				'php_version'       => phpversion(),
				'bf_plugin_version' => $this->version,
				'bf_plugin_name'    => 'Bankful Payments Hosted',
				'bf_plugin_source'  => 'woo_market',
				'callback_url'	=> $this->notify_url
			);

			$params = array_merge($order_param);

			$merchant_info  = $this->merchant_credential_new();
			$payloadHash = generateSignatureHash($params, $merchant_info['bf_hash_salt']);

			$url = $this->api_endpoint_subscription;


			$args = array(
				'body' => http_build_query($params),
				'headers'     => array(
					'Content-Type' => 'application/x-www-form-urlencoded',
					'Authorization' => 'Bearer ' . $merchant_info['bf_access_token'],
					'X-Bankful-Hmac-SHA256' => $payloadHash,
				),
			);
			
			$response = bankful_remote_post($url, $args);

			if (!is_wp_error($response)) {

				$body = wp_remote_retrieve_body($response);
				$bodyArr = $body;
				$body = json_decode($body, false);
				$bodyArr = json_decode($bodyArr, true);
				if (verifyHashSignatureFromRequest($bodyArr)) {

					if (
						isset($body->TRANS_STATUS_NAME)
						&& 'APPROVED' == $body->TRANS_STATUS_NAME
					) {

						// Add order note
						$order->add_order_note('Subscription Payment completed with Bankful and Transaction ID:' . $body->TRANS_ORDER_ID);
						add_post_meta($order->get_id(), '_transaction_id', $body->TRANS_ORDER_ID, true);

						$body->TRANS_VALUE = floatval($body->TRANS_VALUE);

						// Payment complete add TRANS_ORDER_ID as transaction id in post_meta table
						$order->payment_complete($body->TRANS_ORDER_ID);
						wc_reduce_stock_levels($order->get_id());

						// Redirect to the thank you page
						return array(
							'result' => 'success',
							'redirect' => $this->get_return_url($order),
						);
					}else if (
						isset($body->TRANS_STATUS_NAME)
						&& 'PENDING' == $body->TRANS_STATUS_NAME
					) {
						$order->update_status('on-hold');
	
						$this->log('====================== process_payment PAYMENT PENDING for Order: ' . $order_id, 'info');
	
						// Add order note
						$order->add_order_note(' Payment pending with Bankful and Transaction ID:' . $body->TRANS_ORDER_ID);
						$order->add_meta_data( '_transaction_id', $body->TRANS_ORDER_ID, true );
	
						$body->TRANS_VALUE = floatval($body->TRANS_VALUE);
	
						// $order->payment_complete($body->TRANS_ORDER_ID);
						wc_reduce_stock_levels($order->get_id());
	
						// Redirect to the thank you page
						return array(
							'result' => 'success',
							'redirect' => $this->get_return_url($order),
						);
					} else if (!empty($body->ERROR_MESSAGE) || !empty($body->API_ADVICE)) {

						$status = 'ERROR';

						// Add note
						/* translators: %s: Payment Failed Transaction ID */
						$order->add_order_note(sprintf(__('Failed Transaction ID %s', 'bankful'), $body->TRANS_ORDER_ID));

						add_post_meta($order_id, '_transaction_id', $body->TRANS_ORDER_ID, true);

						// Payment failed
						/* translators: %s: Payment Failed Error */
						$order->update_status('failed', sprintf(__('Card payment failed. Payment was rejected due to an error%s', 'bankful'), $order_id));

						$error_message = 'Something went wrong, please contact to your service provider.';
						if (isset($body->TRANS_STATUS_NAME) && 'DECLINED' == $body->TRANS_STATUS_NAME) {
							$error_message = ( ( !empty($body->ERROR_MESSAGE) ) ? $body->ERROR_MESSAGE : ( !empty($body->API_ADVICE) ) ) ? $body->API_ADVICE : $error_message;
						}

						throw new Exception(__($error_message, 'bankful'));
					}
				} else {

					// Add note
					/* translators: %s: Payment Failed Transaction ID */
					$order->add_order_note(sprintf(__('Failed Transaction ID %s', 'bankful'), $body->TRANS_ORDER_ID));

					add_post_meta($order_id, '_transaction_id', $body->TRANS_ORDER_ID, true);

					// Payment failed
					/* translators: %s: Payment Failed Error */
					$order->update_status('failed', sprintf(__('Card payment failed. Payment was rejected due to an error%s', 'bankful'), $order_id));

					$error_message = 'Something went wrong, please contact to your service provider.';
					if (isset($body->TRANS_STATUS_NAME) && 'DECLINED' == $body->TRANS_STATUS_NAME) {
						$error_message = ( ( !empty($body->ERROR_MESSAGE) ) ? $body->ERROR_MESSAGE : ( !empty($body->API_ADVICE) ) ) ? $body->API_ADVICE : $error_message;
					}

					throw new Exception(__($error_message, 'bankful'));
				}
			} else {
				wc_add_notice('Connection error.', 'error');
			}
		} catch (Exception $ex) { // Add log
			$this->log('ERROR Ex', 'info');
			$this->log($ex->getMessage(), 'error');

			/* translators: %s: General Failed Transaction Error */
			$order->add_order_note(sprintf(__('Error Message %s', 'bankful'), $ex->getMessage()));
		}
	}

	/**
	 * Validate Expiry Date entered in Checkout Card Fields
	 * 
	 * @param string||date $card_date date entered
	 * 
	 * @return boolean
	 */
	public function validate_expirydate( $card_date = null ) {
		$today = gmdate('Ym');
		$this->log(' card_date: ' . $card_date, 'info');
		$today_dt = new DateTime($today);
		$expire_dt = new DateTime($card_date);

		if ($expire_dt < $today_dt) {
			return false;
		} else {
			return true;
		}
	}


	/**
	 * Get Cart Total from Cart Object
	 * 
	 * @return float
	 */
	public function get_cart_total() {
		$final_array = array();
		$cart = WC()->cart;
		$totalAmount = $cart->total;
		$final_array['amount'] = floatval($totalAmount);
		return $final_array;
	}

	/**
	 * Get Extra Versioning Options
	 * 
	 * @return float
	 */
	public function get_versions() {
		global $woocommerce;
		global $wp_version;
		global $BF_PLUGIN_SOURCE;
		$versions_array = array();
		$versions_array['woo_version'] = $woocommerce->version;
		$versions_array['wp_version'] = $wp_version;
		$versions_array['php_version'] = phpversion();
		$versions_array['bf_plugin_version'] = $this->version;
		$versions_array['bf_plugin_name'] = 'Bankful Payments Native';
		$versions_array['bf_plugin_source'] = $BF_PLUGIN_SOURCE; // bankful_direct || woo_market
		return $versions_array;
	}

	/**
	 * Get Cart SubTotal from Cart Object
	 * 
	 * @return float
	 */
	public function get_cart_subtotal() {
		$final_array = array();
		$cart = WC()->cart;
		$subTotalAmount = $cart->subtotal;
		$final_array['subtotal_amount'] = floatval($subTotalAmount);
		return $final_array;
	}

	/**
	 * Get Cart Discount Total from Cart Object
	 * 
	 * @return float
	 */
	public function get_discount_total() {
		$final_array = array();
		$cart = WC()->cart;
		$discountAmount = $cart->get_discount_total();
		$final_array['discount_amount'] = floatval($discountAmount);
		return $final_array;
	}

	/**
	 * Get Cart Shipping Total from Cart Object
	 * 
	 * @return float
	 */
	public function get_shipping_total() {
		$final_array = array();
		$cart = WC()->cart;
		$shippingAmount = $cart->get_shipping_total();
		$final_array['shipping_amount'] = floatval($shippingAmount);
		return $final_array;
	}

	/**
	 * Get Merchant Credentials from DB
	 * 
	 * @return array
	 */
	public function merchant_credential() {
		$request_params = array(
			'req_username' => $this->req_username,
			'req_password' => $this->req_password,
		);
		$finalRequestParams = array();

		foreach ($request_params as $reqKey => $reqParamVal) {
			if (empty($request_params[$reqKey])) {
				throw new Exception(
					esc_html(
						'Merchant not configured correctly, please contact Bankful support, Thanks.',
						'bankful_credit_card'
					)
				);
			}

			$finalRequestParams[$reqKey] = trim($reqParamVal);
		}

		return $finalRequestParams;
	}

	/**
	 * Process the payment method change for subscriptions.
	 *
	 * @since 5.6.0
	 *
	 * @param int $order_id
	 * @return array|null
	 */
	public function process_change_bankful_subscription_payment_method( $order_id ) {
		$this->log('====================== process_change_bankful_subscription_payment_method CAPTURE CARD for Order: ' . $order_id, 'info');

		if (!isset($_POST['bf_cc_nonce'])) {
			$this->log('Nonce key not found: ' . $order_id, 'error');
			throw new Exception(esc_html( 'Error Processing Credit Card Payment', 'bankful_credit_card'));
			die(esc_html('Security Check', 'bankful_credit_card'));
		}

		if (!wp_verify_nonce(sanitize_key($_POST['bf_cc_nonce']), 'bf_cc_form_nonce')) {
			$this->log('Nonce key verification failed: ' . $order_id, 'error');
			throw new Exception(esc_html( 'Error Processing Credit Card Payment', 'bankful_credit_card'));
			die(esc_html('Security Check', 'bankful_credit_card'));
		}

		$expiry_month = wp_unslash(sanitize_text_field(isset($_POST['bfws_exp_month']))) ? wc_clean(wp_unslash($_POST['bfws_exp_month'])) : null;
		$expiry_year = wp_unslash(sanitize_text_field(isset($_POST['bfws_exp_year']))) ? wc_clean(wp_unslash($_POST['bfws_exp_year'])) : null;

		$order = wc_get_order($order_id);

		$card_number = !empty(wc_clean(wp_unslash($_POST['bfws_cc_number'])))
			? str_replace(array( ' ', '-' ), '', wc_clean(wp_unslash($_POST['bfws_cc_number'])))
			: '';
		$card_cvc = !empty(wc_clean(wp_unslash($_POST['bfws_cvv'])))
			? wc_clean(wp_unslash($_POST['bfws_cvv']))
			: '';

		try {
			if (empty($card_number)) {
				throw new Exception(__('Please Enter Card number', 'bankful'));
			} elseif (empty($expiry_month) || empty($expiry_year)) {
				throw new Exception(__('Please Enter Card expiration date', 'bankful'));
			} elseif ($this->validate_expirydate($expiry_year . $expiry_month) == false) {
				throw new Exception(__('Invalid Credit Card Expiration date', 'bankful'));
			} elseif (empty($card_cvc)) { 
				throw new Exception(__('Please Enter Card CVV number', 'bankful'));
			}

			$this->is_subscription = true;

			$transaction_mode = $this->testEnv ? 'sandbox' : 'live';

			$order_param = array(
				'pmt_numb' => $card_number,
				'pmt_key' => $card_cvc,
				'transaction_mode' => $transaction_mode,
				'pmt_expiry' => $expiry_month . '/' . $expiry_year,
				'request_currency' => $order->get_currency(),
				'remote_ip' => $order->get_customer_ip_address(),
				'cust_fname' => sanitize_text_field($order->get_billing_first_name()),
				'cust_lname' => sanitize_text_field($order->get_billing_last_name()),
				'cust_email' => sanitize_text_field($order->get_billing_email()),
				'bill_addr' => sanitize_text_field($order->get_billing_address_1() . ' ' . $order->get_billing_address_2()),
				'bill_addr_zip' => sanitize_text_field($order->get_billing_postcode()),
				'bill_addr_city' => sanitize_text_field($order->get_billing_city()),
				'bill_addr_state' => sanitize_text_field($order->get_billing_state()),
				'bill_addr_country' => sanitize_text_field($order->get_billing_country()),
				'ship_addr_country' => sanitize_text_field($order->get_shipping_country()),
				'ship_addr_city' => sanitize_text_field($order->get_shipping_city()),
				'ship_addr_state' => sanitize_text_field($order->get_shipping_state()),
				'ship_addr_zip' => sanitize_text_field($order->get_shipping_postcode()),
				'ship_addr' => sanitize_text_field($order->get_shipping_address_1() . ', ' . $order->get_shipping_address_2()),
				'cart_name' => 'WooCommerce',
				'order_id' => $order_id,
				'xtl_order_id' => $order_id,
				'request_action' => 'CCAUTHCAP',
				'save_card_on_file' => 'Y',
				'callback_url'	=> $this->notify_url
			);
				
			$params         = array_merge($order_param, $this->get_versions(), $this->get_cart_total(), $this->get_cart_subtotal(), $this->get_shipping_total(), $this->get_discount_total());
			$merchant_info  = $this->merchant_credential_new();
			$encrypt_param  = $this->encrypt_card_info($params['pmt_numb'], $params['pmt_key'], $params['pmt_expiry']);
			$params         = array_merge($params, $encrypt_param);
			$payloadHash    = generateSignatureHash($params, $merchant_info['bf_hash_salt']);

			
			// write_logs_bf('$params 1');
			// write_logs_bf(print_r($params, true));

			$url  = $this->api_endpoint_token;

			$args = array(
				'body' => http_build_query($params),
				'headers'     => array(
					'Content-Type' => 'application/x-www-form-urlencoded',
					'Authorization' => 'Bearer ' . $merchant_info['bf_access_token'],
					'X-Bankful-Hmac-SHA256' => $payloadHash,
				),
			);

			$response = bankful_remote_post($url, $args);

			$body = wp_remote_retrieve_body($response);

			$this->log('====================== Payment Method Updated Body Response: ' . print_r($body, true), 'info');

			if (!is_wp_error($response)) {

				$bodyArr = $body;
				$body = json_decode($body, false);
				$bodyArr = json_decode($bodyArr, true);
				if (verifyHashSignatureFromRequest($bodyArr['data'])) {
					if (
							isset($body->status)
							&& isset($body->data)
							&& 'success' == $body->status

						) {
						$body = $body->data;
						$this->log('====================== Payment Method Updated for Order ID : ' . $order_id, 'info');
						$this->log('====================== Payment Method Updated Body Response: ' . print_r($body, true), 'info');
						$this->log('====================== Payment Method Updated $body->CUSTOMER_VAULT_ID1 : ' . $body->CUSTOMER_VAULT_ID, 'info');

						// Add order note
						if (isset($body->CUSTOMER_VAULT_ID) && $body->CUSTOMER_VAULT_ID) {
							$this->log('====================== Payment Method Updated $body->CUSTOMER_VAULT_ID : ' . $body->CUSTOMER_VAULT_ID, 'info');
							$order->update_meta_data( '_bankful_customer_id', $body->CUSTOMER_VAULT_ID );
						
							if ( is_callable( array( $order, 'save' ) ) ) {
								$order->save();
							}
							

							$order_id = $order->get_id();

							// Also store it on the subscriptions being purchased or paid for in the order
							if ( function_exists( 'wcs_order_contains_subscription' ) && wcs_order_contains_subscription( $order_id ) ) {

								$this->log('====================== update Payment in wcs_order_contains_subscription Subscription is True: ', 'info');
								$subscriptions = wcs_get_subscriptions_for_order( $order_id );
								$this->is_subscription = true;

							} elseif ( function_exists( 'wcs_order_contains_renewal' ) && wcs_order_contains_renewal( $order_id ) ) {

								$this->log('====================== update Payment in wcs_order_contains_renewal Subscription is True: ', 'info');
								$subscriptions = wcs_get_subscriptions_for_renewal_order( $order_id );
								$this->is_subscription = true;

							} else {

								$this->log('====================== update Payment in wcs_order_contains_renewal Subscription is False: ', 'info');
								$subscriptions = array();
								$this->is_subscription = false;

							}

							foreach ( $subscriptions as $subscription ) {
								$subscription->add_order_note('Payment Method Updated, New Customer Vault ID:' . $body->CUSTOMER_VAULT_ID);
								$subscription->update_meta_data( '_bankful_customer_id', $body->CUSTOMER_VAULT_ID );
								// Update the payment method.
								if ( ! empty( $this->id ) ) {
									$subscription->set_payment_method( $this->id );
								}
								$subscription->save();
							}

						}
						// Redirect to the thank you page
						return array(
							'result' => 'success',
							'redirect' => $this->get_return_url($order),
						);
					} else if (!empty($body->status) && 'failed' == $body->status) {

						// Add note.
						/* translators: %s: Transaction ID */
						$order->add_order_note(sprintf(__('Payment Method update failed %s', 'wc_iveri'), $body->errorMessage));

						$this->log('Payment Method update failed', 'error');
						$this->log(print_r($body, true), 'error');

						$error_message = 'Something went wrong, please contact to your service provider.';

						throw new Exception(__($error_message, 'bankful'));
					}
				} else {
					/* translators: %s: Transaction ID */
					$order->add_order_note(__('Payment Method update failed', 'wc_iveri'));

					$this->log('Payment Method update failed', 'error');
					$this->log(print_r($body, true), 'error');

					$error_message = 'Something went wrong, please contact to your service provider.';

					throw new Exception(__($error_message, 'bankful'));
				}
			} else {
				wc_add_notice('Connection error.', 'error');
			}
		} catch (Exception $ex) { // Add log
			$this->log('ERROR Throws Exception', 'info');
			$this->log($ex->getMessage(), 'error');

			wc_add_notice($ex->getMessage(), 'error');
			return array(
				'result' => 'failed',
				'redirect' => $this->get_return_url($order),
				'message' => $ex->getMessage(),
			);
		}
		return array(
			'result' => 'failed',
			'redirect' => $this->get_return_url($order),
		);
	}


	/**
	 * Schedule Subscription for Payment
	 *
	 * @param int $order_id Order ID.
	 * 
	 */
	public function scheduled_subscription_payment( $amount_to_charge, $renewal_order ) {
		$this->process_subscription_payment($amount_to_charge, $renewal_order);
	}

	/**
	 * Get Merchant Credentials from DB By Using API Key and Secret
	 * 
	 * @return array
	 */
	public function merchant_credential_new() {
		$result = getBankfulToken();
		if ( ! empty( $result ) ) {
			$request_params = array(
				'bf_access_token' => $result['bf_access_token'],
				'bf_public_key' => $result['bf_public_key'],
				'bf_hash_salt' => $result['bf_hash_salt'],
			);
		} else {
			throw new Exception(
				esc_html(
					'Merchant not configured correctly, please contact Bankful support, Thanks.',
					'bankful_credit_card'
				)
			);
		}
		
		$finalRequestParams = array();

		foreach ($request_params as $reqKey => $reqParamVal) {
			if (empty($request_params[$reqKey])) {
				throw new Exception(
					esc_html(
						'Merchant not configured correctly, please contact Bankful support, Thanks.',
						'bankful_credit_card'
					)
				);
			}

			$finalRequestParams[$reqKey] = trim($reqParamVal);
		}

		return $finalRequestParams;
	}

	/**
	 * Encrypt card information using public key 
	 * 
	 * @return array
	 */
	public function encrypt_card_info( $pmt_num, $pmt_key, $pmt_expiry ) {
		$result  = $this->merchant_credential_new();
		$finalRequestParams = array();
		if ( ! empty( $result ) ) {
			$bf_public_key = $result['bf_public_key'];
			$finalRequestParams['pmt_numb']   = encryptPayload($pmt_num, $bf_public_key);
			$finalRequestParams['pmt_key']    = encryptPayload($pmt_key, $bf_public_key);
			$finalRequestParams['pmt_expiry'] = encryptPayload($pmt_expiry, $bf_public_key);
		} else {
			throw new Exception(
				esc_html(
					'Merchant not configured correctly, please contact Bankful support, Thanks.',
					'bankful_credit_card'
				)
			);
		}
		return $finalRequestParams;
	}
}
