Plugin Directory

Changeset 3288756


Ignore:
Timestamp:
05/07/2025 03:01:58 AM (11 months ago)
Author:
sepayteam
Message:

Fix php oauth token expire bug

Location:
sepay-gateway/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • sepay-gateway/trunk/includes/class-wc-gateway-sepay.php

    r3287649 r3288756  
    4343        $this->bank_name_display_type = $this->get_option('show_bank_name');
    4444
    45         $bank_data = array(
    46             'vietcombank' => array('bin' => '970436', 'code' => 'VCB', 'short_name' => 'Vietcombank', 'full_name' => 'Ngân hàng TMCP Ngoại Thương Việt Nam'),
    47             'vpbank' => array('bin' => '970432', 'code' => 'VPB', 'short_name' => 'VPBank', 'full_name' => 'Ngân hàng TMCP Việt Nam Thịnh Vượng'),
    48             'acb' => array('bin' => '970416', 'code' => 'ACB', 'short_name' => 'ACB', 'full_name' => 'Ngân hàng TMCP Á Châu'),
    49             'sacombank' => array('bin' => '970403', 'code' => 'STB', 'short_name' => 'Sacombank', 'full_name' => 'Ngân hàng TMCP Sài Gòn Thương Tín'),
    50             'hdbank' => array('bin' => '970437', 'code' => 'HDB', 'short_name' => 'HDBank', 'full_name' => 'Ngân hàng TMCP Phát triển Thành phố Hồ Chí Minh'),
    51             'vietinbank' => array('bin' => '970415', 'code' => 'ICB', 'short_name' => 'VietinBank', 'full_name' => 'Ngân hàng TMCP Công thương Việt Nam'),
    52             'techcombank' => array('bin' => '970407', 'code' => 'TCB', 'short_name' => 'Techcombank', 'full_name' => 'Ngân hàng TMCP Kỹ thương Việt Nam'),
    53             'mbbank' => array('bin' => '970422', 'code' => 'MB', 'short_name' => 'MBBank', 'full_name' => 'Ngân hàng TMCP Quân đội'),
    54             'bidv' => array('bin' => '970418', 'code' => 'BIDV', 'short_name' => 'BIDV', 'full_name' => 'Ngân hàng TMCP Đầu tư và Phát triển Việt Nam'),
    55             'msb' => array('bin' => '970426', 'code' => 'MSB', 'short_name' => 'MSB', 'full_name' => 'Ngân hàng TMCP Hàng Hải Việt Nam'),
    56             'shinhanbank' => array('bin' => '970424', 'code' => 'SHBVN', 'short_name' => 'ShinhanBank', 'full_name' => 'Ngân hàng TNHH MTV Shinhan Việt Nam'),
    57             'tpbank' => array('bin' => '970423', 'code' => 'TPB', 'short_name' => 'TPBank', 'full_name' => 'Ngân hàng TMCP Tiên Phong'),
    58             'eximbank' => array('bin' => '970431', 'code' => 'EIB', 'short_name' => 'Eximbank', 'full_name' => 'Ngân hàng TMCP Xuất Nhập khẩu Việt Nam'),
    59             'vib' => array('bin' => '970441', 'code' => 'VIB', 'short_name' => 'VIB', 'full_name' => 'Ngân hàng TMCP Quốc tế Việt Nam'),
    60             'agribank' => array('bin' => '970405', 'code' => 'VBA', 'short_name' => 'Agribank', 'full_name' => 'Ngân hàng Nông nghiệp và Phát triển Nông thôn Việt Nam'),
    61             'publicbank' => array('bin' => '970439', 'code' => 'PBVN', 'short_name' => 'PublicBank', 'full_name' => 'Ngân hàng TNHH MTV Public Việt Nam'),
    62             'kienlongbank' =>  array('bin' => '970452', 'code' => 'KLB', 'short_name' => 'KienLongBank', 'full_name' => 'Ngân hàng TMCP Kiên Long'),
    63             'ocb' => array('bin' => '970448', 'code' => 'OCB', 'short_name' => 'OCB', 'full_name' => 'Ngân hàng TMCP Phương Đông'),
    64         );
     45        $bank_data = $this->get_bank_data();
    6546
    6647        $this->get_bank_account_data();
     
    134115        if ($this->cached_bank_account_data === null && $this->get_option('bank_account')) {
    135116            $this->cached_bank_account_data = $this->api->get_bank_account($this->get_option('bank_account'));
     117           
     118            if ($this->cached_bank_account_data) {
     119                $settings = get_option('woocommerce_sepay_settings', []);
     120                $settings['bank_select'] = strtolower($this->cached_bank_account_data['bank']['short_name']);
     121                $settings['bank_account_number'] = $this->cached_bank_account_data['account_number'];
     122                $settings['bank_account_holder'] = $this->cached_bank_account_data['account_holder_name'];
     123                update_option('woocommerce_sepay_settings', $settings);
     124            }
    136125        }
    137126        return $this->cached_bank_account_data;
     
    615604        $order = wc_get_order($order_id);
    616605        $remark = $this->get_remark($order_id);
    617         if (! $this->api->is_connected()) {
    618             $account_number = $this->get_option('bank_account_number');
    619         } else {
    620             if (! $this->cached_bank_account_data) {
    621                 return;
    622             }
    623 
     606       
     607        if ($this->api->is_connected() && $this->cached_bank_account_data) {
    624608            $bank_account_id = $this->get_option('bank_account');
    625609            $bank_account = $this->api->get_bank_account($bank_account_id);
    626610            $account_number = $this->get_option('sub_account') ? $this->get_option('sub_account') : $bank_account['account_number'];
     611            $account_holder_name = $this->cached_bank_account_data['account_holder_name'];
     612            $bank_bin = $this->cached_bank_account_data['bank']['bin'];
     613            $bank_logo_url = $this->cached_bank_account_data['bank']['logo_url'];
     614            $displayed_bank_name = $this->displayed_bank_name;
     615        } else {
     616            $account_number = $this->get_option('bank_account_number');
     617            $account_holder_name = $this->get_option('bank_account_holder');
     618           
     619            $bank_select = $this->get_option('bank_select');
     620            $bank_info = null;
     621            foreach ($this->get_bank_data() as $bank) {
     622                if ($bank['code'] === strtoupper($bank_select)) {
     623                    $bank_info = $bank;
     624                    break;
     625                }
     626            }
     627
     628            if ($bank_info) {
     629                $bank_bin = $bank_info['bin'];
     630                $bank_logo_url = sprintf('https://my.sepay.vn/assets/images/banklogo/%s.png', strtolower($bank_info['short_name']));
     631               
     632                if ($this->bank_name_display_type == "brand_name") {
     633                    $displayed_bank_name = $bank_info['short_name'];
     634                } else if ($this->bank_name_display_type == "full_name") {
     635                    $displayed_bank_name = $bank_info['full_name'];
     636                } else if ($this->bank_name_display_type == "full_include_brand") {
     637                    $displayed_bank_name = $bank_info['full_name'] . " (" . $bank_info['short_name'] . ")";
     638                } else {
     639                    $displayed_bank_name = $bank_info['short_name'];
     640                }
     641            }
    627642        }
    628643
     
    634649            'https://qr.sepay.vn/img?acc=%s&bank=%s&amount=%s&des=%s&template=compact',
    635650            $account_number,
    636             $this->bank_bin,
     651            $bank_bin,
    637652            $order->get_total(),
    638653            $remark
    639654        );
    640 
    641         $bank_logo_url = $this->bank_logo_url;
    642         $account_holder_name = $this->api->is_connected() ? $this->cached_bank_account_data['account_holder_name'] : $this->get_option('bank_account_holder');
    643         $displayed_bank_name = $this->displayed_bank_name;
    644655
    645656        require_once plugin_dir_path(__FILE__) . 'views/transfer-info.php';
     
    790801        require_once plugin_dir_path(__FILE__) . 'views/setup-webhook.php';
    791802    }
     803
     804    private function get_bank_data()
     805    {
     806        return array(
     807            'vietcombank' => array('bin' => '970436', 'code' => 'VCB', 'short_name' => 'Vietcombank', 'full_name' => 'Ngân hàng TMCP Ngoại Thương Việt Nam'),
     808            'vpbank' => array('bin' => '970432', 'code' => 'VPB', 'short_name' => 'VPBank', 'full_name' => 'Ngân hàng TMCP Việt Nam Thịnh Vượng'),
     809            'acb' => array('bin' => '970416', 'code' => 'ACB', 'short_name' => 'ACB', 'full_name' => 'Ngân hàng TMCP Á Châu'),
     810            'sacombank' => array('bin' => '970403', 'code' => 'STB', 'short_name' => 'Sacombank', 'full_name' => 'Ngân hàng TMCP Sài Gòn Thương Tín'),
     811            'hdbank' => array('bin' => '970437', 'code' => 'HDB', 'short_name' => 'HDBank', 'full_name' => 'Ngân hàng TMCP Phát triển Thành phố Hồ Chí Minh'),
     812            'vietinbank' => array('bin' => '970415', 'code' => 'ICB', 'short_name' => 'VietinBank', 'full_name' => 'Ngân hàng TMCP Công thương Việt Nam'),
     813            'techcombank' => array('bin' => '970407', 'code' => 'TCB', 'short_name' => 'Techcombank', 'full_name' => 'Ngân hàng TMCP Kỹ thương Việt Nam'),
     814            'mbbank' => array('bin' => '970422', 'code' => 'MB', 'short_name' => 'MBBank', 'full_name' => 'Ngân hàng TMCP Quân đội'),
     815            'bidv' => array('bin' => '970418', 'code' => 'BIDV', 'short_name' => 'BIDV', 'full_name' => 'Ngân hàng TMCP Đầu tư và Phát triển Việt Nam'),
     816            'msb' => array('bin' => '970426', 'code' => 'MSB', 'short_name' => 'MSB', 'full_name' => 'Ngân hàng TMCP Hàng Hải Việt Nam'),
     817            'shinhanbank' => array('bin' => '970424', 'code' => 'SHBVN', 'short_name' => 'ShinhanBank', 'full_name' => 'Ngân hàng TNHH MTV Shinhan Việt Nam'),
     818            'tpbank' => array('bin' => '970423', 'code' => 'TPB', 'short_name' => 'TPBank', 'full_name' => 'Ngân hàng TMCP Tiên Phong'),
     819            'eximbank' => array('bin' => '970431', 'code' => 'EIB', 'short_name' => 'Eximbank', 'full_name' => 'Ngân hàng TMCP Xuất Nhập khẩu Việt Nam'),
     820            'vib' => array('bin' => '970441', 'code' => 'VIB', 'short_name' => 'VIB', 'full_name' => 'Ngân hàng TMCP Quốc tế Việt Nam'),
     821            'agribank' => array('bin' => '970405', 'code' => 'VBA', 'short_name' => 'Agribank', 'full_name' => 'Ngân hàng Nông nghiệp và Phát triển Nông thôn Việt Nam'),
     822            'publicbank' => array('bin' => '970439', 'code' => 'PBVN', 'short_name' => 'PublicBank', 'full_name' => 'Ngân hàng TNHH MTV Public Việt Nam'),
     823            'kienlongbank' =>  array('bin' => '970452', 'code' => 'KLB', 'short_name' => 'KienLongBank', 'full_name' => 'Ngân hàng TMCP Kiên Long'),
     824            'ocb' => array('bin' => '970448', 'code' => 'OCB', 'short_name' => 'OCB', 'full_name' => 'Ngân hàng TMCP Phương Đông'),
     825        );
     826    }
    792827}
  • sepay-gateway/trunk/includes/class-wc-sepay-api.php

    r3287649 r3288756  
    131131    }
    132132
     133    private function log_error($message, $context = []) {
     134        if (function_exists('wc_get_logger')) {
     135            $logger = wc_get_logger();
     136            $logger->error($message, [
     137                'source' => 'sepay',
     138                'context' => $context
     139            ]);
     140        }
     141    }
     142
    133143    public function make_request($endpoint, $method = 'GET', $data = null)
    134144    {
    135         try {
    136             $access_token = $this->get_access_token();
    137         } catch (Exception $e) {
    138             return null;
    139         }
    140 
    141         if (!$access_token) {
    142             return null;
    143         }
    144 
    145         $args = [
    146             'method' => $method,
    147             'headers' => [
    148                 'Authorization' => 'Bearer ' . $access_token,
    149                 'Content-Type' => 'application/json',
    150             ],
    151             'sslverify' => false,
    152         ];
    153 
    154         if ($data !== null && $method !== 'GET') {
    155             $args['body'] = json_encode($data);
    156         } else if ($data !== null && $method === 'GET') {
    157             $endpoint .= '?' . http_build_query($data);
    158         }
    159 
    160         $url = SEPAY_API_URL . '/api/v1/' . $endpoint;
    161 
    162         $response = wp_remote_request($url, $args);
    163 
    164         if (is_wp_error($response)) {
    165             throw new Exception(esc_html($response->get_error_message()));
    166         }
    167 
    168         $data = json_decode(wp_remote_retrieve_body($response), true);
    169 
    170         if (isset($data['error']) && $data['error'] === 'access_denied') {
     145        $max_retries = 3;
     146        $retry_count = 0;
     147        $retry_delay = 1; // seconds
     148
     149        while ($retry_count < $max_retries) {
    171150            try {
    172                 $this->refresh_token();
     151                $access_token = $this->get_access_token();
    173152            } catch (Exception $e) {
     153                $this->log_error('Failed to get access token', [
     154                    'error' => $e->getMessage(),
     155                    'retry_count' => $retry_count
     156                ]);
     157                if ($retry_count === $max_retries - 1) {
     158                    return null;
     159                }
     160                $retry_count++;
     161                sleep($retry_delay);
     162                continue;
     163            }
     164
     165            if (!$access_token) {
     166                $this->log_error('No access token available');
    174167                return null;
    175168            }
    176             return $this->make_request($endpoint, $method, $data);
    177         }
    178 
    179         return $data;
     169
     170            $args = [
     171                'method' => $method,
     172                'headers' => [
     173                    'Authorization' => 'Bearer ' . $access_token,
     174                    'Content-Type' => 'application/json',
     175                ],
     176                'sslverify' => false,
     177                'timeout' => 30,
     178            ];
     179
     180            if ($data !== null && $method !== 'GET') {
     181                $args['body'] = json_encode($data);
     182            } else if ($data !== null && $method === 'GET') {
     183                $endpoint .= '?' . http_build_query($data);
     184            }
     185
     186            $url = SEPAY_API_URL . '/api/v1/' . $endpoint;
     187
     188            $response = wp_remote_request($url, $args);
     189
     190            if (is_wp_error($response)) {
     191                $this->log_error('API request failed', [
     192                    'error' => $response->get_error_message(),
     193                    'endpoint' => $endpoint,
     194                    'retry_count' => $retry_count
     195                ]);
     196                if ($retry_count === $max_retries - 1) {
     197                    throw new Exception(esc_html($response->get_error_message()));
     198                }
     199                $retry_count++;
     200                sleep($retry_delay);
     201                continue;
     202            }
     203
     204            $data = json_decode(wp_remote_retrieve_body($response), true);
     205
     206            if (isset($data['error']) && $data['error'] === 'access_denied') {
     207                $this->log_error('Access denied, attempting to refresh token', [
     208                    'endpoint' => $endpoint
     209                ]);
     210                try {
     211                    $this->refresh_token();
     212                } catch (Exception $e) {
     213                    $this->log_error('Failed to refresh token', [
     214                        'error' => $e->getMessage(),
     215                        'retry_count' => $retry_count
     216                    ]);
     217                    if ($retry_count === $max_retries - 1) {
     218                        return null;
     219                    }
     220                    $retry_count++;
     221                    sleep($retry_delay);
     222                    continue;
     223                }
     224                return $this->make_request($endpoint, $method, $data);
     225            }
     226
     227            return $data;
     228        }
     229
     230        $this->log_error('Max retries reached for API request', [
     231            'endpoint' => $endpoint,
     232            'method' => $method
     233        ]);
     234        return null;
    180235    }
    181236
     
    221276    {
    222277        $access_token = get_option('wc_sepay_access_token');
    223         $token_expires = get_option('wc_sepay_token_expires');
     278        $token_expires = (int) get_option('wc_sepay_token_expires');
    224279
    225280        if (empty($access_token)) {
     
    227282        }
    228283
    229         if ((int) $token_expires < time()) {
     284        if ($token_expires < time() + 300) {
    230285            $access_token = $this->refresh_token();
    231286        }
     
    328383            update_option('wc_sepay_webhook_id', $response['data']['id'] ?? $webhook_id ?? null);
    329384            update_option('wc_sepay_webhook_api_key', $api_key);
     385            $settings = get_option('woocommerce_sepay_settings', []);
     386            $settings['api_key'] = $api_key;
     387            update_option('woocommerce_sepay_settings', $settings);
    330388        }
    331389
     
    428486        return in_array($bank_account[$key]['bank']['short_name'], $required_sub_account_banks);
    429487    }
     488
     489    public function check_connection_health() {
     490        try {
     491            $response = $this->make_request('me');
     492            if ($response && isset($response['data'])) {
     493                return true;
     494            }
     495            return false;
     496        } catch (Exception $e) {
     497            $this->log_error('Health check failed', [
     498                'error' => $e->getMessage()
     499            ]);
     500            return false;
     501        }
     502    }
     503
     504    public function get_connection_status() {
     505        $access_token = get_option('wc_sepay_access_token');
     506        $refresh_token = get_option('wc_sepay_refresh_token');
     507        $token_expires = get_option('wc_sepay_token_expires');
     508        $last_connected_at = get_option('wc_sepay_last_connected_at');
     509
     510        $status = [
     511            'is_connected' => !empty($access_token) && !empty($refresh_token),
     512            'token_expires_in' => $token_expires ? ($token_expires - time()) : 0,
     513            'last_connected_at' => $last_connected_at,
     514            'health_check' => $this->check_connection_health()
     515        ];
     516
     517        return $status;
     518    }
    430519}
  • sepay-gateway/trunk/readme.txt

    r3287649 r3288756  
    44 - Tags: woocommerce, payment gateway, vietqr, ngan hang, thanh toan
    55 - Requires WooCommerce at least: 2.1
    6  - Stable Tag: 1.1.6
    7  - Version: 1.1.6
     6 - Stable Tag: 1.1.7
     7 - Version: 1.1.7
    88 - Tested up to: 6.6
    99 - Requires at least: 5.6
  • sepay-gateway/trunk/sepay-gateway.php

    r3287649 r3288756  
    66 * Author: SePay Team
    77 * Author URI: https://sepay.vn/
    8  * Version: 1.1.6
     8 * Version: 1.1.7
    99 * Requires Plugins: woocommerce
    1010 * Text Domain: sepay-gateway
Note: See TracChangeset for help on using the changeset viewer.