Changeset 3288756
- Timestamp:
- 05/07/2025 03:01:58 AM (11 months ago)
- Location:
- sepay-gateway/trunk
- Files:
-
- 4 edited
-
includes/class-wc-gateway-sepay.php (modified) (5 diffs)
-
includes/class-wc-sepay-api.php (modified) (5 diffs)
-
readme.txt (modified) (1 diff)
-
sepay-gateway.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
sepay-gateway/trunk/includes/class-wc-gateway-sepay.php
r3287649 r3288756 43 43 $this->bank_name_display_type = $this->get_option('show_bank_name'); 44 44 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(); 65 46 66 47 $this->get_bank_account_data(); … … 134 115 if ($this->cached_bank_account_data === null && $this->get_option('bank_account')) { 135 116 $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 } 136 125 } 137 126 return $this->cached_bank_account_data; … … 615 604 $order = wc_get_order($order_id); 616 605 $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) { 624 608 $bank_account_id = $this->get_option('bank_account'); 625 609 $bank_account = $this->api->get_bank_account($bank_account_id); 626 610 $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 } 627 642 } 628 643 … … 634 649 'https://qr.sepay.vn/img?acc=%s&bank=%s&amount=%s&des=%s&template=compact', 635 650 $account_number, 636 $ this->bank_bin,651 $bank_bin, 637 652 $order->get_total(), 638 653 $remark 639 654 ); 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;644 655 645 656 require_once plugin_dir_path(__FILE__) . 'views/transfer-info.php'; … … 790 801 require_once plugin_dir_path(__FILE__) . 'views/setup-webhook.php'; 791 802 } 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 } 792 827 } -
sepay-gateway/trunk/includes/class-wc-sepay-api.php
r3287649 r3288756 131 131 } 132 132 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 133 143 public function make_request($endpoint, $method = 'GET', $data = null) 134 144 { 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) { 171 150 try { 172 $ this->refresh_token();151 $access_token = $this->get_access_token(); 173 152 } 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'); 174 167 return null; 175 168 } 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; 180 235 } 181 236 … … 221 276 { 222 277 $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'); 224 279 225 280 if (empty($access_token)) { … … 227 282 } 228 283 229 if ( (int) $token_expires < time()) {284 if ($token_expires < time() + 300) { 230 285 $access_token = $this->refresh_token(); 231 286 } … … 328 383 update_option('wc_sepay_webhook_id', $response['data']['id'] ?? $webhook_id ?? null); 329 384 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); 330 388 } 331 389 … … 428 486 return in_array($bank_account[$key]['bank']['short_name'], $required_sub_account_banks); 429 487 } 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 } 430 519 } -
sepay-gateway/trunk/readme.txt
r3287649 r3288756 4 4 - Tags: woocommerce, payment gateway, vietqr, ngan hang, thanh toan 5 5 - Requires WooCommerce at least: 2.1 6 - Stable Tag: 1.1. 67 - Version: 1.1. 66 - Stable Tag: 1.1.7 7 - Version: 1.1.7 8 8 - Tested up to: 6.6 9 9 - Requires at least: 5.6 -
sepay-gateway/trunk/sepay-gateway.php
r3287649 r3288756 6 6 * Author: SePay Team 7 7 * Author URI: https://sepay.vn/ 8 * Version: 1.1. 68 * Version: 1.1.7 9 9 * Requires Plugins: woocommerce 10 10 * Text Domain: sepay-gateway
Note: See TracChangeset
for help on using the changeset viewer.