<?php

defined('ABSPATH') || exit;

require_once plugin_dir_path(__FILE__) . 'class-primer-payments-gateway-helpers.php';

class PrimerPaymentFunctions {

    private $PrimerPaymentHelpers;

    private $PrimerPaymentGateway;

    private bool $has_wc_subscriptions;

    private bool $primer_payments_enabled;

    public function __construct() {
        $this->PrimerPaymentHelpers    = new PrimerPaymentHelpers();
        $this->PrimerPaymentGateway    = get_option('woocommerce_piraeusbank_gateway_settings');
        $this->has_wc_subscriptions    = class_exists('WC_Subscription');
        $this->primer_payments_enabled = get_option('primer_generals')['primer_payments_gateway'] === 'on' ? true : false;

        $payment_switch = false;

        if ($payment_switch && $this->primer_payments_enabled) {
            add_action("wp_ajax_continue_3ds_method", array($this, 'continue_3ds_method'));
            add_action('wp_ajax_nopriv_continue_3ds_method', array($this, 'continue_3ds_method'));
            add_action("wp_ajax_finalize_3ds_method", array($this, 'finalize_3ds_method'));
            add_action('wp_ajax_nopriv_finalize_3ds_method', array($this, 'finalize_3ds_method'));
            add_action("wp_ajax_process_payment_with_token_3ds", array($this, 'process_payment_with_token_3ds'));
            add_action('wp_ajax_nopriv_process_payment_with_token_3ds', array($this, 'process_payment_with_token_3ds'));
            add_action('woocommerce_api_wc_piraeusbank_gateway', array($this, 'check_piraeusbank_response'));
        }
    }

    public function generate_piraeusbank_form($order_id) {
        global $woocommerce;
        global $wpdb;

        $order = wc_get_order($order_id);

        $installments         = 1;
        $installments_allowed = $order->get_meta('is_using_installments_payment') ?? false;

        if ($installments_allowed) {
            $installments = $order->get_meta('installments');
        }

        if (get_post_meta($order_id, 'is_using_saved_payment', true) == 'true' && !$installments_allowed) {
            echo $this->show3ds_modal(null, null);

            $wc_token = \WC_Payment_Tokens::get(get_post_meta($order_id, 'saved_token_id', true));

            if ($wc_token) {
                $order  = wc_get_order($order_id);
                $token  = explode('-', $wc_token->get_token());
                $amount = $order->get_total();

                if ($this->has_wc_subscriptions && wcs_is_subscription($order_id)) {
                    $amount = 0;
                }

                $verify_secure = $this->open_3d_secure($token[0], $amount, $order_id);

                echo $verify_secure;

                if ($verify_secure['result'] == 'fail') {
                    return $verify_secure;
                } elseif ($verify_secure['result'] == 'success') {
                    $response = $this->do_transaction_with_token($token[0], $token[1], $amount, $order_id, $wc_token->get_card_type(), $verify_secure);

                    if ($response->Body->TransactionInfo->StatusFlag == "Success") {
                        $message      = __('Η συναλλαγή σας ήταν επιτυχής, η πληρωμή ελήφθη.', 'primer');
                        $message_type = 'success';

                        $wc_token->set_token($wc_token->get_token() . '-' . $response->Body->TransactionInfo->TraceID);
                        $wc_token->set_default(true);
                        $wc_token->save();

                        $transaction_info   = $response->Body->TransactionInfo;
                        $SupportReferenceID = strval($transaction_info->RetrievalRef);
                        $TransactionID      = strval($transaction_info->TransactionID);
                        $MerchantReference  = strval($transaction_info->MerchantReference);
                        $card_number        = strval($transaction_info->MaskedCard);

                        $wpdb->insert($wpdb->prefix . 'piraeusbank_transactions', array(
                                'trans_ticket' => $TransactionID,
                                'merch_ref'    => $MerchantReference,
                                'order_id'     => $order->get_id(),
                                'timestamp'    => current_time('mysql', 1)
                        ));

                        $order->add_order_note(__('Payment Via Peiraeus Bank (follow-up).', 'primer') . '<br />MerchantReference: ' . $MerchantReference . ', SupportReferenceID: ' . $SupportReferenceID . ', Transaction ID: ' . $TransactionID . ', Amount: ' . $amount);
                        $order->set_transaction_id($TransactionID);

                        update_post_meta($order->get_id(), '_piraeus_source_id', $wc_token->get_id());
                        update_post_meta($order->get_id(), '_piraeus_card_id', $card_number);

                        if ($this->has_wc_subscriptions && $this->PrimerPaymentHelpers->has_subscription($order_id)) {
                            if (function_exists('wcs_order_contains_subscription') && wcs_order_contains_subscription($order_id)) {
                                $subscriptions = wcs_get_subscriptions_for_order($order_id);
                            } elseif (function_exists('wcs_order_contains_renewal') && wcs_order_contains_renewal($order_id)) {
                                $subscriptions = wcs_get_subscriptions_for_renewal_order($order_id);
                            } else {
                                $subscriptions = [];
                            }

                            foreach ($subscriptions as $subscription) {
                                $subscription_id = $subscription->get_id();
                                update_post_meta($subscription_id, '_piraeus_card_id', $card_number);
                                update_post_meta($subscription_id, '_piraeus_source_id', $wc_token->get_id());
                            }
                        }

                        $order->save();
                        WC()->cart->empty_cart();
                        $order->payment_complete();

                        wc_add_notice($message, $message_type);
                        do_action('primer_woocommerce_piraeus_bank_success', $order->get_id());
                        $redirect_url = $this->PrimerPaymentHelpers->get_return_url($order);
                        wp_redirect($redirect_url);

                        exit;
                    } else {
                        $error_message = $response->Header->ResultDescription;

                        if ($this->has_wc_subscriptions || !wcs_is_subscription($order_id)) {
                            $order->update_status('failed');
                        }

                        wc_add_notice(__('Payment error:', 'woothemes') . 'Υπήρξε σφάλμα κατά την πληρωμή. Παρακαλώ ξαναδοκιμάστε με νέα μέθοδο πληρωμής. ' . $error_message, 'error');

                        if ($this->has_wc_subscriptions && wcs_is_subscription($order_id)) {
                            $redirect_url = $order->get_view_order_url();
                            wp_redirect($redirect_url);
                            exit;
                        } else {
                            $checkout_url = wc_get_checkout_url();
                            wp_redirect($checkout_url);
                            exit;
                        }
                    }
                } else {
                    exit;
                }
            } else {
                wc_add_notice(__('Payment error:', 'woothemes') . 'Υπήρξε σφάλμα κατά την πληρωμή. Παρακαλώ ξαναδοκιμάστε με νέα μέθοδο πληρωμής', 'error');
                if ($this->has_wc_subscriptions && wcs_is_subscription($order_id)) {
                    $redirect_url = $order->get_view_order_url();
                    wp_redirect($redirect_url);
                    exit;
                } else {
                    $checkout_url = wc_get_checkout_url();
                    wp_redirect($checkout_url);
                    exit;
                }
            }
        }

        if ($order->get_total() == 0) {
            $requestType   = '00';
            $ExpirePreauth = '30';
        } else {
            $requestType   = '02';
            $ExpirePreauth = '0';
        }

        $order_amount = $order->get_total();
        $currency          = get_woocommerce_currency();
        $MerchantReference = uniqid("$order_id-");

        try {
            $soap             = new SoapClient("https://paycenter.piraeusbank.gr/services/tickets/issuer.asmx?WSDL");
            $billing_address  = $this->PrimerPaymentHelpers->split(preg_replace("/[^\p{L}\p{N}\p{Z}_]/u", '', $order->get_billing_address_1()), 50);
            $shipping_address = $this->PrimerPaymentHelpers->split(preg_replace("/[^\p{L}\p{N}\p{Z}_]/u", '', ($order->get_shipping_address_1() ? $order->get_shipping_address_1() : $order->get_billing_address_1())), 50);

            $ticketRequest = array(
                    'Username'            => $this->PrimerPaymentGateway['pb_Username'],
                    'Password'            => hash('md5', $this->PrimerPaymentGateway['pb_Password']),
                    'MerchantId'          => $this->PrimerPaymentGateway['pb_PayMerchantId'],
                    'PosId'               => apply_filters('primer_custom_pos_id', $this->PrimerPaymentGateway['pb_PosId']),
                    'AcquirerId'          => $this->PrimerPaymentGateway['pb_AcquirerId'],
                    'MerchantReference'   => $MerchantReference,
                    'RequestType'         => $requestType,
                    'AccountVerification' => 1,
                    'ExpirePreauth'       => $ExpirePreauth,
                    'Amount'              => $order_amount,
                    'CurrencyCode'        => $this->PrimerPaymentHelpers->currencyCode[$currency],
                    'Installments'        => $installments,
                    'Bnpl'                => 0,
                    'Parameters'          => '',
                    'BillAddrCity'        => mb_substr($order->get_billing_city(), 0, 50),
                    'BillAddrCountry'     => $this->PrimerPaymentHelpers->convert_alpha_2_to_code($order->get_billing_country()),
                    'BillAddrLine1'       => $billing_address[0] ?? '',
                    'BillAddrLine2'       => $billing_address[1] ?? '',
                    'BillAddrLine3'       => $billing_address[2] ?? '',
                    'BillAddrPostCode'    => $order->get_billing_postcode(),
                    'BillAddrState'       => $order->get_billing_country() == 'GR' ? $order->get_billing_state() : '',
                    'ShipAddrCity'        => mb_substr(!empty($order->get_shipping_city()) ? $order->get_shipping_city() : $order->get_billing_city(), 0, 50),
                    'ShipAddrCountry'     => $this->PrimerPaymentHelpers->convert_alpha_2_to_code($order->get_shipping_country()),
                    'ShipAddrLine1'       => $shipping_address[0] ?? '',
                    'ShipAddrLine2'       => $shipping_address[1] ?? '',
                    'ShipAddrLine3'       => $shipping_address[2] ?? '',
                    'ShipAddrPostCode'    => $order->get_shipping_postcode() ? $order->get_shipping_postcode() : $order->get_billing_postcode(),
                    'ShipAddrState'       => $order->get_billing_country() == 'GR' ? ($order->get_shipping_state() ? $order->get_shipping_state() : $order->get_billing_state()) : '',
                    'CardholderName'      => apply_filters('primer_piraeusbank_custom_cardholder', $this->PrimerPaymentHelpers->attempt_transliteration("{$order->get_billing_first_name()} {$order->get_billing_last_name()}")),
                    'Email'               => $order->get_billing_email(),
                    'HomePhone'           => $this->PrimerPaymentHelpers->itu_e164(apply_filters('primer_piraeusbank_custom_home_phone', $order->get_billing_phone()), $order->get_billing_country()),
                    'MobilePhone'         => $this->PrimerPaymentHelpers->itu_e164(apply_filters('primer_piraeusbank_custom_mobile_phone', $order->get_billing_phone()), $order->get_billing_country()),
                    'WorkPhone'           => $this->PrimerPaymentHelpers->itu_e164(apply_filters('primer_piraeusbank_custom_work_phone', $order->get_billing_phone()), $order->get_billing_country()),
            );

            if (in_array('primer-greek-states-and-cities/primer-greek-states-and-cities.php', apply_filters('active_plugins', get_option('active_plugins'))) || in_array('primer-greek-states-based-shipping/primer-greek-states-and-cities.php', apply_filters('active_plugins', get_option('active_plugins')))) {
                $ticketRequest['BillAddrState'] = $this->PrimerPaymentHelpers->prefecture_to_state($order->get_billing_state());
                $ticketRequest['ShipAddrState'] = $this->PrimerPaymentHelpers->prefecture_to_state($order->get_shipping_state() ? $order->get_shipping_state() : $order->get_billing_state());
            }

            if ($order->get_billing_country() != "GR") {
                unset($ticketRequest['BillAddrState']);
                unset($ticketRequest['ShipAddrState']);
            }

            if ($order->get_total() != 0) {
                unset($ticketRequest['AccountVerification']);
            }

//            if ($this->PrimerPaymentHelpers->has_subscription($order)) {
//                $ticketRequest['RecurringInd']      = 'C';
//                $ticketRequest['RecurPurchaseDate'] = '';
//                $ticketRequest['RecurFreq']         = '';
//                $ticketRequest['RecurEnd']          = '';
//            }
//
//            if ($this->has_wc_subscriptions && function_exists('wcs_is_subscription')) {
//                if (wcs_is_subscription($order_id)) {
//                    $ticketRequest['RequestType']         = '00';
//                    $ticketRequest['ExpirePreauth']       = '30';
//                    $ticketRequest['AccountVerification'] = 1;
//                }
//            }

            $xml = array('Request' => $ticketRequest);

            /** @noinspection PhpUndefinedMethodInspection */
            $oResult = $soap->IssueNewTicket($xml);

            if ($oResult->IssueNewTicketResult->ResultCode == 0) {
                $wpdb->insert($wpdb->prefix . 'piraeusbank_transactions', array(
                        'trans_ticket' => $oResult->IssueNewTicketResult->TranTicket,
                        'merch_ref'    => $MerchantReference,
                        'order_id'     => $order->get_id(),
                        'timestamp'    => current_time('mysql', 1)
                ));

                wc_enqueue_js('jQuery.blockUI({
						message: "' . esc_js(apply_filters('primer_piraeusbank_custom_javascript_message', __('Thank you for your order. We are now redirecting you to Piraeus Bank to make payment.', 'primer-woocommerce-piraeus-payment-gateway'))) . '",
						baseZ: 99999,
						overlayCSS: {
							background: "#fff",
							opacity: 0.6
						},
						css: {
                            width: "100%",
                            "max-width": "600px",
                            padding: "20px",
                            zIndex: "9999999",
                            left: "50%",
                            transform: "translate(-50%, 0)",
                            textAlign: "center",
                            color: "#555",
                            border: "3px solid #aaa",
                            backgroundColor: "#fff",
                            cursor: "wait",
                            lineHeight: "24px",
                        }
					});
				    jQuery("#submit_pb_payment_form").click(); ');

                $language_code_allowed = array("el-GR", "en-US", "ru-RU", "de-DE");

                $LanCode = get_locale();
                $LanCode = $LanCode == "el" ? "el-GR" : (!in_array($LanCode, $language_code_allowed) ? "en-US" : $LanCode);

                $checkout_url = wc_get_checkout_url();
                $cancel_url   = 'wc-api=wc_piraeusbank_gateway&peiraeus=cancel';
                return '<form action="' . esc_url("https://paycenter.piraeusbank.gr/redirection/pay.aspx") . '" method="post" id="pb_payment_form" target="_top">
                            <input type="hidden" id="AcquirerId" name="AcquirerId" value="' . esc_attr($this->PrimerPaymentGateway['pb_AcquirerId']) . '"/>
                            <input type="hidden" id="MerchantId" name="MerchantId" value="' . esc_attr($this->PrimerPaymentGateway['pb_PayMerchantId']) . '"/>
                            <input type="hidden" id="PosID" name="PosID" value="' . esc_attr(apply_filters('primer_custom_pos_id', $this->PrimerPaymentGateway['pb_PosId'])) . '"/>
                            <input type="hidden" id="User" name="User" value="' . esc_attr($this->PrimerPaymentGateway['pb_Username']) . '"/>
                            <input type="hidden" id="LanguageCode"  name="LanguageCode" value="' . $LanCode . '"/>
                            <input type="hidden" id="MerchantReference" name="MerchantReference"  value="' . esc_attr($MerchantReference) . '"/>
                            <input type="hidden" id="ParamBackLink" name="ParamBackLink" value="' . $cancel_url . '"/>
                            <div class="payment_buttons">
                                <input type="submit" class="button alt" id="submit_pb_payment_form" value="' . __('Pay via Pireaus Bank', 'primer') . '" /> <a class="button cancel" href="' . $checkout_url . '">' . __('Cancel order &amp; restore cart', 'primer') . '</a>

                            </div>
                            <script type="text/javascript">
                            jQuery(".payment_buttons").hide();
                            </script>
                         </form>';
            } else {
                $resultCode        = $oResult->IssueNewTicketResult->ResultCode;
                $resultDescription = $oResult->IssueNewTicketResult->ResultDescription;

                $error_message = $this->get_payment_error_message($resultCode);

//              $order->add_order_note($error_message . __('Payment Via Peiraeus Bank', 'primer-woocommerce-piraeus-payment-gateway') . '<br />MerchantReference: ' . $MerchantReference . ', SupportReferenceID: ' . $SupportReferenceID . ', Transaction ID: ' . $TransactionID);
//              update_post_meta($order_id, '_piraeus_comments', $error_message . __('Payment Via Peiraeus Bank', 'primer-woocommerce-piraeus-payment-gateway') . '<br />MerchantReference: ' . $MerchantReference . ', SupportReferenceID: ' . $SupportReferenceID . ', Transaction ID: ' . $TransactionID);

                $message_type = 'error';

                wc_add_notice($error_message, $message_type);
                $redirect_url = wc_get_checkout_url();
                wp_redirect($redirect_url);

                exit;
            }
        } catch (SoapFault $fault) {
            $order->add_order_note(__('Error' . $fault, ''));
            return __('Error' . $fault, '');
        }
    }

    public function check_piraeusbank_response() {
        global $woocommerce;
        global $wpdb;

        $order = null;

        if (isset($_GET['peiraeus']) && ($_GET['peiraeus'] == 'success')) {
            $ResultCode         = $_REQUEST['ResultCode'];
            $ResponseCode       = $_REQUEST['ResponseCode'];
            $StatusFlag         = $_REQUEST['StatusFlag'];
            $HashKey            = $_REQUEST['HashKey'];
            $SupportReferenceID = $_REQUEST['SupportReferenceID'];
            $TransactionID      = $_REQUEST['TransactionId'];
            $ApprovalCode       = $_REQUEST['ApprovalCode'];
            $Parameters         = $_REQUEST['Parameters'];
            $AuthStatus         = $_REQUEST['AuthStatus'];
            $PackageNo          = $_REQUEST['PackageNo'];
            $MerchantReference  = $_REQUEST['MerchantReference'];
            $token              = $_REQUEST['Token'];
            $trace_id           = $_REQUEST['TraceID'];
            $card_number        = $_REQUEST['CardNumber'];
            $first5Digits       = substr($card_number, 0, 5);
            $cleanUniqString    = explode("-", $_REQUEST['MerchantReference']);
            $exp_date           = explode('-', $_REQUEST['CardExpDate']);
            $exp_month          = $exp_date[0];
            $exp_year           = $exp_date[1];

            if (sizeof($cleanUniqString) > 1) {
                $order_id = $cleanUniqString[0];
            } else {
                $order_id = $MerchantReference;
            }

            $order = wc_get_order($order_id);

            if ($order === false) {
                return;
            }

            if ($ResultCode != 0) {
                $message      = $this->get_payment_error_message($ResultCode);
                $message_type = 'error';
                wc_add_notice($message, $message_type);
                $order->update_status('failed', '');
                $redirect_url = wc_get_checkout_url();
                wp_redirect($redirect_url);
                exit;
            }

            $ttquery      = 'SELECT trans_ticket FROM `' . $wpdb->prefix . 'piraeusbank_transactions` WHERE `merch_ref` = "' . $MerchantReference . '"	;';
            $tt           = $wpdb->get_results($ttquery);
            $transticket  = $tt['0']->trans_ticket;
            $stcon        = $transticket . apply_filters('primer_custom_pos_id', $this->PrimerPaymentGateway['pb_PosId']) . $this->PrimerPaymentGateway['pb_AcquirerId'] . $MerchantReference . $ApprovalCode . $Parameters . $ResponseCode . $SupportReferenceID . $AuthStatus . $PackageNo . $StatusFlag;
            $conhash      = strtoupper(hash('sha256', $stcon));
            $stcon_hmac   = $transticket . ";" . apply_filters('primer_custom_pos_id', $this->PrimerPaymentGateway['pb_PosId']) . ";" . $this->PrimerPaymentGateway['pb_AcquirerId'] . ";" . $MerchantReference . ";" . $ApprovalCode . ";" . $Parameters . ";" . $ResponseCode . ";" . $SupportReferenceID . ";" . $AuthStatus . ";" . $PackageNo . ";" . $StatusFlag;
            $conhash_hmac = strtoupper(hash_hmac('sha256', $stcon_hmac, $transticket));

            if ($conhash != $HashKey && $conhash_hmac != $HashKey) {
                $message      = __('Thank you for choosing us for your online shopping. <br />However, the transaction wasn\'t successful, payment wasn\'t received.', 'primer');
                $message_type = 'error';
                wc_add_notice($message, $message_type);
                if ($this->has_wc_subscriptions && !wcs_is_subscription($order_id)) {
                    $order->update_status('failed');
                }
                echo "Wrong hash" . $conhash;
                exit;
            } else {
                if ($ResponseCode == 0 || $ResponseCode == 8 || $ResponseCode == 10 || $ResponseCode == 16) {
                    $order->add_order_note(__('Payment Via Peiraeus Bank.', 'primer') . '<br />MerchantReference: ' . $MerchantReference . ', SupportReferenceID: ' . $SupportReferenceID . ', Transaction ID: ' . $TransactionID);
                    update_post_meta($order->get_id(), '_piraeus_comments', __('Payment Via Peiraeus Bank.', 'primer') . '<br />MerchantReference: ' . $MerchantReference . ', SupportReferenceID: ' . $SupportReferenceID . ', Transaction ID: ' . $TransactionID);
                    $message      = __('Η συναλλαγή σας ήταν επιτυχής, η πληρωμή ελήφθη.', 'primer');
                    $message_type = 'success';
                    $order->set_transaction_id($TransactionID);
                    $order->save();

//                    if ($order->get_user_id() && class_exists('WC_Payment_Token_CC') && $enabled_tokens === 'yes') {
//                        $wc_token = \WC_Payment_Tokens::get_tokens([
//                                'user_id' => $order->get_user_id(),
//                                'token'   => $token . '-',
//                                'limit'   => 1
//                        ]);
//                        if (!empty($wc_token)) {
//                            $token_obj = reset($wc_token);
//                            $token_obj->delete();
//                        }
//                        $wc_token = new WC_Payment_Token_CC();
//                        $wc_token->set_token($token . '-' . $trace_id);
//                        $wc_token->set_gateway_id('piraeusbank_gateway');
//                        $wc_token->set_card_type($this->PrimerPaymentHelpers->getCardNetwork($first5Digits));
//                        $wc_token->set_last4(substr($card_number, -4));
//                        $wc_token->set_expiry_month($exp_month);
//                        $wc_token->set_expiry_year($exp_year);
//                        $wc_token->set_user_id($order->get_user_id());
//                        $wc_token->set_default(true);
//                        $wc_token->save();
//
//                        update_post_meta($order->get_id(), '_piraeus_source_id', $wc_token->get_id());
//                        update_post_meta($order->get_id(), '_piraeus_card_id', $card_number);
//
//                        if ($this->has_wc_subscriptions && $this->PrimerPaymentHelpers->has_subscription($order_id)) {
//                            if (function_exists('wcs_order_contains_subscription') && wcs_order_contains_subscription($order_id)) {
//                                $subscriptions = wcs_get_subscriptions_for_order($order_id);
//                            } elseif (function_exists('wcs_order_contains_renewal') && wcs_order_contains_renewal($order_id)) {
//                                $subscriptions = wcs_get_subscriptions_for_renewal_order($order_id);
//                            } else {
//                                $subscriptions = [];
//                            }
//                            foreach ($subscriptions as $subscription) {
//                                $subscription_id = $subscription->get_id();
//                                update_post_meta($subscription_id, '_piraeus_card_id', $card_number);
//                                update_post_meta($subscription_id, '_piraeus_source_id', $wc_token->get_id());
//                            }
//                        }
//                    }

                    $enabled_tokens = $this->PrimerPaymentGateway['pb_enabled_save_payment_token'] === 'yes' ? true : false;

                    $cart       = WC()->cart;
                    $order_card = $cart ? $cart->get_cart() : null;
                    foreach ($order_card as $cart_item) {
                        $product = $cart_item['data'];
                        $product->get_type();
                        if ($product->get_type() === 'subscription') {
                            $enabled_tokens = true;
                            break;
                        }
                    }

                    if ($enabled_tokens && $order->get_user_id() && class_exists('WC_Payment_Token_CC')) {
                        $existing_tokens = \WC_Payment_Tokens::get_tokens([
                            'user_id'    => $order->get_user_id(),
                            'gateway_id' => 'piraeusbank_gateway',
                            'type'       => 'CC',
                        ]);

                        $last4 = substr($card_number, -4);
                        foreach ($existing_tokens as $existing_token) {
                            if ($existing_token->get_last4() === $last4) {
                                $existing_token->delete();
                            }
                        }

                        $wc_token = new WC_Payment_Token_CC();
                        $wc_token->set_token($token . '-' . uniqid());
                        $wc_token->set_gateway_id('piraeusbank_gateway');
                        $wc_token->set_card_type($this->PrimerPaymentHelpers->getCardNetwork($first5Digits));
                        $wc_token->set_last4($last4);
                        $wc_token->set_expiry_month($exp_month);
                        $wc_token->set_expiry_year($exp_year);
                        $wc_token->set_user_id($order->get_user_id());
                        $wc_token->set_default(true);
                        $wc_token->save();

                        update_post_meta($order->get_id(), '_piraeus_source_id', $wc_token->get_id());
                        update_post_meta($order->get_id(), '_piraeus_card_id', $card_number);

                        if ($this->has_wc_subscriptions && $this->PrimerPaymentHelpers->has_subscription($order_id)) {
                            $subscriptions = [];
                            if (function_exists('wcs_order_contains_subscription') && wcs_order_contains_subscription($order_id)) {
                                $subscriptions = wcs_get_subscriptions_for_order($order_id);
                            } elseif (function_exists('wcs_order_contains_renewal') && wcs_order_contains_renewal($order_id)) {
                                $subscriptions = wcs_get_subscriptions_for_renewal_order($order_id);
                            }
                            foreach ($subscriptions as $subscription) {
                                $subscription_id = $subscription->get_id();
                                update_post_meta($subscription_id, '_piraeus_card_id', $card_number);
                                update_post_meta($subscription_id, '_piraeus_source_id', $wc_token->get_id());
                            }
                        }
                    }

                    $order->payment_complete();
                    do_action('primer_woocommerce_piraeus_bank_success', $order->get_id());

                    if ($this->has_wc_subscriptions && wcs_is_subscription($order_id)) {
                        wc_add_notice(__('Ο τρόπος πληρωμής ενημερώθηκε.', 'primer'));
                        $redirect_url = $order->get_view_order_url();
                    } else {
                        wc_add_notice($message, $message_type);
                        $redirect_url = $this->PrimerPaymentHelpers->get_return_url($order);
                    }
                    wp_redirect($redirect_url);
                    exit;
                } elseif ($ResponseCode == '11') {
                    $message      = __('Thank you for choosing us for your online shopping.<br />Your transaction was previously received.', 'primer');
                    $message_type = 'success';
                    wc_add_notice($message, $message_type);
                    do_action('primer_woocommerce_piraeus_bank_success', $order->get_id());
                    if ($this->has_wc_subscriptions && wcs_is_subscription($order_id)) {
                        wc_add_notice(__('Ο τρόπος πληρωμής ενημερώθηκε.', 'primer'));
                        $redirect_url = $order->get_view_order_url();
                    } else {
                        wc_add_notice($message, $message_type);
                        $redirect_url = $this->PrimerPaymentHelpers->get_return_url($order);
                    }
                    wp_redirect($redirect_url);
                    exit;
                } else {
                    $message      = __('Thank you for choosing us for your online shopping. <br />However, the transaction was declined by the Issuer, payment wasn\'t received. Please contact your bank or use another card.', 'primer');
                    $message_type = 'error';
                    wc_add_notice($message, $message_type);
                    do_action('primer_woocommerce_piraeus_bank_failed', $order->get_id());
                    $order->update_status('failed', '');
                    if (wcs_is_subscription($order_id)) {
                        wc_add_notice(__('Ο τρόπος πληρωμής ενημερώθηκε.', 'primer'));
                        $redirect_url = $order->get_view_order_url();
                    } else {
                        wc_add_notice($message, $message_type);
                        $redirect_url = $this->PrimerPaymentHelpers->get_return_url($order);
                    }
                    wp_redirect($redirect_url);
                    exit;
                }
            }
        }

        if (isset($_GET['peiraeus']) && ($_GET['peiraeus'] == 'fail')) {
            $ResultCode = $_REQUEST['ResultCode'];
            if (isset($_REQUEST['MerchantReference'])) {
                $MerchantReference  = $_REQUEST['MerchantReference'];
                $cleanUniqString    = explode("-", $_REQUEST['MerchantReference']);
                $SupportReferenceID = $_REQUEST['SupportReferenceID'];
                $TransactionID      = $_REQUEST['TransactionId'];
                if (sizeof($cleanUniqString) > 1) {
                    $order_id = $cleanUniqString[0];
                } else {
                    $order_id = $MerchantReference;
                }
                $order = wc_get_order($order_id);
                if ($order === false) {
                    $checkout_url = wc_get_checkout_url();
                    wp_redirect($checkout_url);
                    return;
                }

                $message = $this->get_payment_error_message($ResultCode);

                $order->add_order_note($message . __('Payment Via Peiraeus Bank', 'primer') . '<br />MerchantReference: ' . $MerchantReference . ', SupportReferenceID: ' . $SupportReferenceID . ', Transaction ID: ' . $TransactionID);
                update_post_meta($order->get_id(), '_piraeus_comments', $message . __('Payment Via Peiraeus Bank', 'primer') . '<br />MerchantReference: ' . $MerchantReference . ', SupportReferenceID: ' . $SupportReferenceID . ', Transaction ID: ' . $TransactionID);

                if ($this->has_wc_subscriptions && !wcs_is_subscription($order_id)) {
                    $order->update_status('failed');
                }

                $request_params = [];

                foreach ($_REQUEST as $key => $value) {
                    $request_params[$key] = $value;
                }

                $message_type = 'error';
                wc_add_notice($message, $message_type);
                $redirect_url = wc_get_checkout_url();
                wp_redirect($redirect_url);
                exit;
            } else {
                $checkout_url = wc_get_checkout_url();
                wp_redirect($checkout_url);
                exit;
            }
        }

        if (isset($_GET['peiraeus']) && $_GET['peiraeus'] === 'cancel') {
            wc_add_notice(__('Payment was cancelled. You can try again below.', 'primer'), 'notice');
            wp_safe_redirect(wc_get_checkout_url());
            exit;
        }

        $redirect_url = $this->PrimerPaymentHelpers->get_return_url($order);
        wp_redirect($redirect_url);

        exit;
    }

    public function open_3d_secure($token, $amount, $order_id) {
        $soapUrl           = "https://paycenter.piraeusbank.gr/services/Wrapper3DSecure.asmx";
        $MerchantReference = uniqid("$order_id-");

        delete_post_meta($order_id, 'MerchantReference');
        delete_post_meta($order_id, 'threeDSMethodResponseData');
        delete_post_meta($order_id, 'pares');
        delete_post_meta($order_id, 'cres');

        $xml_post_string = '<?xml version="1.0" encoding="utf-8"?>
                    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                      <soap12:Body>
                        <Process3DSecure xmlns="http://piraeusbank.gr/paycenter">
                          <requestData>
                               <Header>
                                    <MerchantInfo>
                                <AcquirerID>GR014</AcquirerID>
                                <MerchantID>' . $this->PrimerPaymentGateway['pb_PayMerchantId'] . '</MerchantID>	                              
                                <User>' . $this->PrimerPaymentGateway['pb_Username'] . '</User>
                                <Password>' . hash('md5', $this->PrimerPaymentGateway['pb_Password']) . '</Password>
                              </MerchantInfo>
                                    <RequestType>EnrollmentRequestInit</RequestType>                       
                                </Header>
                                <Body>
                                    <Request3DSInfo>
                                        <MerchantReference>' . $MerchantReference . '</MerchantReference>
                                         <PurchAmount>' . $this->PrimerPaymentHelpers->get_amount($amount) . '</PurchAmount>
                                         <Exponent>2</Exponent>
                                         <Currency>978</Currency>                                                       
                                        <Description>Payment with Saved Payment Method</Description>
                                        <Pan>' . $token . '</Pan>
                                        <Expiry xsi:nil="true" />                          
                                        <MD>' . $MerchantReference . '</MD>
                                        <Lang>el</Lang>
                                        <TermURL>' . $this->PrimerPaymentHelpers->get_site_url() . '/wp-json/piraeus/sendTerms</TermURL>
                                        <Pares xsi:nil="true" />
                                        <Cres xsi:nil="true" />
                                        <ThreeDSMethodNotificationURL>' . $this->PrimerPaymentHelpers->get_site_url() . '/wp-json/piraeus/send3dsMethodNotification?MerchantReference=' . $MerchantReference . '</ThreeDSMethodNotificationURL>     
                                        <ThreeDSCompInd xsi:nil="true" />
                                        <PanMode xsi:nil="true" />                    
                                        <MessageCategory>Payment</MessageCategory>
                                        <ChallengeWindowSize>W250H400</ChallengeWindowSize>                               
                                        <RequestBrowserBasedData>
                                         <UserAgent>' . $_SERVER['HTTP_USER_AGENT'] . '</UserAgent>    
                                        </RequestBrowserBasedData>                                                                                                   
                                        <RequestRecurringInfo>
                                            <RecurringInd>C</RecurringInd>
                                            <RecurPurchaseDate xsi:nil="true" />
                                            <RecurFreq xsi:nil="true" />
                                            <RecurEnd xsi:nil="true" />
                                        </RequestRecurringInfo>
                                        ' . ($amount == 0 ? "<ChallengeInd>04</ChallengeInd>" : '<ChallengeInd xsi:nil="true" />') . '
                                    </Request3DSInfo>
                                </Body>
                                </requestData>
                            </Process3DSecure>
                      </soap12:Body>
                    </soap12:Envelope>';

        $headers = array(
                "POST /services/Wrapper3DSecure.asmx HTTP/1.1",
                "Host: " . $_SERVER['SERVER_NAME'] . "",
                "Content-Type: application/soap+xml; charset=utf-8",
                "Content-Length: " . strlen($xml_post_string)
        );

        $url = $soapUrl;
        $ch  = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        $response = curl_exec($ch);
        $xml      = simplexml_load_string($response);

        $xml->registerXPathNamespace("soap", "http://www.w3.org/2003/05/soap-envelope");
        $resultCode = $xml->xpath('//soap:Body')[0]->Process3DSecureResponse->Response3DS->Header->ResultCode;

        if ($resultCode != 0) {
            $error_message = $xml->xpath('//soap:Body')[0]->Process3DSecureResponse->Response3DS->Header->ResultDescription;
            wc_add_notice(__('Payment error:', 'woothemes') . 'Υπήρξε σφάλμα κατά την πληρωμή. Παρακαλώ ξαναδοκιμάστε με νέα μέθοδο πληρωμής. ' . $error_message, 'error');
            $checkout_url = wc_get_checkout_url();
            wp_redirect($checkout_url);

            return [
                    'result'   => 'fail',
                    'redirect' => '',
            ];
        } else {
            update_post_meta($order_id, 'MerchantReference', $MerchantReference);
            $responseInfo = $xml->xpath('//soap:Body')[0]->Process3DSecureResponse->Response3DS->Body->Response3DSInfo;
            $md_status    = (int) $responseInfo->MdStatus;
            if ($md_status == 1 || $md_status == 2 || $md_status == 3 || $md_status == 4) {
                return [
                        'result'    => 'success',
                        'Eci'       => (string) $responseInfo->Eci,
                        'Cavv'      => (string) $responseInfo->Cavv,
                        'Xid'       => (string) $responseInfo->Xid,
                        'Protocol'  => (string) $responseInfo->Protocol,
                        'DsTransID' => (string) $responseInfo->DsTransID,
                ];
            } elseif ($md_status == 50) {
                $iframe = (string) $responseInfo->TDSMethodContent;
                echo $this->show_md50_modal($iframe, $order_id);
            } elseif ($md_status == 9) {
                $acs_form_data = $responseInfo->RedirectToACSFormData;
                ?>
                <script type="text/javascript">
                    const firstModal = document.getElementById("primer-modal");
                    firstModal.remove();
                </script>
                <?php

                echo $this->show3ds_modal($acs_form_data, $order_id);
            } else {
                $error_message = $responseInfo->MdErrorMsg;
                wc_add_notice(__('Payment error:', 'woothemes') . 'Υπήρξε σφάλμα κατά την πληρωμή. Παρακαλώ ξαναδοκιμάστε με νέα μέθοδο πληρωμής. ' . $error_message, 'error');
                $redirect_url = wc_get_checkout_url();
                wp_redirect($redirect_url);
                return [
                        'result'   => 'fail',
                        'redirect' => ''
                ];
            }
        }
    }

    public function show_md50_modal($iframe, $order_id) {
        if (!is_wc_endpoint_url('order-pay')) {
            return 'Όοουπς λάθος endpoint';
        }

        $order = wc_get_order($order_id);

        if (!$order) {
            error_log('No order with ID: ' . $order_id);
            return '';
        }

        $order_date     = $order->get_date_created() ? $order->get_date_created()->date('Y-m-d') : 'N/A';
        $order_total    = $order->get_formatted_order_total();
        $payment_method = $order->get_payment_method_title() ?: 'N/A';

        $html = '';
        $html .= get_header();
        $html .= '<div id="primer-modal" class="primer-modal primer-modal-3d no-select">
                    <div class="primer-modal-content">
                         <div class="primer-logo">
                            <img src="' . esc_url(plugin_dir_url(dirname(__FILE__)) . 'assets/primer_logo_pay.png') . '" alt="Primer Logo">
                        </div>
                        <h2 class="primer-modal-header">Ελέγχος ταυτότητας 3D Secure</h2>
                        <p class="primer-modal-subtitles">Ακολουθήστε τη διαδικασία ελέγχου ταυτότητας που απαιτείται από την εκδότρια Τράπεζα.</p>
                        <div class="primer-order-details">
                            <div class="primer-order-details-inner">
                                <div class="primer-box">
                                    <h3 class="primer-box-h3">Order Number:</h3>
                                    <h4 class="primer-box-h4">' . $order_id . '</h4>
                                </div>
                                <div class="primer-box">
                                     <h3 class="primer-box-h3">Date:</h3>
                                     <h4 class="primer-box-h4">' . $order_date . '</h4>
                                </div>
                                <div class="primer-box">
                                    <h3 class="primer-box-h3">Total:</h3>
                                    <h4 class="primer-box-h4">' . $order_total . '</h4>
                                </div>
                                <div class="primer-box" >
                                    <h3 class="primer-box-h3">Payment method:</h3>
                                    <h4 class="primer-box-h4">' . $payment_method . '</h4>
                                </div>
                            </div>
                        </div>
                        <div class="primer-modal-icon">
                            <img src="' . esc_url(plugin_dir_url(dirname(__FILE__)) . '/assets/visa-secure_blu_72dpi.jpg') . '" alt="Visa Secure" />
                            <img src="' . esc_url(plugin_dir_url(dirname(__FILE__)) . '/assets/mc_idcheck_hrz_pos_105px.png') . '" alt="Mastercard ID Check" />
                        </div>

                        <div class="primer-loading-banner">
                            <p>Παρακαλώ Περιμένετε...</p>
                            <div class="primer-loading-bar" style="display: flex; justify-content: center; gap: 5px; margin: 0 auto; max-width: 200px;">
                                <div class="primer-loading-box" style="animation: primer-loading 1.5s infinite ease-in-out;"></div>
                                <div class="primer-loading-box" style="animation: primer-loading 1.5s infinite ease-in-out 0.2s;"></div>
                                <div class="primer-loading-box" style="animation: primer-loading 1.5s infinite ease-in-out 0.4s;"></div>
                                <div class="primer-loading-box" style="animation: primer-loading 1.5s infinite ease-in-out 0.6s;"></div>
                            </div>
                        </div>
                        <iframe hidden="hidden" id="showAcs" ' . $iframe . '</iframe>
                    </div>
                 </div>';

        return $html;
    }

    public function show3ds_modal($iframe_data, $order_id): string {
        if (!is_wc_endpoint_url('order-pay')) {
            return 'Όοουπς λάθος endpoint';
        }

        $order = wc_get_order($order_id);

        if (!$order) {
            error_log('No order with ID: ' . $order_id);
            return '';
        }

        $order_date     = $order->get_date_created() ? $order->get_date_created()->date('Y-m-d') : 'N/A';
        $order_total    = $order->get_formatted_order_total();
        $payment_method = $order->get_payment_method_title() ?: 'N/A';

        $html = $iframe_src = '';
        if (!empty($iframe_data)) {
            $iframe_src = 'src="data:text/html;charset=utf-8,' . rawurlencode($iframe_data) . '"';
        }

        $html .= get_header();
        $html .= '<div id="primer-modal" class="primer-modal primer-modal-3d no-select">
                    <div class="primer-modal-content">
                         <div class="primer-logo">
                            <img src="' . esc_url(plugin_dir_url(dirname(__FILE__)) . 'assets/primer_logo_pay.png') . '" alt="Primer Logo">
                        </div>
                        <h2 class="primer-modal-header">Ελέγχος ταυτότητας 3D Secure</h2>
                        <p class="primer-modal-subtitles">Ακολουθήστε τη διαδικασία ελέγχου ταυτότητας που απαιτείται από την εκδότρια Τράπεζα.</p>
                        <div class="primer-order-details">
                            <div class="primer-order-details-inner">
                                <div class="primer-box">
                                    <h3 class="primer-box-h3">Order Number:</h3>
                                    <h4 class="primer-box-h4">' . $order_id . '</h4>
                                </div>
                                <div class="primer-box">
                                     <h3 class="primer-box-h3">Date:</h3>
                                     <h4 class="primer-box-h4">' . $order_date . '</h4>
                                </div>
                                <div class="primer-box">
                                    <h3 class="primer-box-h3">Total:</h3>
                                    <h4 class="primer-box-h4">' . $order_total . '</h4>
                                </div>
                                <div class="primer-box" >
                                    <h3 class="primer-box-h3">Payment method:</h3>
                                    <h4 class="primer-box-h4">' . $payment_method . '</h4>
                                </div>
                            </div>
                        </div>
                        <div class="primer-modal-icon">
                            <img src="' . esc_url(plugin_dir_url(dirname(__FILE__)) . '/assets/visa-secure_blu_72dpi.jpg') . '" alt="Visa Secure" />
                            <img src="' . esc_url(plugin_dir_url(dirname(__FILE__)) . '/assets/mc_idcheck_hrz_pos_105px.png') . '" alt="Mastercard ID Check" />
                        </div>

                        <div class="primer-loading-banner">
                            <p>Παρακαλώ Περιμένετε...</p>
                            <div class="primer-loading-bar" style="display: flex; justify-content: center; gap: 5px; margin: 0 auto; max-width: 200px;">
                                <div class="primer-loading-box" style="animation: primer-loading 1.5s infinite ease-in-out;"></div>
                                <div class="primer-loading-box" style="animation: primer-loading 1.5s infinite ease-in-out 0.2s;"></div>
                                <div class="primer-loading-box" style="animation: primer-loading 1.5s infinite ease-in-out 0.4s;"></div>
                                <div class="primer-loading-box" style="animation: primer-loading 1.5s infinite ease-in-out 0.6s;"></div>
                            </div>
                        </div>
                        <iframe id="showAcs" ' . $iframe_src . ' onload="document.querySelector(\'.primer-loading-banner\').style.display = \'none\'; this.style.display = \'block\';"></iframe>
                    </div>
                 </div>';

        return $html;
    }

    public function continue_3ds_method() {
        if (!isset($_POST['order_id'])) {
            wp_send_json(['type' => 'fail']);
        }

        $order_id = $_POST['order_id'];

        if (get_post_meta($order_id, 'threeDSMethodResponseData', true) == null && $_POST['timesCalled'] <= 10) {
            wp_send_json(['type' => 'fail']);
        }

        $MerchantReference = get_post_meta($order_id, 'MerchantReference', true);
        $order             = wc_get_order($order_id);
        $ThreeDSCompInd = 'N';

        if ($_POST['timesCalled'] <= 10) {
            $ThreeDSCompInd = 'Y';
        }

        $soapUrl = "https://paycenter.piraeusbank.gr/services/Wrapper3DSecure.asmx";

        $xml_post_string = '<?xml version="1.0" encoding="utf-8"?>
            <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
              <soap12:Body>
                <Process3DSecure xmlns="http://piraeusbank.gr/paycenter">
                  <requestData>
                       <Header>
                            <MerchantInfo>
                        <AcquirerID>GR014</AcquirerID>
                        <MerchantID>' . $this->PrimerPaymentGateway['pb_PayMerchantId'] . '</MerchantID>
                        <User>' . $this->PrimerPaymentGateway['pb_Username'] . '</User>
                        <Password>' . hash('md5', $this->PrimerPaymentGateway['pb_Password']) . '</Password>
                      </MerchantInfo>
                            <RequestType>EnrollmentRequestContinue</RequestType>
                        </Header>
                        <Body>
                            <Request3DSInfo>
                                <MerchantReference>' . $MerchantReference . '</MerchantReference>                        
                                <ThreeDSCompInd>' . $ThreeDSCompInd . '</ThreeDSCompInd>                                                
                            </Request3DSInfo>
                        </Body>
                        </requestData>
                    </Process3DSecure>
              </soap12:Body>
            </soap12:Envelope>';

        $headers = array(
                "POST /services/Wrapper3DSecure.asmx HTTP/1.1",
                "Host: " . $_SERVER['SERVER_NAME'] . "",
                "Content-Type: application/soap+xml; charset=utf-8",
                "Content-Length: " . strlen($xml_post_string)
        );

        $url = $soapUrl;
        $ch  = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        sleep(10);

        $response = curl_exec($ch);
        $xml      = simplexml_load_string($response);
        $xml->registerXPathNamespace("soap", "http://www.w3.org/2003/05/soap-envelope");

        $xml_response_header = $xml->xpath('//soap:Body')[0]->Process3DSecureResponse->Response3DS->Header;
        $xml_response_body   = $xml->xpath('//soap:Body')[0]->Process3DSecureResponse->Response3DS->Body->Response3DSInfo;

        if ($xml_response_header->ResultCode != 0) {
            $error_message = (string) $xml_response_header->ResultDescription;
            wc_add_notice(__('Payment error:', 'woothemes') . 'Υπήρξε σφάλμα κατά την πληρωμή. Παρακαλώ ξαναδοκιμάστε με νέα μέθοδο πληρωμής. ' . $error_message, 'error');
            if ($this->has_wc_subscriptions && wcs_is_subscription($order_id)) {
                wp_send_json([
                        'type'     => 'redirect',
                        'redirect' => $order->get_view_order_url()
                ]);
            } else {
                wp_send_json([
                        'type'     => 'redirect',
                        'redirect' => wc_get_checkout_url()
                ]);
            }
        } else {
            $md_status = (int) $xml_response_body->MdStatus;
            if ($md_status == 1 || $md_status == 2 || $md_status == 3 || $md_status == 4) {
                wp_send_json([
                        'type'   => 'success',
                        'action' => 'do_transaction',
                        'data'   => $xml_response_body
                ]);
            } elseif ($md_status == 9) {
                wp_send_json([
                        'type'    => 'showAcs',
                        'acsData' => (string) $xml_response_body->RedirectToACSFormData
                ]);
            } else {
                $error_message = (string) $xml_response_body->MdErrorMsg;
                wc_add_notice(__('Payment error:', 'woothemes') . 'Υπήρξε σφάλμα κατά την πληρωμή. Παρακαλώ ξαναδοκιμάστε με νέα μέθοδο πληρωμής. ' . $error_message, 'error');
                if ($this->has_wc_subscriptions && wcs_is_subscription($order_id)) {
                    wp_send_json([
                            'type'     => 'redirect',
                            'redirect' => $order->get_view_order_url()
                    ]);
                } else {
                    wp_send_json([
                            'type'     => 'redirect',
                            'redirect' => wc_get_checkout_url()
                    ]);
                }
            }
        }
    }

    public function finalize_3ds_method() {
        if (!isset($_POST['order_id'])) {
            wp_send_json(['type' => 'fail']);
        }

        $order_id = $_POST['order_id'];

        if (get_post_meta($order_id, 'pares', true) == null && get_post_meta($order_id, 'cres', true) == null) {
            wp_send_json(['type' => 'fail']);
        }

        $pares             = get_post_meta($order_id, 'pares', true);
        $cres              = get_post_meta($order_id, 'cres', true);
        $order             = wc_get_order($order_id);
        $MerchantReference = get_post_meta($order_id, 'MerchantReference', true);

        $soapUrl         = "https://paycenter.piraeusbank.gr/services/Wrapper3DSecure.asmx";
        $xml_post_string = '<?xml version="1.0" encoding="utf-8"?>
                <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                    <soap12:Body>
                        <Process3DSecure xmlns="http://piraeusbank.gr/paycenter">
                            <requestData>
                                <Header>
                                    <MerchantInfo>
                                        <AcquirerID>GR014</AcquirerID>
                                        <MerchantID>' . $this->PrimerPaymentGateway['pb_PayMerchantId'] . '</MerchantID>
                                        <User>' . $this->PrimerPaymentGateway['pb_Username'] . '</User>
                                        <Password>' . hash('md5', $this->PrimerPaymentGateway['pb_Password']) . '</Password>
                                    </MerchantInfo>
                                    <RequestType>PAResValidationRequest</RequestType>
                                </Header>
                                <Body>
                                    <Request3DSInfo>
                                        <MerchantReference>' . $MerchantReference . '</MerchantReference>   
                                        ' . ($pares != null ? "<Pares>{$pares}</Pares>" : '<Pares xsi:nil="true" />') . '
                                        ' . ($cres != null ? "<Cres>{$cres}</Cres>" : '<Cres xsi:nil="true" />') . '                           
                                    </Request3DSInfo>
                                </Body>
                            </requestData>
                        </Process3DSecure>
                    </soap12:Body>
                </soap12:Envelope>';

        $headers = array(
                "POST /services/Wrapper3DSecure.asmx HTTP/1.1",
                "Host: " . $_SERVER['SERVER_NAME'] . "",
                "Content-Type: application/soap+xml; charset=utf-8",
                "Content-Length: " . strlen($xml_post_string)
        );
        $url     = $soapUrl;
        $ch      = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        sleep(10);

        $response = curl_exec($ch);
        $xml      = simplexml_load_string($response);
        $xml->registerXPathNamespace("soap", "http://www.w3.org/2003/05/soap-envelope");

        $xml_response_header = $xml->xpath('//soap:Body')[0]->Process3DSecureResponse->Response3DS->Header;
        $xml_response_body   = $xml->xpath('//soap:Body')[0]->Process3DSecureResponse->Response3DS->Body->Response3DSInfo;

        if ($xml_response_header->ResultCode != 0) {
            $error_message = (string) $xml_response_header->ResultDescription;
            wc_add_notice(__('Payment error:', 'woothemes') . 'Υπήρξε σφάλμα κατά την πληρωμή. Παρακαλώ ξαναδοκιμάστε με νέα μέθοδο πληρωμής. ' . $error_message, 'error');
            if ($this->has_wc_subscriptions && wcs_is_subscription($order_id)) {
                wp_send_json([
                        'type'     => 'redirect',
                        'redirect' => $order->get_view_order_url()
                ]);
            } else {
                wp_send_json([
                        'type'     => 'redirect',
                        'redirect' => wc_get_checkout_url()
                ]);
            }
        } else {
            $md_status = (int) $xml_response_body->MdStatus;
            if ($md_status == 1 || $md_status == 2 || $md_status == 3 || $md_status == 4) {
                wp_send_json([
                        'type'   => 'success',
                        'action' => 'do_transaction',
                        'data'   => $xml_response_body
                ]);
            } else {
                $error_message = (string) $xml_response_body->MdErrorMsg;
                wc_add_notice(__('Payment error:', 'woothemes') . 'Υπήρξε σφάλμα κατά την πληρωμή. Παρακαλώ ξαναδοκιμάστε με νέα μέθοδο πληρωμής. ' . $error_message, 'error');
                if ($this->has_wc_subscriptions && wcs_is_subscription($order_id)) {
                    wp_send_json([
                            'type'     => 'redirect',
                            'redirect' => $order->get_view_order_url()
                    ]);
                } else {
                    wp_send_json([
                            'type'     => 'redirect',
                            'redirect' => wc_get_checkout_url()
                    ]);
                }
            }
        }
    }

    public function process_payment_with_token($order_id, $amount = 0) {
        global $wpdb;

        $renew_order = $order_id;
        $renew_id    = $renew_order->get_id();
        $wc_token_id = get_post_meta($renew_id, '_piraeus_source_id', true);
        $wc_token    = \WC_Payment_Tokens::get($wc_token_id);

        // Work here.
        if ($wc_token) {
            $token    = explode('-', $wc_token->get_token());
            $response = $this->do_transaction_with_token($token[0], $token[1], $amount, $renew_id, $wc_token->get_card_type());

            if ($response->Body->TransactionInfo->StatusFlag == "Success") {
                $message      = __('Η συναλλαγή σας ήταν επιτυχής, η πληρωμή ελήφθη.', 'primer');
                $message_type = 'success';

                $wc_token->set_default(true);
                $wc_token->save();

                $transaction_info   = $response->Body->TransactionInfo;
                $SupportReferenceID = strval($transaction_info->RetrievalRef);
                $TransactionID      = strval($transaction_info->TransactionID);
                $MerchantReference  = strval($transaction_info->MerchantReference);
                $card_number        = strval($transaction_info->MaskedCard);

                $wpdb->insert($wpdb->prefix . 'piraeusbank_transactions', array(
                        'trans_ticket' => $TransactionID,
                        'merch_ref'    => $MerchantReference,
                        'order_id'     => $renew_id,
                        'timestamp'    => current_time('mysql', 1)
                ));

                $renew_order->add_order_note(__('Payment Via Peiraeus Bank (follow-up).', 'primer') . '<br />MerchantReference: ' . $MerchantReference . ', SupportReferenceID: ' . $SupportReferenceID . ', Transaction ID: ' . $TransactionID . ', Amount: ' . $amount);
                $renew_order->set_transaction_id($TransactionID);

                update_post_meta($renew_order->get_id(), '_piraeus_source_id', $wc_token->get_id());
                update_post_meta($renew_order->get_id(), '_piraeus_card_id', $card_number);

                if ($this->has_wc_subscriptions && $this->PrimerPaymentHelpers->has_subscription($renew_id)) {
                    if (function_exists('wcs_order_contains_subscription') && wcs_order_contains_subscription($renew_id)) {
                        $subscriptions = wcs_get_subscriptions_for_order($renew_id);
                    } elseif (function_exists('wcs_order_contains_renewal') && wcs_order_contains_renewal($renew_id)) {
                        $subscriptions = wcs_get_subscriptions_for_renewal_order($renew_id);
                    } else {
                        $subscriptions = [];
                    }
                    foreach ($subscriptions as $subscription) {
                        $subscription_id = $subscription->get_id();
                        update_post_meta($subscription_id, '_piraeus_card_id', $card_number);
                        update_post_meta($subscription_id, '_piraeus_source_id', $wc_token->get_id());
                    }
                }
                $renew_order->save();
                $renew_order->payment_complete();
                $renew_order->add_order_note($message, $message_type);
            } else {
                $transaction_info = strval($response->Header);
                update_post_meta($renew_id, 'transaction_info', $transaction_info);
                $error_message = $response->Header->ResultDescription;
                $renew_order->update_status('failed');
                $renew_order->add_order_note(__('Payment error:', 'woothemes') . 'Υπήρξε σφάλμα κατά την πληρωμή. Παρακαλώ ξαναδοκιμάστε με νέα μέθοδο πληρωμής. ' . $error_message, 'error');
                $renew_order->save();
            }
        } else {
            $renew_order->add_order_note(__('Payment error:', 'woothemes') . 'Υπήρξε σφάλμα κατά την πληρωμή. No token found. Παρακαλώ ξαναδοκιμάστε με νέα μέθοδο πληρωμής', 'error');
            $renew_order->update_status('failed');
            $renew_order->save();
        }
    }

    public function do_transaction_with_token($token, $traceId, $amount, $order_id, $cardType, $threeDsecureResponse = null) {
        $soapUrl           = "https://paycenter.winbank.gr/services/paymentgateway.asmx";
        $MerchantReference = uniqid("$order_id-");
        $card_network      = $cardType == 'visa' ? '07' : '00';
        $xml_post_string   = '';

        if ($threeDsecureResponse != null) {
            $xml_post_string = '<?xml version="1.0" encoding="utf-8"?>
                <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                  <soap12:Body>
                    <ProcessTransaction xmlns="http://piraeusbank.gr/paycenter">
                      <TransactionRequest xmlns="http://piraeusbank.gr/paycenter/1.0">
                        <Header>
                          <RequestType>SALE</RequestType>
                          <MerchantInfo>
                            <AcquirerID>GR014</AcquirerID>
                            <MerchantID>' . $this->PrimerPaymentGateway['pb_PayMerchantId'] . '</MerchantID>
                            <PosID>' . $this->PrimerPaymentGateway['pb_PosId'] . '</PosID>
                            <ChannelType>3DSecure</ChannelType>
                            <User>' . $this->PrimerPaymentGateway['pb_Username'] . '</User>
                            <Password>' . hash('md5', $this->PrimerPaymentGateway['pb_Password']) . '</Password>
                          </MerchantInfo>
                        </Header>
                        <Body>
                            <TransactionInfo>                   
                            <MerchantReference>' . $MerchantReference . '</MerchantReference>                    
                            <TransactionReferenceID xsi:nil=" true" />                   
                            <EntryType xsi:nil=" true" />                    
                            <CurrencyCode>978</CurrencyCode>                    
                            <Amount>' . $amount . '</Amount>                                       
                            <Installments>0</Installments>                    
                            <ExpirePreauth xsi:nil=" true" />                    
                            <TipAmount xsi:nil=" true" />                    
                            <Bnpl xsi:nil=" true" />                   
                            <SessionKey xsi:nil=" true" />                   
                            <CardInfo>                   
                            <CardType>UNKNOWN</CardType>                    
                            <CardNumber>' . $token . '</CardNumber>                                      
                            <CardHolderName />                   
                            <ExpirationMonth xsi:nil=" true" />                      
                            <ExpirationYear xsi:nil=" true" />                       
                            <Aid xsi:nil=" true" />                    
                            <PinBlock xsi:nil=" true" />                   
                            <Track1 xsi:nil=" true" />                   
                            <Track2 xsi:nil=" true" />                    
                            </CardInfo>                    
                            <AuthInfo>                    
                            <Cavv>' . $threeDsecureResponse['Cavv'] . '</Cavv>                    
                            <Eci>' . $threeDsecureResponse['Eci'] . '</Eci>                   
                            <Xid>' . $threeDsecureResponse['Xid'] . '</Xid>                
                            <Enrolled>Undefined</Enrolled>                    
                            <PAResStatus>Unknown</PAResStatus>                   
                            <SignatureVerification>Undefined</SignatureVerification>                    
                            <Protocol>' . $threeDsecureResponse['Protocol'] . '</Protocol>                    
                            <DsTransID>' . $threeDsecureResponse['DsTransID'] . '</DsTransID>                  
                            <ProtocolFullVersion xsi:nil=" true" />                    
                            </AuthInfo>                   
                            <TaxCardNumber xsi:nil=" true" />                    
                            <WalletData xsi:nil=" true" />   
                            <TraceID xsi:nil=" true" />                  
                            <RecurringInd>C</RecurringInd>                                         
                            <RecurFreq xsi:nil=" true" />                    
                            <RequestBrowserBasedData xsi:nil=" true" />                   
                            <RequestBillingInfo xsi:nil=" true" />                    
                            <RequestShippingInfo xsi:nil=" true" />                   
                            <RequestContactInfo xsi:nil=" true" />                    
                            <DeviceCategory xsi:nil=" true" />                   
                            <AddressMatch xsi:nil=" true" />                   
                            <DeliveryTimeframe xsi:nil=" true" />                    
                            <ReorderItemsInd xsi:nil=" true" />                   
                            <PreOrderPurchaseInd xsi:nil=" true" />                    
                            <AuthMethod xsi:nil=" true" />                   
                            <AccountAgeInd xsi:nil=" true" />                   
                            <AccountChangeInd xsi:nil=" true" />                    
                            <AccountPwdChangeInd xsi:nil=" true" />                   
                            <ShipAddressUsageInd xsi:nil=" true" />                   
                            <SuspiciousAccActivity xsi:nil=" true" />                   
                            </TransactionInfo>
                            </Body>
                      </TransactionRequest>
                    </ProcessTransaction>
                  </soap12:Body>
                </soap12:Envelope>';
        } else {
            $xml_post_string = '<?xml version="1.0" encoding="utf-8"?>
                <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                  <soap12:Body>
                    <ProcessTransaction xmlns="http://piraeusbank.gr/paycenter">
                      <TransactionRequest xmlns="http://piraeusbank.gr/paycenter/1.0">
                        <Header>
                          <RequestType>SALE</RequestType>
                          <MerchantInfo>
                            <AcquirerID>GR014</AcquirerID>
                            <MerchantID>' . $this->PrimerPaymentGateway['pb_PayMerchantId'] . '</MerchantID>
                            <PosID>' . $this->PrimerPaymentGateway['pb_PosId'] . '</PosID>
                            <ChannelType>3DSecure</ChannelType>
                            <User>' . $this->PrimerPaymentGateway['pb_Username'] . '</User>
                            <Password>' . hash('md5', $this->PrimerPaymentGateway['pb_Password']) . '</Password>
                          </MerchantInfo>
                        </Header>
                        <Body>
                            <TransactionInfo>                   
                            <MerchantReference>' . $MerchantReference . '</MerchantReference>                    
                            <TransactionReferenceID xsi:nil=" true" />                   
                            <EntryType xsi:nil=" true" />                    
                            <CurrencyCode>978</CurrencyCode>                    
                            <Amount>' . $amount . '</Amount>                                       
                            <Installments>0</Installments>                    
                            <ExpirePreauth xsi:nil=" true" />                    
                            <TipAmount xsi:nil=" true" />                    
                            <Bnpl xsi:nil=" true" />                   
                            <SessionKey xsi:nil=" true" />                   
                            <CardInfo>                   
                            <CardType>UNKNOWN</CardType>                    
                            <CardNumber>' . $token . '</CardNumber>                                      
                            <CardHolderName />                   
                            <ExpirationMonth xsi:nil=" true" />                      
                            <ExpirationYear xsi:nil=" true" />                       
                            <Aid xsi:nil=" true" />                    
                            <PinBlock xsi:nil=" true" />                   
                            <Track1 xsi:nil=" true" />                   
                            <Track2 xsi:nil=" true" />                    
                            </CardInfo>                    
                            <AuthInfo>                    
                            <Cavv xsi:nil=" true" />                    
                            <Eci>' . $card_network . '</Eci>                   
                            <Xid xsi:nil=" true" />                  
                            <Enrolled>Undefined</Enrolled>                    
                            <PAResStatus>Unknown</PAResStatus>                   
                            <SignatureVerification>Undefined</SignatureVerification>                    
                            <Protocol>2</Protocol>                    
                            <DsTransID xsi:nil=" true" />                    
                            <ProtocolFullVersion xsi:nil=" true" />                    
                            </AuthInfo>                   
                            <TaxCardNumber xsi:nil=" true" />                    
                            <WalletData xsi:nil=" true" />   
                            <TraceID>' . $traceId . '</TraceID>                 
                            <RecurringInd>C</RecurringInd>                                         
                            <RecurFreq xsi:nil=" true" />                    
                            <RequestBrowserBasedData xsi:nil=" true" />                   
                            <RequestBillingInfo xsi:nil=" true" />                    
                            <RequestShippingInfo xsi:nil=" true" />                   
                            <RequestContactInfo xsi:nil=" true" />                    
                            <DeviceCategory xsi:nil=" true" />                   
                            <AddressMatch xsi:nil=" true" />                   
                            <DeliveryTimeframe xsi:nil=" true" />                    
                            <ReorderItemsInd xsi:nil=" true" />                   
                            <PreOrderPurchaseInd xsi:nil=" true" />                    
                            <AuthMethod xsi:nil=" true" />                   
                            <AccountAgeInd xsi:nil=" true" />                   
                            <AccountChangeInd xsi:nil=" true" />                    
                            <AccountPwdChangeInd xsi:nil=" true" />                   
                            <ShipAddressUsageInd xsi:nil=" true" />                   
                            <SuspiciousAccActivity xsi:nil=" true" />                   
                            </TransactionInfo>
                            </Body>
                      </TransactionRequest>
                    </ProcessTransaction>
                  </soap12:Body>
                </soap12:Envelope>';
        }

        $headers = array(
                "POST /services/TokenService.asmx HTTP/1.1",
                "Host: " . $_SERVER['SERVER_NAME'] . "",
                "Content-Type: application/soap+xml; charset=utf-8",
                "Content-Length: " . strlen($xml_post_string)
        );
        $url     = $soapUrl;
        $ch      = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $response = curl_exec($ch);
        $xml      = simplexml_load_string($response);
        $xml->registerXPathNamespace("soap", "http://www.w3.org/2003/05/soap-envelope");

        return $xml->xpath('//soap:Body')[0]->ProcessTransactionResponse->TransactionResponse;
    }

    public function process_payment_with_token_3ds() {
        global $wpdb;

        if (!isset($_POST['transaction_form_data']) || !isset($_POST['order_id'])) {
            wp_send_json(['type' => 'fail1']);
            exit;
        } else {
            $order_id = $_POST['order_id'];
            $order    = wc_get_order($order_id);

            $wc_token = \WC_Payment_Tokens::get(get_post_meta($order_id, 'saved_token_id', true));

            if (!$wc_token) {
                wp_send_json(['type' => 'fail2']);
                exit;
            }

            $transaction_form_data = $_POST['transaction_form_data'];
            $token                 = explode('-', $wc_token->get_token());
            $amount                = $order->get_total();

            if ($this->has_wc_subscriptions && wcs_is_subscription($order_id)) {
                $amount = 0;
            }

            $response = $this->send_transaction_with_token($token[0], $transaction_form_data, $amount);

            if ($response->Body->TransactionInfo->StatusFlag == "Success") {
                $message      = __('Η συναλλαγή σας ήταν επιτυχής, η πληρωμή ελήφθη.', 'primer');
                $message_type = 'success';
                $wc_token->set_token($wc_token->get_token() . '-' . $response->Body->TransactionInfo->TraceID);
                $wc_token->set_default(true);
                $wc_token->save();
                $transaction_info   = $response->Body->TransactionInfo;
                $SupportReferenceID = strval($transaction_info->RetrievalRef);
                $TransactionID      = strval($transaction_info->TransactionID);
                $MerchantReference  = strval($transaction_info->MerchantReference);
                $card_number        = strval($transaction_info->MaskedCard);

                $wpdb->insert($wpdb->prefix . 'piraeusbank_transactions', array(
                        'trans_ticket' => $TransactionID,
                        'merch_ref'    => $MerchantReference,
                        'order_id'     => $order->get_id(),
                        'timestamp'    => current_time('mysql', 1)
                ));
                $order->add_order_note(__('Payment Via Peiraeus Bank (follow-up).', 'primer') . '<br />MerchantReference: ' . $MerchantReference . ', SupportReferenceID: ' . $SupportReferenceID . ', Transaction ID: ' . $TransactionID . ', Amount: ' . $amount);
                $order->set_transaction_id($TransactionID);

                update_post_meta($order->get_id(), '_piraeus_source_id', $wc_token->get_id());
                update_post_meta($order->get_id(), '_piraeus_card_id', $card_number);

                if ($this->has_wc_subscriptions && $this->PrimerPaymentHelpers->has_subscription($order_id)) {
                    if (function_exists('wcs_order_contains_subscription') && wcs_order_contains_subscription($order_id)) {
                        $subscriptions = wcs_get_subscriptions_for_order($order_id);
                    } elseif (function_exists('wcs_order_contains_renewal') && wcs_order_contains_renewal($order_id)) {
                        $subscriptions = wcs_get_subscriptions_for_renewal_order($order_id);
                    } else {
                        $subscriptions = [];
                    }
                    foreach ($subscriptions as $subscription) {
                        $subscription_id = $subscription->get_id();
                        update_post_meta($subscription_id, '_piraeus_card_id', $card_number);
                        update_post_meta($subscription_id, '_piraeus_source_id', $wc_token->get_id());
                    }
                }

                $order->save();
                WC()->cart->empty_cart();
                $order->payment_complete();

                do_action('primer_woocommerce_piraeus_bank_success', $order->get_id());

                if ($this->has_wc_subscriptions && wcs_is_subscription($order_id)) {
                    wc_add_notice(__('Ο τρόπος πληρωμής ενημερώθηκε.', 'primer'));
                    $redirect_url = $order->get_view_order_url();
                } else {
                    wc_add_notice($message, $message_type);
                    $redirect_url = $this->PrimerPaymentHelpers->get_return_url($order);
                }
                wp_send_json([
                        'type'     => 'redirect',
                        'redirect' => $redirect_url
                ]);
                exit;
            } else {
                $error_message = $response->Header->ResultDescription;
                if ($this->has_wc_subscriptions && !wcs_is_subscription($order_id)) {
                    $order->update_status('failed');
                }
                wc_add_notice(__('Payment error:', 'woothemes') . 'Υπήρξε σφάλμα κατά την πληρωμή. Παρακαλώ ξαναδοκιμάστε με νέα μέθοδο πληρωμής. ' . $error_message, 'error');
                if (wcs_is_subscription($order_id)) {
                    wp_send_json([
                            'type'     => 'redirect',
                            'redirect' => $order->get_view_order_url()
                    ]);
                } else {
                    wp_send_json([
                            'type'     => 'redirect',
                            'redirect' => wc_get_checkout_url()
                    ]);
                }
                exit;
            }
        }
    }

    public function send_transaction_with_token($token, $threeDsecureResponse, $amount) {
        $soapUrl     = "https://paycenter.winbank.gr/services/paymentgateway.asmx";
        $requestType = 'SALE';

        if ($amount == 0) {
            $requestType = 'AUTHORIZE';
        }

        $xml_post_string = '<?xml version="1.0" encoding="utf-8"?>
                <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
                  <soap12:Body>
                    <ProcessTransaction xmlns="http://piraeusbank.gr/paycenter">
                      <TransactionRequest xmlns="http://piraeusbank.gr/paycenter/1.0">
                        <Header>
                          <RequestType>' . $requestType . '</RequestType>
                          <MerchantInfo>
                            <AcquirerID>GR014</AcquirerID>
                            <MerchantID>' . $this->PrimerPaymentGateway['pb_PayMerchantId'] . '</MerchantID>
                            <PosID>' . $this->PrimerPaymentGateway['pb_PosId'] . '</PosID>
                            <ChannelType>3DSecure</ChannelType>
                            <User>' . $this->PrimerPaymentGateway['pb_Username'] . '</User>
                            <Password>' . hash('md5', $this->PrimerPaymentGateway['pb_Password']) . '</Password>
                          </MerchantInfo>
                        </Header>
                        <Body>
                            <TransactionInfo>                   
                            <MerchantReference>' . $threeDsecureResponse['MerchantReference'] . '</MerchantReference>                    
                            <TransactionReferenceID xsi:nil=" true" />                   
                            <EntryType xsi:nil=" true" />                    
                            <CurrencyCode>978</CurrencyCode>                    
                            <Amount>' . $amount . '</Amount>                                       
                            <Installments>0</Installments>   
                            ' . ($amount == 0 ? "<ExpirePreauth>30</ExpirePreauth>" : '<ExpirePreauth xsi:nil="true" />') . '                           
                            <TipAmount xsi:nil=" true" />                    
                            <Bnpl xsi:nil=" true" />                   
                            <SessionKey xsi:nil=" true" />                   
                            <CardInfo>                   
                            <CardType>UNKNOWN</CardType>                    
                            <CardNumber>' . $token . '</CardNumber>                                      
                            <CardHolderName />                   
                            <ExpirationMonth xsi:nil=" true" />                      
                            <ExpirationYear xsi:nil=" true" />                       
                            <Aid xsi:nil=" true" />                    
                            <PinBlock xsi:nil=" true" />                   
                            <Track1 xsi:nil=" true" />                   
                            <Track2 xsi:nil=" true" />                    
                            </CardInfo>                    
                            <AuthInfo>                    
                            <Cavv>' . $threeDsecureResponse['Cavv'] . '</Cavv>                    
                            <Eci>' . $threeDsecureResponse['Eci'] . '</Eci>                   
                            <Xid>' . $threeDsecureResponse['Xid'] . '</Xid>                
                            <Enrolled>Undefined</Enrolled>                    
                            <PAResStatus>Unknown</PAResStatus>                   
                            <SignatureVerification>Undefined</SignatureVerification>                    
                            <Protocol>' . $threeDsecureResponse['Protocol'] . '</Protocol>                    
                            <DsTransID>' . $threeDsecureResponse['DsTransID'] . '</DsTransID>                  
                            <ProtocolFullVersion xsi:nil=" true" />                    
                            </AuthInfo>                   
                            <TaxCardNumber xsi:nil=" true" />                    
                            <WalletData xsi:nil=" true" />   
                            <TraceID xsi:nil=" true" />                  
                            <RecurringInd>C</RecurringInd>                                         
                            <RecurFreq xsi:nil=" true" />                    
                            <RequestBrowserBasedData xsi:nil=" true" />                   
                            <RequestBillingInfo xsi:nil=" true" />                    
                            <RequestShippingInfo xsi:nil=" true" />                   
                            <RequestContactInfo xsi:nil=" true" />                    
                            <DeviceCategory xsi:nil=" true" />                   
                            <AddressMatch xsi:nil=" true" />                   
                            <DeliveryTimeframe xsi:nil=" true" />                    
                            <ReorderItemsInd xsi:nil=" true" />                   
                            <PreOrderPurchaseInd xsi:nil=" true" />                    
                            <AuthMethod xsi:nil=" true" />                   
                            <AccountAgeInd xsi:nil=" true" />                   
                            <AccountChangeInd xsi:nil=" true" />                    
                            <AccountPwdChangeInd xsi:nil=" true" />                   
                            <ShipAddressUsageInd xsi:nil=" true" />                   
                            <SuspiciousAccActivity xsi:nil=" true" />                   
                            </TransactionInfo>
                            </Body>
                      </TransactionRequest>
                    </ProcessTransaction>
                  </soap12:Body>
                </soap12:Envelope>';

        $headers = array(
                "POST /services/TokenService.asmx HTTP/1.1",
                "Host: " . $_SERVER['SERVER_NAME'] . "",
                "Content-Type: application/soap+xml; charset=utf-8",
                "Content-Length: " . strlen($xml_post_string)
        );

        $url = $soapUrl;
        $ch  = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        $response = curl_exec($ch);
        $xml      = simplexml_load_string($response);

        $xml->registerXPathNamespace("soap", "http://www.w3.org/2003/05/soap-envelope");

        return $xml->xpath('//soap:Body')[0]->ProcessTransactionResponse->TransactionResponse;
    }

    public function get_payment_error_message($resultCode) {
        $error_messages = [
            1    => __('An error occurred. Please check your data or else contact epay eCommerce administrator. Try again later when the problem has been rectified. ', 'primer'),
            05   => __('Declined, Transaction declined by the Issuer. ', 'primer'),
            12   => __('Declined. Transaction declined by the Issuer. ', 'primer'),
            51   => __('Declined. Transaction declined by the Issuer. ', 'primer'),
            34   => __('Lost card, Stolen card, Pick-up. Transaction declined by the Issuer. ', 'primer'),
            43   => __('Lost card, Stolen card, Pick-up. Transaction declined by the Issuer. ', 'primer'),
            54   => __('Expired card. The card has expired and has not been renewed. ', 'primer'),
            62   => __('Restricted Card. Transaction declined by the Issuer. ', 'primer'),
            92   => __('Declined. Communication problem with the payment Organisation (Visa, Mastercard etc.), Try again later. ', 'primer'),
            100  => __('Authentication Error. Wrong username or/and password. ', 'primer'),
            130  => __('Fields contains invalid characters. ', 'primer'),
            151  => __('Check fields that contains data. No value is send. ', 'primer'),
            215  => __('AMEX cards require 4 digit CVV2. An American Express card was used and the CVV2 did not consist of 4 digits as it should. Re-send the transaction using the correct (4-digit) CVV2. ', 'primer'),
            216  => __('Wrong CVV2. An invalid value was used in CVV2 parameter. Re-send the transaction using a valid CVV2. ', 'primer'),
            981  => __('Invalid Card number, Exp/Month Exp/Year. No valid values were used in card details (e.g. wrong card number, past expiration date etc) or unsupported card was used. Re-send the transaction using correct card details. ', 'primer'),
            1006 => __('Unknown BIN. The user card is not eligible for Euronet Merchant Services interest-free installments program. Use another card or re-send the transaction without installments. ', 'primer'),
            1007 => __('Merchant does not support given bin. It concerns installment transaction. The card bin (i.e. the first 6 digits) may not be used in installment transaction in this merchant. Use another card or re-send the transaction without installments. ', 'primer'),
            1010 => __('Wrong original transaction. The request is rejected because there is no successful transaction for which the settlement, the preauthorization cancellation, the refund transaction or the follow up is asked. Check the initial transaction and send correct value in TransactionReferenceID parameter. ', 'primer'),
            1012 => __('Original transaction already settled, or being settled. A settlement is requested for a preauthorization which has already been settled or is being settled. Check if the preauthorization is finally settled using epay eCommerce AdminTool. ', 'primer'),
            1014 => __('Refunding amount cannot exceed remaining amount of the original transaction. The refund amount is greater than the initial charge amount. Re-send the transaction using correct amount. ', 'primer'),
            1017 => __('Preorder date has expired. The settlement cannot be carried out because the preauthorization has expired. Submit a new preauthorization transaction. ', 'primer'),
            1019 => __('Too many installments asked. The number of installments requested is higher than the maximum allowed for this merchant. Use a lower number of installments. ', 'primer'),
            1026 => __('Merchant does not support instalments. Installments were used in the transaction but the merchant does not support installments. Contact Euronet Merchant Services in order to activate the use of installments. ', 'primer'),
            1034 => __('Terminal does not support given card type. Transaction with unsupported card type. Check the CardType parameter value and contact Euronet Merchant Services. ', 'primer'),
            1040 => __('Error validating IP address, Contact sysadmin. The IP address validation failed as the request was sent through a server with different IP address than the one that was provided by the technical Manager to Euronet Merchant Services. Check the server’s IP address and if it’s necessary, contact Euronet Merchant Services in order to change the IP address that corresponds to the specific merchant id. ', 'primer'),
            1041 => __('Invalid IP address. The IP address validation failed as the request was sent through a server with different IP address than the one that was provided by the technical Manager to Euronet Merchant Services. Check the server’s IP address and if it’s necessary, contact Euronet Merchant Services in order to change the IP address that corresponds to the specific merchant id. ', 'primer'),
            1042 => __('Refund maximum allowed period exceeded. Attempted refund after the allowed period of 365 days. Contact Euronet Merchant Services. ', 'primer'),
            1045 => __('Duplicate transaction references are not allowed. The request was sent with the same MerchantReference as that of a transaction currently processed by epay eCommerce. Try again later in order for the initial transaction to have been completed. ', 'primer'),
            1048 => __('Transaction already processed and completed. The request sent had a MerchantReference value already used for an approved transaction. Re-send the transaction using a different MerchantReference value. ', 'primer'),
            1072 => __('Pack is still closing. The batch settlement process is in progress (batch closing). Try again later after the batch has been closed. ', 'primer'),
            1802 => __('Wrong amount value. Invalid value used in Amount parameter (e.g. zero amount). Use a valid value in Amount parameter. ', 'primer'),
            7001 => __('Error occurred. Please use different card. ', 'primer'),
            9150 => __('Wallet transaction in request message is not supported. Re-send the transaction using correct values in parameters. ', 'primer'),
            9151 => __('Wrong Funds Transfer Parameters. Re-send the transaction using correct values in parameters. ', 'primer'),
            9152 => __('Funds Transfer in request message is not supported. Refers to merchant that doesn’t support digital wallet top up FUNDSTRANSFER. The request was sent with unsupported transaction type. Contact Euronet Merchant Services. ', 'primer'),
            9156 => __('Transaction Type in request message is not supported. Refers to merchant that only supports digital wallet top up FUNDSTRANSFER. The request was sent with unsupported transaction type. Contact Euronet Merchant Services. ', 'primer'),
            9153 => __('Loyalty is not supported for Funds Transfer. Refers to merchant that only supports digital wallet top up FUNDSTRANSFER. Contact Euronet Merchant Services. ', 'primer'),
            9154 => __('Installments are not supported for Funds Transfer. Refers to merchant that only supports digital wallet top up FUNDSTRANSFER. The request was sent with installments. Contact Euronet Merchant Services. ', 'primer'),
            9155 => __('Recurring Transactions are not supported for Funds Transfer. Refers to merchant that only supports digital wallet top up FUNDSTRANSFER. The request was sent with recurring payments indicator. Contact Euronet Merchant Services. ', 'primer'),
            9158 => __('Account Verification is not supported for Amex cards. The request was sent with unsupported transaction type for given card type. Use another card type. ', 'primer'),
            9159 => __('Installments are not supported for Amex cards. The request was sent with installments but the card type does not support installments. Use another card type or re-send the transaction without installments. ', 'primer'),
        ];
        $resultCode = (int) $resultCode;

        if ($resultCode >= 500 && $resultCode <= 599) {
            return __('Communication Error . Problem with the transaction processing system, try again later when the problem has been rectified . ', 'primer');
        }

        return $error_messages[$resultCode] ?? '';
    }

}

new PrimerPaymentFunctions();
