<?php
/*####################################################################
 # Copyright ©2020 UseePay Ltd. All Rights Reserved.                 #
 # This file may not be redistributed in whole or significant part.  #
 # This file is part of the UseePay package and should not be used   #
 # and distributed for any other purpose that is not approved by     #
 # UseePay Ltd.                                                      #
 # https://www.useepay.com                                           #
 ####################################################################*/

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



/**
 * Class WC_Gateway_UseePay_CreditCard
 */
class WC_Gateway_UseePay_CreditCard extends WC_UseePay_Inner_Payment_Gateway
{
    const ID                                = 'useepay_creditcard';
    
    // Settings keys
    const SETTINGS_KEY_ENABLED              = 'enabled';
    const SETTINGS_KEY_TITLE                = 'title';
    const SETTINGS_KEY_DESCRIPTION          = 'description';
    const SETTINGS_KEY_MERCHANT_NO          = 'merchantNo';
    const SETTINGS_KEY_SECURITY_KEY         = 'useepay_key';
    const SETTINGS_KEY_APP_ID               = 'useepay_app_id';
    const SETTINGS_KEY_SANDBOX_MODE         = 'testMode';
    const SETTINGS_KEY_DEBUG_LOG            = 'debug';
    const SETTINGS_KEY_CARD_LOGOS           = 'card_logos';

    /**
     * Available card brand logos.
     * key => [label, svg filename under assets/images/cards/]
     */
    private static $card_brand_logos = array(
        'visa'       => array( 'label' => 'Visa',             'file' => 'visa.svg' ),
        'mastercard' => array( 'label' => 'Mastercard',       'file' => 'mastercard.svg' ),
        'amex'       => array( 'label' => 'American Express', 'file' => 'amex.svg' ),
        'jcb'        => array( 'label' => 'JCB',              'file' => 'jcb.svg' ),
        'discover'   => array( 'label' => 'Discover',         'file' => 'discover.svg' ),
        'diners'     => array( 'label' => 'Diners Club',      'file' => 'diners.svg' ),
        'unionpay'   => array( 'label' => 'UnionPay',         'file' => 'unionpay.svg' ),
    );
    
    
    

    private $return_url;
    private $payment_async_notify_url;
    private $refund_async_notify_url;
    private $query_order_status_url;

    public function __construct()
    {

        $this->id                 = self::ID;
        $this->method_title       = 'UseePay';
        $this->method_description = 'UseePay standard payment redirects customers to UseePay to enter payment information.';
        $this->has_fields         = true;
        $this->icon               = apply_filters('woocommerce_useepay_icon', plugins_url('../assets/images/cards.svg', __FILE__));
        $this->title                = $this->get_validated_option( 'title' );
        $this->supports           = array(
            'products',
            'refunds',
        );

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

        $this->return_url = WC()->api_request_url('WC_useepay_inner_return');

        // async notify
        $this->payment_async_notify_url = WC()->api_request_url('WC_useepay_inner_notify');
        $this->refund_async_notify_url  = WC()->api_request_url('WC_useepay_inner_refund_notify');
        $this->query_order_status_url = WC()->api_request_url("WC_useepay_inner_query_order_status");
        // Actions
        add_filter('http_request_version', array($this, 'use_http_1_1'));
        add_action( 'wp_enqueue_scripts', [ $this, 'payment_scripts' ] );
        add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options')); // WC >= 2.0

        add_action('woocommerce_api_wc_useepay_inner_return', array($this, 'return_handle'));

        add_filter( 'woocommerce_payment_successful_result', [ $this, 'modify_successful_payment_result' ], 99999, 2 );

        add_action('woocommerce_api_wc_useepay_inner_notify', array($this, 'payment_async_notify_handle'));
        add_action('woocommerce_api_wc_useepay_inner_refund_notify', array($this, 'refund_async_notify_handle'));

        add_action('woocommerce_api_wc_useepay_inner_query_order_status', array($this, 'query_order_status'));

        add_action('woocommerce_admin_order_data_after_billing_address', array($this, 'wc_useepay_display_order_meta_for_admin'));
    }

    /**
     * Render the gateway icon on the checkout page.
     *
     * Generates an <img> per card brand the merchant has selected in
     * "Accepted Card Logos". Falls back to the legacy combined cards.svg
     * if the selection is empty/invalid (e.g. fresh install with no settings).
     *
     * @return string
     */
    public function get_icon() {
        $selected = $this->get_option( self::SETTINGS_KEY_CARD_LOGOS );

        if ( ! is_array( $selected ) || empty( $selected ) ) {
            // Fallback to legacy combined logo so we never end up with a blank icon.
            $legacy_url = plugins_url( '../assets/images/cards.svg', __FILE__ );
            $icon_html  = '<img src="' . esc_url( WC_HTTPS::force_https_url( $legacy_url ) ) . '" alt="' . esc_attr( $this->get_title() ) . '" />';
            return apply_filters( 'woocommerce_gateway_icon', $icon_html, $this->id );
        }

        $icon_html = '';
        foreach ( $selected as $brand ) {
            if ( ! isset( self::$card_brand_logos[ $brand ] ) ) {
                continue;
            }
            $url = plugins_url( '../assets/images/cards/' . self::$card_brand_logos[ $brand ]['file'], __FILE__ );
            $icon_html .= '<img src="' . esc_url( WC_HTTPS::force_https_url( $url ) ) . '"'
                . ' alt="' . esc_attr( self::$card_brand_logos[ $brand ]['label'] ) . '"'
                . ' style="margin-left:4px;max-height:24px;vertical-align:middle;display:inline-block;" />';
        }

        return apply_filters( 'woocommerce_gateway_icon', $icon_html, $this->id );
    }

    /**
     * Admin Panel Option
     * - Options for bits like 'title' and account etc.
     *
     * @access public
     * @return void
     */
    public function admin_options()
    {
        // 添加自定义CSS样式
        echo '<style>
        .useepay-admin-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
        }
        .useepay-admin-header h1 {
            margin: 0 0 10px 0;
            font-size: 24px;
            font-weight: 600;
        }
        .useepay-admin-header p {
            margin: 0 0 10px 0;
            opacity: 0.9;
        }
        .useepay-status-badge {
            display: inline-block;
            background: rgba(255,255,255,0.2);
            padding: 4px 12px;
            border-radius: 20px;
            font-size: 12px;
            font-weight: 500;
            margin-right: 8px;
        }
        .useepay-help-section {
            background: #f8f9fa;
            border-left: 4px solid #667eea;
            padding: 15px;
            margin: 20px 0;
            border-radius: 4px;
        }
        .useepay-help-section h3 {
            margin: 0 0 10px 0;
            color: #333;
            font-size: 16px;
        }
        .useepay-help-section ul {
            margin: 0;
            padding-left: 20px;
        }
        .useepay-help-section li {
            margin-bottom: 5px;
            line-height: 1.5;
        }
        .useepay-help-section a {
            color: #667eea;
            text-decoration: none;
        }
        .useepay-help-section a:hover {
            text-decoration: underline;
        }
        .form-table {
            background: white;
            border: 1px solid #e1e1e1;
            border-radius: 8px;
            overflow: hidden;
        }
        .form-table th {
            font-weight: 600;
            background: #f8f9fa;
            border-bottom: 1px solid #e1e1e1;
        }
        </style>';

        // 获取沙盒模式设置
        $is_sandbox  = 'yes' === $this->get_option(self::SETTINGS_KEY_SANDBOX_MODE);
        $is_enabled = $this->get_option(self::SETTINGS_KEY_ENABLED) === 'yes';
        
        // UseePay 设置页面包装器
        echo '<div class="useepay-settings-wrapper woocommerce-useepay-settings">';
        
        // 设置页面头部
        echo '<div class="useepay-settings-header">';
        echo '<h1>UseePay Payment Gateway</h1>';
        echo '<p>UseePay is a simple, secure, and fast online payment gateway that allows customers to pay via credit or debit cards.</p>';
        echo '</div>';

        // 帮助信息区域
        echo '<div class="useepay-info-box">';
        echo '<h3>Quick Setup Guide</h3>';
        echo '<ul>';
        echo '<li>1. Ensure you have a UseePay merchant account, <a href="https://useepay.com/global-payment-acquiring-apply" target="_blank">apply here</a> if you don\'t have one</li>';
        echo '<li>2. Enable the payment gateway in General Settings and set the display name</li>';
        echo '<li>3. Enter your merchant number, security key, and app ID in API Credentials</li>';
        echo '<li>4. Test in sandbox mode first, then switch to production environment when ready</li>';
        echo '<li>5. Enable debug log if you encounter any issues for troubleshooting</li>';
        echo '</ul>';
        echo '</div>';

        // 配置表单
        echo $this->generate_settings_html();

        // 配置状态检查
        echo '<div class="useepay-info-box">';
        echo '<h3>Configuration Status</h3>';
        
        $is_enabled = $this->get_option(self::SETTINGS_KEY_ENABLED) === 'yes';
        $has_merchant_no = !empty($this->get_merchant_no());
        $has_security_key = !empty($this->get_security_key());
        $has_app_id = !empty($this->get_app_id());
        
        echo '<ul>';
        echo '<li style="color: ' . ($is_enabled ? 'var(--useepay-success)' : 'var(--useepay-error)') . ';">' . 
             ($is_enabled ? '✓' : '✗') . ' Payment Gateway: ' . 
             ($is_enabled ? 'Enabled' : 'Disabled') . '</li>';
        echo '<li style="color: ' . ($has_merchant_no ? 'var(--useepay-success)' : 'var(--useepay-error)') . ';">' . 
             ($has_merchant_no ? '✓' : '✗') . ' Merchant No: ' . 
             ($has_merchant_no ? 'Configured' : 'Not Configured') . '</li>';
        echo '<li style="color: ' . ($has_security_key ? 'var(--useepay-success)' : 'var(--useepay-error)') . ';">' . 
             ($has_security_key ? '✓' : '✗') . ' Security Key: ' . 
             ($has_security_key ? 'Configured' : 'Not Configured') . '</li>';
        echo '<li style="color: ' . ($has_app_id ? 'var(--useepay-success)' : 'var(--useepay-error)') . ';">' . 
             ($has_app_id ? '✓' : '✗') . ' App ID: ' . 
             ($has_app_id ? 'Configured' : 'Not Configured') . '</li>';
        echo '</ul>';
        echo '</div>';

        // 技术支持信息
        echo '<div class="useepay-info-box">';
        echo '<h3>Technical Support</h3>';
        echo '<p>If you encounter any issues during configuration, you can get help through:</p>';
        echo '<ul>';
        echo '<li>Official Documentation: <a href="https://useepay.com" target="_blank">https://useepay.com</a></li>';
        echo '<li>Merchant Support Email: support@useepay.com</li>';
        echo '<li>Plugin version: v1.0.4</li>';
        echo '</ul>';
        echo '</div>';
        
        // 闭合设置页面包装器
        echo '</div>';
    }

    /**
     * Retrieves validated field value.
     *
     * @param string $field_key the form field key.
     * @param mixed $empty_value fallback value.
     *
     * @return string validated field value.
     */
    public function get_validated_option( $field_key, $empty_value = null ) {
        $value = parent::get_option( $field_key, $empty_value );
        return $this->validate_field( $field_key, $value );
    }

    /**
     * Ensures validated field values.
     *
     * @param string $field_key the form field key.
     * @param string $field_value the form field value.
     *
     * @return string validated field value.
     */
    private function validate_field( $field_key, $field_value ) {
        if ( is_callable( [ $this, 'validate_' . $field_key . '_field' ] ) ) {
            return $this->{'validate_' . $field_key . '_field'}( $field_key, $field_value );
        }

        if ( empty( $this->form_fields ) ) {
            $this->init_form_fields();
        }
        if ( key_exists( $field_key, $this->form_fields ) ) {
            $field_type = $this->form_fields[ $field_key ]['type'];

            if ( is_callable( [ $this, 'validate_' . $field_type . '_field' ] ) ) {
                return $this->{'validate_' . $field_type . '_field'}( $field_key, $field_value );
            }
        }

        return $this->validate_text_field( $field_key, $field_value );
    }


    /**
     * Set the HTTP version for the remote posts
     * https://developer.wordpress.org/reference/hooks/http_request_version/
     */
    public function use_http_1_1($httpversion)
    {
        return '1.1';
    }

    /**
     * Check if the gateway is available for use
     */
    public function is_available() {
        if ('yes' !== $this->get_option(self::SETTINGS_KEY_ENABLED)) {
            return false;
        }
        
        $merchant_no = $this->get_option(self::SETTINGS_KEY_MERCHANT_NO);
        $security_key = $this->get_option(self::SETTINGS_KEY_SECURITY_KEY);
        $app_id = $this->get_option(self::SETTINGS_KEY_APP_ID);
        
        if (empty($merchant_no) || empty($security_key) || empty($app_id)) {
            return false;
        }
        
        return true;
    }

    /**
     * Validate form fields which rendered in payment_fields()
     */
    public function validate_fields()
    {
        $ok = true;
        if (empty($_POST['session'])) {
            wc_add_notice('Server is busy, please try again', 'error');
            $ok = false;
        }
        return $ok;
    }

    /**
     * Render Credit/Debit Card form
     */
    public function payment_fields() {
        // 检查是否启用沙盒模式
        if ('yes' === $this->get_option(self::SETTINGS_KEY_SANDBOX_MODE)) {
            // 显示测试模式警告
            echo '<p style="background:#fff3cd; border:1px solid #f0c36d; 
                            border-radius:4px; padding:8px 12px; margin-bottom:8px; 
                            font-size:13px;">
                    <strong>⚠ Test Mode:</strong> No real payment will be processed.
                  </p>';
        }
        
        // 显示支付方式描述
        if ($this->description) {
            echo '<p>' . wp_kses_post($this->description) . '</p>';
        }
        
        echo '<div id="useepay-container"></div>';
    }


    /**
     * Initialise Gateway Settings Form Fields
     */
    public function init_form_fields() {
        $is_gte_wc6_6 = defined( WC_VERSION ) && version_compare( WC_VERSION, '6.6', '>=' );
        
        $this->form_fields = array(

            // ── General Settings ────────────────────────────────────────
            'section_general'               => array(
                'title' => 'General Settings',
                'type'  => 'title',
                'description' => 'Configure basic UseePay payment gateway settings',
            ),
            self::SETTINGS_KEY_ENABLED      => array(
                'title'   => 'Enable/Disable',
                'type'    => 'checkbox',
                'label'   => 'Enable UseePay Payment',
                'default' => 'no',
                'description' => 'Enable UseePay payment method on checkout page',
                'desc_tip' => true,
            ),
            self::SETTINGS_KEY_TITLE        => array(
                'title'       => 'Title',
                'type'        => $is_gte_wc6_6 ? 'safe_text' : 'text',
                'description' => 'Payment method name shown to customers on the checkout page',
                'default'     => 'Credit Card',
                'desc_tip'    => true,
                'css'         => 'width:360px',
            ),
            self::SETTINGS_KEY_DESCRIPTION  => array(
                'title'       => 'Description',
                'type'        => 'textarea',
                'description' => 'Payment method description shown to customers on the checkout page',
                'default'     => 'Secure credit and debit card payments',
                'desc_tip'    => true,
                'css'         => 'width:400px; height:80px;',
            ),
            self::SETTINGS_KEY_CARD_LOGOS   => array(
                'title'       => 'Accepted Card Logos',
                'type'        => 'multiselect',
                'class'       => 'wc-enhanced-select',
                'description' => 'Select which card organization logos to display next to the payment method on the checkout page',
                'default'     => array( 'visa', 'mastercard', 'amex', 'jcb', 'discover', 'diners' ),
                'options'     => array_combine(
                    array_keys( self::$card_brand_logos ),
                    array_map( function ( $b ) { return $b['label']; }, self::$card_brand_logos )
                ),
                'desc_tip'    => true,
                'css'         => 'width:360px',
            ),

            // ── API Credentials ───────────────────────────────────────────
            'section_credentials'           => array(
                'title'       => 'API Credentials',
                'type'        => 'title',
                'description' => 'Enter your UseePay merchant credentials. <a href="https://useepay.com/global-payment-acquiring-apply" target="_blank">Apply for an account</a> if you don\'t have one.',
            ),
            self::SETTINGS_KEY_MERCHANT_NO  => array(
                'title'       => 'Merchant No',
                'type'        => $is_gte_wc6_6 ? 'safe_text' : 'text',
                'description' => 'Your UseePay merchant number',
                'placeholder' => 'e.g. USEEPAY123456',
                'desc_tip'    => true,
                'css'         => 'width:360px',
            ),
            self::SETTINGS_KEY_SECURITY_KEY => array(
                'title'       => 'Security Key',
                'type'        => 'password',
                'description' => 'Your UseePay security / secret key',
                'placeholder' => 'Enter 32-character security key',
                'desc_tip'    => true,
                'css'         => 'width:360px',
            ),
            self::SETTINGS_KEY_APP_ID       => array(
                'title'       => 'UseePay App ID',
                'type'        => $is_gte_wc6_6 ? 'safe_text' : 'text',
                'description' => 'Your UseePay application ID issued for API authentication',
                'placeholder' => 'e.g. app_1234567890',
                'desc_tip'    => true,
                'css'         => 'width:360px',
            ),

            // ── Environment Settings ──────────────────────────────────────
            'section_environment'           => array(
                'title' => 'Environment Settings',
                'type'  => 'title',
                'description' => 'Configure runtime environment and debugging options',
            ),
            self::SETTINGS_KEY_SANDBOX_MODE => array(
                'title'       => 'Sandbox Mode',
                'type'        => 'checkbox',
                'label'       => 'Enable Sandbox Mode',
                'default'     => 'no',
                'description' => 'Use the UseePay UAT environment for testing. Disable this in production',
                'desc_tip'    => true,
            ),
            self::SETTINGS_KEY_DEBUG_LOG    => array(
                'title'       => 'Debug Log',
                'type'        => 'checkbox',
                'label'       => 'Enable logging',
                'default'     => 'no',
                'description' => 'Log UseePay events for debugging. View logs in <a href="' . esc_url(admin_url('admin.php?page=wc-status&tab=logs')) . '">WooCommerce › Status › Logs</a>',
                'desc_tip'    => true,
            ),

            
            
        );
    }

    /**
     * Validate settings fields
     */
    public function validate_settings_fields($form_fields = []) {
        $errors = [];

        // 从POST数据获取值
        $merchant_no = isset($_POST[self::SETTINGS_KEY_MERCHANT_NO]) ? sanitize_text_field($_POST[self::SETTINGS_KEY_MERCHANT_NO]) : '';
        $security_key = isset($_POST[self::SETTINGS_KEY_SECURITY_KEY]) ? sanitize_text_field($_POST[self::SETTINGS_KEY_SECURITY_KEY]) : '';
        $app_id = isset($_POST[self::SETTINGS_KEY_APP_ID]) ? sanitize_text_field($_POST[self::SETTINGS_KEY_APP_ID]) : '';

        // 验证商户号
        if (!empty($merchant_no)) {
            if (strlen($merchant_no) < 6) {
                $errors[self::SETTINGS_KEY_MERCHANT_NO] = 'Merchant number must be at least 6 characters';
            }
            if (!preg_match('/^[A-Za-z0-9]+$/', $merchant_no)) {
                $errors[self::SETTINGS_KEY_MERCHANT_NO] = 'Merchant number can only contain letters and numbers';
            }
        }

        // 验证安全密钥
        if (!empty($security_key)) {
            if (strlen($security_key) < 16) {
                $errors[self::SETTINGS_KEY_SECURITY_KEY] = 'Security key must be at least 16 characters';
            }
        }

        // 验证应用ID
        if (!empty($app_id)) {
            if (!preg_match('/^app_[A-Za-z0-9]+$/', $app_id)) {
                $errors[self::SETTINGS_KEY_APP_ID] = 'App ID format is incorrect, should start with app_';
            }
        }

        

        // 如果有错误，显示给用户
        if (!empty($errors)) {
            foreach ($errors as $field => $message) {
                WC_Admin_Settings::add_error($message);
            }
            return false;
        }

        return true;
    }

    /**
     * Override process_admin_options to add validation
     */
    public function process_admin_options() {
        // 验证字段
        if (!$this->validate_settings_fields($this->form_fields)) {
            return false;
        }
        
        parent::process_admin_options();
        
        // 显示成功消息
        WC_Admin_Settings::add_message('UseePay settings saved successfully');
    }

    /**
     * Get merchant number from settings
     */
    protected function get_merchant_no() {
        return $this->get_option(self::SETTINGS_KEY_MERCHANT_NO);
    }

    /**
     * Get security key from settings
     */
    protected function get_security_key() {
        return $this->get_option(self::SETTINGS_KEY_SECURITY_KEY);
    }

    /**
     * Get app ID from settings
     */
    protected function get_app_id() {
        return $this->get_option(self::SETTINGS_KEY_APP_ID);
    }

    /**
     * Check if sandbox mode is enabled
     */
    protected function is_sandbox_mode() {
        return 'yes' === $this->get_option(self::SETTINGS_KEY_SANDBOX_MODE);
    }

    /**
     * Check if debug logging is enabled
     */
    protected function is_debug_enabled() {
        return 'yes' === $this->get_option(self::SETTINGS_KEY_DEBUG_LOG);
    }

    


    /**
     * Process Payment.
     *
     * Process the payment. Override this in your gateway. When implemented, this should.
     * return the success and redirect in an array. e.g:
     *
     *        return array(
     *            'result'   => 'success',
     *            'redirect' => $this->get_return_url( $order )
     *        );
     *
     * @param int $order_id Order ID.
     * @return array
     */
    public function process_payment($order_id)
    {
        WC_UseePay_Inner_Logger::log('Process payment with order_id: ' . $order_id);
        $order = wc_get_order($order_id);
        WC_UseePay_Inner_Logger::log('Process payment with order_key: ' . $order->get_order_key());
        if (empty($order)) {
            wc_add_notice('Order not exist!', 'error');
            return array(
                'result'   => 'fail',
                'redirect' => '',
            );
        }
        $parameters = $this->build_payment_request_parameters($order);
        WC_UseePay_Inner_Logger::log('Process payment with request parameters: ' . var_export($parameters, true));

        try {
            $response       = WC_UseePay_Inner_API::request($parameters);
            $result_code    = isset($response['resultCode']) ? $response['resultCode'] : null;
            $error_code     = isset($response['errorCode']) ? $response['errorCode'] : null;
            $error_msg      = isset($response['errorMsg']) ? $response['errorMsg'] : null;
            $transaction_id = isset($response['reference']) ? $response['reference'] : null;
            if ($result_code == 'succeed') {
                $this->do_order_complete_tasks($order, $transaction_id);
                return array(
                    'result'   => 'success',
                    'redirect' => $this->get_return_url($order)
                );
            } else if ($result_code == 'pending_review') {

               $this->do_order_on_hold_tasks($order, $transaction_id);

               return array(
                    'result'   => 'success',
                    'redirect' => empty($response['redirectUrl']) ? $this->get_return_url($order) : $response['redirectUrl']
                );
            } else if (($result_code == 'pending' || $result_code == 'challenge' || $result_code == 'gather') && $error_code == '3200') {
                // 3DS transaction processing
                WC_UseePay_Inner_Logger::log('3DS Transaction detected - Result Code: ' . $result_code . ', Error Code: ' . $error_code);
                
                if ($result_code == "gather") {
                    // 3DS Method gathering - collect device information
                    WC_UseePay_Inner_Logger::log('3DS: Gathering device information');
                    return [
                        'result'   => 'success',
                        'redirect' => empty($response['redirectUrl']) ? $this->get_return_url($order) : $response['redirectUrl'],
                        'token' => $response['redirectUrl'],
                    ];
                } else if ($result_code == "challenge") {
                    // 3DS Challenge required - user authentication needed
                    WC_UseePay_Inner_Logger::log('3DS: Challenge required - user authentication needed');
                    return [
                        'result'   => 'success',
                        'redirect' => empty($response['redirectUrl']) ? $this->get_return_url($order) : $response['redirectUrl'],
                        'token' => $response['redirectUrl'],
                    ];
                } else if ($result_code == "pending") {
                    // 3DS processing in progress
                    WC_UseePay_Inner_Logger::log('3DS: Processing in progress');
                    return [
                        'result'   => 'success',
                        'redirect' => empty($response['redirectUrl']) ? $this->get_return_url($order) : $response['redirectUrl'],
                    ];
                }
            } else if ($result_code == 'succeed' && isset($response['threeDSInfo'])) {
                // 3DS Exemption successful - no challenge required
                WC_UseePay_Inner_Logger::log('3DS: Exemption successful - payment approved without challenge');
                $exemption_type = isset($response['threeDSInfo']['exemption']) ? $response['threeDSInfo']['exemption'] : 'unknown';
                WC_UseePay_Inner_Logger::log('3DS Exemption Type: ' . $exemption_type);
                
                $this->do_order_complete_tasks($order, $transaction_id);
                return array(
                    'result'   => 'success',
                    'redirect' => $this->get_return_url($order)
                );
            } else {
                $transaction_error_message = $error_code . "," . $error_msg;
                $this->mark_as_failed_payment($order, $transaction_error_message);
                wc_add_notice('(Transaction Error) An issue occurred. ' . ' ' . $transaction_error_message, 'error');
                return array(
                    'result'   => 'fail',
                    'redirect' => '',
                );
            }
        } catch (WC_UseePay_Inner_Exception $e) {
            wc_add_notice($e->get_error_message(), 'error');
            return array(
                'result'   => 'fail',
                'redirect' => '',
            );
        }
    }

    public function modify_successful_payment_result( $result, $order_id ) {
        if ( ! isset( $result['token'] )) {
            // Only redirects with intents need to be modified.
            return $result;
        }

        $verification_url = $this->return_url;

        if ( isset( $result['token'] ) ) {
            $redirect_signature = sprintf(
                '#confirm-token-%s~%s',
                $result['token'],
                rawurlencode( wp_sanitize_redirect( esc_url_raw( $verification_url ) ) )
            );
        }

        WC_UseePay_Inner_Logger::log('Process payment with 3DS: ' .  $redirect_signature);
        return [
            'result'   => 'success',
            'redirect' => $redirect_signature, // This signature will be used by JS to redirect to the proper URL.
        ];
    }

    /**
     * Process refund.
     *
     * If the gateway declares 'refunds' support, this will allow it to refund.
     * a passed in amount.
     *
     * @param int $order_id Order ID.
     * @param float $amount Refund amount.
     * @param string $reason Refund reason.
     * @return boolean True or false based on success, or a WP_Error object.
     */
    public function process_refund($order_id, $amount = null, $reason = '')
    {
        $order = wc_get_order($order_id);

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

        $parameters = $this->build_refund_request_parameters($order, $amount, $reason);

        try {
            $response       = WC_UseePay_Inner_API::request($parameters);
            $result_code    = isset($response['resultCode']) ? $response['resultCode'] : '';
            $error_code     = isset($response['errorCode']) ? $response['errorCode'] : '';
            $error_msg      = isset($response['errorMsg']) ? $response['errorMsg'] : '';
            $transaction_id = isset($response['reference']) ? $response['reference'] : '';

            if ($result_code == "pending" && $error_code == "0000") {
                $order->add_order_note(sprintf('Credit card refund approved; Refund ID: %s', $transaction_id));
                WC_UseePay_Inner_Logger::log('[Refund] Submitted. Order #' . $order_id . ', reference=' . $transaction_id . ', amount=' . $amount);
                return true;
            } else {
                WC_UseePay_Inner_Logger::log('[Refund] Rejected. Order #' . $order_id . ', error=' . $error_code . ',' . $error_msg);
                return new WP_Error('useepay_refund_error', $result_code . "," . $error_msg);
            }
        } catch (WC_UseePay_Inner_Exception $e) {
            WC_UseePay_Inner_Logger::log('[Refund] Exception. Order #' . $order_id . ': ' . $e->get_localization_message());
            return new WP_Error('useepay_refund_error', $e->get_localization_message());
        }
    }

    /**
     * Can the order be refunded via Useepay?
     *
     * @param WC_Order $order Order object.
     * @return bool
     */
    function can_refund_order($order)
    {
        $settings                              = get_option( 'woocommerce_'.self::ID.'_settings', [] );
        $has_api_creds = ! empty($settings['merchantNo'])
            && ! empty($settings['useepay_app_id'])
            && ! empty($settings['useepay_key']);

        return $order && $order->get_id() && $has_api_creds;
    }

    /**
     * Build parameters for payment
     *
     * @param $order
     * @return array
     */
    function build_payment_request_parameters($order)
    {
        $settings                              = get_option( 'woocommerce_'.self::ID.'_settings', [] );
        $sandbox_mode       = isset($settings["testMode"]) && 'yes' === $settings["testMode"];
        $currency    = $order->get_currency();    //	交易币种
        $amount      = Wc_UseePay_Inner_Util::convert_woo_price_to_useepay_price($currency, $order->get_total(), 2);
        $notifyUrl   = $this->payment_async_notify_url; //	商户通知地址
        $redirectUrl = $sandbox_mode?'https://checkout1.uat.useepay.com/v3/payResult' : 'https://checkout.useepay.com/v3/payResult'; //	商户通知地址

        $goods_name_desc = $this->get_goods_name_desc($order);
        $goodsInfo       = [];
        foreach ($order->get_items() as $lineitem) {
            $_product         = $lineitem->get_product();
            if (!$_product) {
                continue;
            }
            $temp             = [];
            $temp['name']     = strval($lineitem->get_name());
            $temp['sku']      = strval($_product->get_data()['sku']);
            $temp['price']    = strval(Wc_UseePay_Inner_Util::convert_woo_price_to_useepay_price($currency, $_product->get_data()['sale_price']));
            $temp['quantity'] = strval($lineitem->get_data()['quantity']);
            $goodsInfo[]      = $temp;
        }
        $billingStreet  = $this->clean($order->get_billing_address_1());
        $billingHouseNo = $this->clean($order->get_billing_address_2());
        $billingCity    = $order->get_billing_city(); //	账单城市
        $billingState   = $order->get_billing_state(); //	账单州省
        if ($billingState == null || strlen(trim($billingState)) <= 0) {
            $billingState = $billingCity;
        }

        $shippingStreet  = $this->clean($order->get_shipping_address_1());
        $shippingHouseNo = $this->clean($order->get_shipping_address_2());
        $shippingCity    = $order->get_shipping_city(); //	收货人城市
        $shippingState   = $order->get_shipping_state(); //	收货人州省
        if ($shippingState == null || strlen(trim($shippingState)) <= 0) {
            $shippingState = $billingState;
        }

        $shippingStreet = empty($shippingStreet) ? $billingStreet : $shippingStreet;
        $shippingCity   = empty($shippingCity) ? $billingCity : $shippingCity;
        $shippingState  = empty($shippingState) ? $billingState : $shippingState;
        $orderInfo      = [
            "subject"         => trim($goods_name_desc["product_names"]),
            "goodsInfo"       => $goodsInfo,
            "shippingAddress" => [
                "email"      => trim($order->get_billing_email()),
                "phoneNo"    => trim($order->get_billing_phone()),
                "firstName"  => empty(trim($order->get_shipping_first_name())) ? trim($order->get_billing_first_name()) : trim($order->get_shipping_first_name()),
                "lastName"   => empty(trim($order->get_shipping_last_name())) ? trim($order->get_billing_last_name()) : trim($order->get_shipping_last_name()),
                "street"     => trim($shippingStreet),
                "postalCode" => empty(trim($order->get_shipping_postcode())) ? trim($order->get_billing_postcode()) : trim($order->get_shipping_postcode()),
                "city"       => trim($shippingCity),
                "state"      => trim($shippingState),
                "country"    => empty(trim($order->get_shipping_country())) ? trim($order->get_billing_country()) : trim($order->get_shipping_country()),
                "houseNo"    => $shippingHouseNo,
            ]
        ];

        $userInfo = [
            'userId'     => trim($order->get_user_id()), // 用户在商户系统的id
            'ip'         => trim($order->get_customer_ip_address()),  // 用户下单IP
            'email'      => trim($order->get_billing_email()),     // 用户email
            'phoneNo'    => trim($order->get_billing_phone()), // 用户phone
            'createTime' => '', // 用户的注册时间
        ];

        $cardHolderFirstName = trim($order->get_billing_first_name());    //	持卡人名
        $cardHolderLastName  = trim($order->get_billing_last_name());    //	持卡人姓

        // 组装 threeDS2RequestData，失败时不传（不影响交易）
        $threeDS2RequestData = null;
        try {
            $browserInfo = isset($_POST["browserInfo"]) ? $_POST["browserInfo"] : null;
            if ($browserInfo) {
                $browserInfo = json_decode("\"" . $browserInfo . "\"", true);
                $browserInfo = json_decode($browserInfo, true);
            }

            $acceptHeader = ($browserInfo && !empty($browserInfo["acceptHeader"]))
                ? substr($browserInfo["acceptHeader"], 0, 512)
                : "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";

            $threeDS2RequestData = [
                "deviceChannel"  => "browser",
                "acceptHeader"   => $acceptHeader,
                "javaEnabled"    => isset($browserInfo["javaEnabled"]) ? (bool) $browserInfo["javaEnabled"] : false,
                "screenHeight"   => isset($browserInfo["screenHeight"]) ? (string) $browserInfo["screenHeight"] : "",
                "screenWidth"    => isset($browserInfo["screenWidth"]) ? (string) $browserInfo["screenWidth"] : "",
                "timeZoneOffset" => isset($browserInfo["timeZoneOffset"]) ? (string) $browserInfo["timeZoneOffset"] : "",
                "language"       => isset($browserInfo["language"]) ? substr((string) $browserInfo["language"], 0, 32) : "",
                "userAgent"      => isset($browserInfo["userAgent"]) ? substr((string) $browserInfo["userAgent"], 0, 512) : "",
                "colorDepth"     => isset($browserInfo["colorDepth"]) ? (string) $browserInfo["colorDepth"] : "",
            ];
        } catch (\Throwable $e) {
            WC_UseePay_Inner_Logger::log('[3DS] Failed to build threeDS2RequestData: ' . $e->getMessage());
            $threeDS2RequestData = null;
        }

        $payerInfo   = [
            'paymentMethod'       => 'credit_card',
            'authorizationMethod' => 'cvv',
            'session'             => $_POST['session'],
            'firstName'           => trim($cardHolderFirstName),
            'lastName'            => trim($cardHolderLastName),
            'billingDescriptor'   => '',
            'billingAddress'      => [
                'houseNo'    => $billingHouseNo,
                'email'      => trim($order->get_billing_email()),
                'phoneNo'    => trim($order->get_billing_phone()),
                'firstName'  => trim($order->get_billing_first_name()),
                'lastName'   => trim($order->get_billing_last_name()),
                'street'     => trim($billingStreet), // 账单街道
                'postalCode' => trim($order->get_billing_postcode()), // 账单邮政编码
                'city'       => trim($billingCity),   // 账单城市
                'state'      => trim($billingState),  // 账单省份
                'country'    => trim($order->get_billing_country()) // 账单国家英文二字码
            ],
        ];

        if ($threeDS2RequestData) {
            $payerInfo['threeDS2RequestData'] = $threeDS2RequestData;
        }

        $wrapThreeDsParams         = [
                'useWrapThreeDs'         =>  "true",
                'threeDsCallbackUrl'     =>  $sandbox_mode?"https://pay-gateway1.uat.useepay.com/InternalAPI.do/api/session/01/resolve" :"https://open-pay-gateway.useepay.com/InternalAPI.do/api/session/01/resolve",
            ];

        $deviceInfo = null;
        if (isset($_COOKIE['CO_XD_FP_ID'])) {
            $fingerPrintId = $_COOKIE["CO_XD_FP_ID"];
            $deviceInfo    = [
                'fingerPrintId' => trim($fingerPrintId), // 设备指纹
            ];
        }
       
        
        $transaction_id = $order->get_transaction_id();
        if (!$transaction_id) {
            $transaction_id = $this->get_useepay_order_transaction_id($order);
            $this->update_transaction_id($transaction_id, $order);
        }

        //组装参数
        return array(
            'transactionType'           => 'pay',
            'version'                   => '1.0',
            'signType'                  => 'MD5',
            'merchantNo'                => $settings['merchantNo'],
            'transactionId'             => $transaction_id,
            'transactionExpirationTime' => '2880',
            'appId'                     => $settings['useepay_app_id'],
            'amount'                    => $amount,
            'currency'                  => $currency,
            'notifyUrl'                 => $notifyUrl,
            'redirectUrl'               => $redirectUrl,
            'echoParam'                 => $order->get_id(),
            'wrapThreeDsParams'         => json_encode($wrapThreeDsParams),
            'testMode'                  => 'false',
            'reserved'                  => '{"pluginName":"woocommerce-gateway-useepay","pluginVersion":"1.0.4"}',

            'orderInfo'  => json_encode($orderInfo),
            'userInfo'   => json_encode($userInfo),
            'payerInfo'  => json_encode($payerInfo),
            'deviceInfo' => empty($deviceInfo) ? null : json_encode($deviceInfo),
        );
    }

    /**
	 * Sets transaction ID to the WC order.
	 *
	 * @param string               $transaction_id The transaction ID to set.
	 * @param WC_Order             $wc_order The order to set transaction ID to.
	 *
	 * @return bool
	 */
	protected function update_transaction_id(string $transaction_id,WC_Order $wc_order): bool {
		try {
			$wc_order->set_transaction_id( $transaction_id );
			$wc_order->save();

			$wc_order->add_order_note(
				sprintf(
					/* translators: %s is the Useepay transaction ID */
					'UseePay Transaction ID: %s',
					$transaction_id
				)
			);

			return true;
		} catch ( Exception $exception ) {
			WC_UseePay_Inner_Logger::log('Failed to set transaction ID '.$transaction_id . $exception->getMessage());
			return false;
		}
	}

    /**
     * Build parameters for refund
     *
     * @param $order
     * @param null $amount
     * @param string $reason
     * @return array
     */
    function build_refund_request_parameters($order, $amount = null, $reason = '')
    {
        $settings                              = get_option( 'woocommerce_'.self::ID.'_settings', [] );
        $uniqId        = md5(uniqid(microtime(true), true));
        $transactionId = time() . substr($uniqId, 0, 6);

        $currency = $order->get_currency();    //	交易币种
        $amount   = Wc_UseePay_Inner_Util::convert_woo_price_to_useepay_price($currency, $amount, 2);
        //组装参数
        $parameters = array(
            'transactionType'       => 'refund',
            'version'               => '1.0',
            'signType'              => 'MD5',
            'merchantNo'            => $settings["merchantNo"],
            'transactionId'         => $transactionId,
            'originalTransactionId' => $order->get_transaction_id(),
            'amount'                => $amount,
            'notifyUrl'             => $this->refund_async_notify_url,
            'echoParam'             => $order->get_id(),
            'reserved'              => '{"pluginName":"woocommerce-gateway-useepay","pluginVersion":"1.0.4"}',
        );

        WC_UseePay_Inner_Logger::log("useepay request:" . var_export($parameters, true));
        return $parameters;
    }

    protected function mark_as_failed_payment($order, $message)
    {
        $order->add_order_note(sprintf("Credit card payment failed with message: '%s'", $message));
    }

    protected function do_order_complete_tasks($order, $transaction_id)
    {
        global $woocommerce;
        if ($order->get_status() == 'completed')
            return;

        if ($order->get_status() == 'pending') {
            $order->add_order_note(
                sprintf("Credit card payment completed with transaction id of '%s'", $transaction_id)
            );
        }

        $order->payment_complete();
        $woocommerce->cart->empty_cart();

        WC()->session->set('order_awaiting_payment', null);
    }


    protected function do_order_on_hold_tasks($order, $transaction_id)
    {
        global $woocommerce;
        if ($order->get_status() == 'completed')
            return;

         if ($order->get_status() == 'pending') {
             $order->add_order_note(
                sprintf("Credit card authorize with transaction id of '%s'", $transaction_id)
            );
        }

        $order->update_status('on-hold', 'Awaiting payment capture');

        if (isset($woocommerce->cart)) {
            $woocommerce->cart->empty_cart();
        }
        if (WC()->session) {
            WC()->session->set('order_awaiting_payment', false);
        }
    }

    /**
     * Build the parameters for querying 3ds next-step
     *
     * @param $threeds_trans_id
     * @return array
     */
    private function build_threeds_query_request_parameters($threeds_trans_id, $threeDSMethodData)
    {
        if (empty($threeDSMethodData)) {
            return array(
                'transactionType'      => 'threeDSMethodCompletion',
                'version'              => '1.0',
                'signType'             => 'MD5',
                'merchantNo'           => self::get_merchant_no(),
                'threeDSServerTransId' => $threeds_trans_id,
                'threeDSCompleted'     => 'N'
            );
        } else {
            return array(
                'transactionType'      => 'threeDSMethodCompletion',
                'version'              => '1.0',
                'signType'             => 'MD5',
                'merchantNo'           => self::get_merchant_no(),
                'threeDSServerTransId' => $threeds_trans_id,
                'threeDSCompleted'     => 'Y'
            );
        }
    }

    function return_handle()
    {
        global $woocommerce;
        $settings = get_option( 'woocommerce_'.self::ID.'_settings', [] );
        if (!empty($_GET) && !empty($_GET['resp'])) {
            $_POST = json_decode(stripslashes(urldecode($_GET['resp'])), true);
        } else if (!empty($_GET) && !empty($_GET['resultCode'])) {
            $_POST = stripslashes_deep($_GET);
            unset($_POST['wc-api']);
            foreach ($_POST as $key => $value) {
                $_POST[$key] = urldecode($value);
            }
        } else {
            $_POST = stripslashes_deep($_POST);
        }

        $order_id = isset($_POST['echoParam']) ? $_POST['echoParam'] : '';
        $order    = wc_get_order($order_id);
        if (!$order) {
            WC_UseePay_Inner_Logger::log('[Return] Order not found. echoParam=' . $order_id);
            return;
        }

        WC_UseePay_Inner_Logger::log('[Return] Order #' . $order_id . ' response: ' . var_export($_POST, true));
        $security_key = isset($settings['useepay_key']) ? $settings['useepay_key'] : '';
        if (!Wc_UseePay_Inner_Util::verify_signature($_POST, $security_key)) {
            WC_UseePay_Inner_Logger::log('[Return] Signature verification failed for Order #' . $order_id);
            return;
        }

        //处理返回结果
        $result_code    = isset($_POST['resultCode']) ? $_POST['resultCode'] : '';
        $error_code     = isset($_POST['errorCode']) ? $_POST['errorCode'] : '';
        $errorMsg       = isset($_POST['errorMsg']) ? $_POST['errorMsg'] : '';
        $transaction_id = isset($_POST['transactionId']) ? $_POST['transactionId'] : '';

        if ($result_code == "succeed" || 'completed' === $order->get_status() || 'processing' === $order->get_status()) {
            $woocommerce->cart->empty_cart();
            WC_UseePay_Inner_Logger::log('[Return] Order #' . $order_id . ' succeed. transactionId=' . $transaction_id);
            $this->do_order_complete_tasks($order, $transaction_id);
            wp_safe_redirect($this->get_return_url($order));
        } else if ('failed' == $result_code || 'closed' == $result_code || 'cancelled' == $result_code) {
            WC_UseePay_Inner_Logger::log('[Return] Order #' . $order_id . ' failed. resultCode=' . $result_code);
            $order->update_status("failed");
            return;
        } else if ('pending' == $result_code) {
            wp_safe_redirect( $this->get_return_url( $order ) );
            exit;
        } else {
            if (!empty($_POST['redirectUrl'])) {
                $woocommerce->cart->empty_cart();
            }
            $appendHtml = "window.parent.location.href='" . $this->get_return_url($order) . "';";
            $html = "<div></div><script type='text/javascript'>if (window.parent.document.getElementById(\"isGather\")) { window.parent.postMessage(" . json_encode($_POST) . ", location.protocol + \"//\" + location.host);} else {$appendHtml}</script>";
            echo $html;
        }

        exit;
    }

    /**
     * UseePay async notify handle for payment
     */
    function payment_async_notify_handle()
    {
        sleep(3);
        $settings = get_option( 'woocommerce_'.self::ID.'_settings', [] );
        $_POST    = stripslashes_deep($_POST);

        $orderId       = isset($_POST['echoParam']) ? $_POST['echoParam'] : '';
        $transactionId = isset($_POST['transactionId']) ? $_POST['transactionId'] : '';
        $reference     = isset($_POST['reference']) ? $_POST['reference'] : '';

        $order = wc_get_order($orderId);
        if (!$order) {
            WC_UseePay_Inner_Logger::log('[Payment Notify] Order not found. echoParam=' . $orderId);
            return;
        }

        WC_UseePay_Inner_Logger::log('[Payment Notify] Order #' . $orderId . ', transactionId=' . $transactionId . ' received.');
        $security_key = isset($settings['useepay_key']) ? $settings['useepay_key'] : '';
        if (!Wc_UseePay_Inner_Util::verify_signature($_POST, $security_key)) {
            WC_UseePay_Inner_Logger::log('[Payment Notify] Signature verification failed. Order #' . $orderId);
            return;
        }

        //处理返回结果
        $resultCode  = isset($_POST['resultCode']) ? $_POST['resultCode'] : null;
        $errorMsg    = isset($_POST['errorMsg']) ? $_POST['errorMsg'] : null;
        $threeDSInfo = isset($_POST['threeDSInfo']) ? json_decode($_POST['threeDSInfo'], true) : null;

        if ('succeed' != $resultCode && 'failed' != $resultCode && 'closed' != $resultCode && 'cancelled' != $resultCode && 'pending_review' != $resultCode) {
            WC_UseePay_Inner_Logger::log('[Payment Notify] Order #' . $orderId . ' not in final status (resultCode=' . $resultCode . '), ignoring.');
            exit();
        }

        /**
         * 订单处于completed /processing 则不修改订单状态
         */
        if ('completed' === $order->get_status() || 'processing' === $order->get_status()){
            WC_UseePay_Inner_Logger::log('[Payment Notify] Order #' . $orderId . ' already ' . $order->get_status() . ', skipping.');
            return;
        }

        if ($resultCode == "succeed") {
            if ($threeDSInfo && isset($threeDSInfo['exemption'])) {
                WC_UseePay_Inner_Logger::log('[Payment Notify] 3DS Exemption: ' . $threeDSInfo['exemption']);
            }
            $this->do_order_complete_tasks($order, $reference);
            WC_UseePay_Inner_Logger::log('[Payment Notify] Order #' . $orderId . ' completed.');
            echo 'OK';
        } else if ('failed' == $resultCode || 'closed' == $resultCode || 'cancelled' == $resultCode) {
            global $woocommerce;
            $order->update_status("failed");
            $woocommerce->cart->empty_cart();
            WC_UseePay_Inner_Logger::log('[Payment Notify] Order #' . $orderId . ' marked as failed. resultCode=' . $resultCode);
            echo 'OK';
        } else if ("pending_review" == $resultCode) {
            $this->do_order_on_hold_tasks($order, $orderId);
            WC_UseePay_Inner_Logger::log('[Payment Notify] Order #' . $orderId . ' set to on-hold (pending_review).');
            echo 'ok';
        }
    }

    /**
     * Handle UseePay async notify for refund
     *
     * @access public
     * @return void
     */
    function refund_async_notify_handle()
    {
        $_POST = stripslashes_deep( $_POST );

        $transactionId         = isset($_POST['transactionId']) ? $_POST['transactionId'] : '';
        $originalTransactionId = isset($_POST['originalTransactionId']) ? $_POST['originalTransactionId'] : '';
        $reference             = isset($_POST['reference']) ? $_POST['reference'] : '';
        $echoParam             = isset($_POST['echoParam']) ? $_POST['echoParam'] : '';

        WC_UseePay_Inner_Logger::log('[Refund Notify] Received. transactionId=' . $transactionId . ', originalTransactionId=' . $originalTransactionId . ', reference=' . $reference);

        // 查找订单
        $order = wc_get_order($originalTransactionId);
        if (!$order && !empty($echoParam)) {
            WC_UseePay_Inner_Logger::log('[Refund Notify] Order not found by originalTransactionId=' . $originalTransactionId . ', trying echoParam=' . $echoParam);
            $order = wc_get_order($echoParam);
        }
        if (!$order) {
            WC_UseePay_Inner_Logger::log('[Refund Notify] Order not found. originalTransactionId=' . $originalTransactionId . ', echoParam=' . $echoParam . '. Aborting.');
            return;
        }

        WC_UseePay_Inner_Logger::log('[Refund Notify] Order #' . $order->get_id() . ' matched. Verifying signature...');
        if (!Wc_UseePay_Inner_Util::verify_signature($_POST, $this->get_security_key())) {
            WC_UseePay_Inner_Logger::log('[Refund Notify] Signature verification failed for reference=' . $reference);
            return;
        }

        //处理返回结果
        $resultCode = isset($_POST['resultCode']) ? $_POST['resultCode'] : null;
        $errorCode  = isset($_POST['errorCode']) ? $_POST['errorCode'] : null;
        $errorMsg   = isset($_POST['errorMsg']) ? $_POST['errorMsg'] : null;
        $amount     = isset($_POST['amount']) ? $_POST['amount'] : 0;

        if ($resultCode == "succeed" && $errorCode == "0000") {
            $refund_amount = Wc_UseePay_Inner_Util::convert_useepay_price_to_woo_price($order->get_currency(), $amount, 2);
            $order->add_order_note(
                sprintf('Credit card refund successful; Refund ID: %s; Refund Amount: %s', $reference, $refund_amount)
            );
            WC_UseePay_Inner_Logger::log('[Refund Notify] Success. Order #' . $order->get_id() . ', reference=' . $reference . ', amount=' . $refund_amount);
        } else {
            $errorMessage = $errorCode . "," . $errorMsg;
            $order->add_order_note(
                sprintf('Credit card refund failed; Refund ID: %s; Error Message: %s', $reference, $errorMessage)
            );
            WC_UseePay_Inner_Logger::log('[Refund Notify] Failed. Order #' . $order->get_id() . ', reference=' . $reference . ', error=' . $errorMessage);
        }
    }

    function get_goods_name_desc($order)
    {

        
        
        $result = array(
            "product_names"        => "",
            "product_descriptions" => ""
        );

        if (sizeof($order->get_items()) > 0) {
            foreach ($order->get_items() as $item) {
                if ($item['product_id'] > 0) {
                    if ($result["product_names"] != "") $result["product_names"] .= "|";
                    if ($result["product_descriptions"] != "") $result["product_descriptions"] .= "|";
                    $_product                       = $item->get_product();
                    $result["product_names"]        .= $_product->get_data()["name"];
                    $result["product_descriptions"] .= $_product->get_data()["description"];

                }
            }
        }
        //截断
        if (strlen($result["product_names"]) > 200) $result["product_names"] = mb_strcut($result["product_names"], 0, 256);
        if (strlen($result["product_descriptions"]) > 2000) $result["product_descriptions"] = mb_strcut($result["product_descriptions"], 0, 2000);

        //  var_dump($result);
        return $result;
    }

    function clean($str = '')
    {
        $clean = str_replace(array('%'), '', $str);
        $clean = sanitize_text_field($clean);
        $clean = html_entity_decode($clean, ENT_NOQUOTES);
        return $clean;
    }


    function wc_useepay_display_order_meta_for_admin($order)
    {
        $trade_no = get_post_meta($order->get_id(), 'UseePay Trade No.', true);
        if (!empty($trade_no)) {
            echo '<p><strong>UseePay Transaction ID:</strong><br />' . $trade_no . '</p>';
        }
    }

    function query_order_status()
    {
        $order_id = isset($_GET['order_id']) ? $_GET['order_id'] : '';
        if (empty($order_id)) {
            WC_UseePay_Inner_Logger::log('[Query] Missing order_id parameter');
            exit(-1);
        }
        $order = wc_get_order($order_id);
        if (!$order) {
            WC_UseePay_Inner_Logger::log('[Query] Order #' . $order_id . ' not found');
            exit(-1);
        }
        WC_UseePay_Inner_Logger::log('[Query] Order #' . $order_id . ' status: ' . $order->get_status());
        exit($order->get_status());
    }

    protected function get_useepay_order_transaction_id( WC_Order $order ): ?string {
		return  substr($order->get_order_number() . '.' . md5(uniqid(microtime(true), true)), 0, 16);
	}
}

?>
