Changeset 3462156
- Timestamp:
- 02/16/2026 02:33:16 AM (6 weeks ago)
- Location:
- triplea-cryptocurrency-payment-gateway-for-woocommerce/trunk
- Files:
-
- 3 edited
-
includes/WooCommerce/TripleA_Payment_Gateway.php (modified) (10 diffs)
-
readme.txt (modified) (3 diffs)
-
triplea-cryptocurrency-payment-gateway-for-woocommerce.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
triplea-cryptocurrency-payment-gateway-for-woocommerce/trunk/includes/WooCommerce/TripleA_Payment_Gateway.php
r3446959 r3462156 63 63 $this->clientID = $this->get_option('client_id'); 64 64 $this->clientSecret = $this->decrypt_credential($this->get_option('client_secret')); 65 $this->oauthToken = $this-> get_option('oauth_token');65 $this->oauthToken = $this->decrypt_credential($this->get_option('oauth_token')); 66 66 $this->oauthTokenExpiry = $this->get_option('oauth_token_expiry'); 67 67 68 68 $this->logger = Logger::get_instance(); 69 70 // Migrate plaintext OAuth token to encrypted storage (one-time migration for existing installations) 71 if (!empty($this->oauthToken) && strpos($this->get_option('oauth_token'), 'ENC:') !== 0) { 72 // Token exists in plaintext (not encrypted) - migrate it 73 $encrypted_token = $this->encrypt_credential($this->oauthToken); 74 if ($encrypted_token !== false) { 75 $this->update_option('oauth_token', $encrypted_token); 76 $this->logger->write_log('OAuth token successfully migrated to encrypted storage', true); 77 } else { 78 $this->logger->write_log('MIGRATION ERROR: Failed to encrypt existing OAuth token. Check TRIPLEA_ENCRYPTION_KEY in wp-config.php', true); 79 } 80 } 69 81 70 82 $this->triplea_set_api_endpoint_token(); … … 158 170 // Nonce is verified by WooCommerce settings save process 159 171 $client_secret_raw = null; 160 $client_secret_posted = !empty($_POST['woocommerce_triplea_payment_gateway_client_secret']) ? sanitize_text_field(wp_unslash($_POST['woocommerce_triplea_payment_gateway_client_secret'])) : ''; 172 $client_secret_posted = ''; 173 174 if (!empty($_POST['woocommerce_triplea_payment_gateway_client_secret'])) { 175 $client_secret_posted = wp_unslash($_POST['woocommerce_triplea_payment_gateway_client_secret']); 176 177 // Validate format: alphanumeric + common special chars, 16-256 chars 178 if (!preg_match('/^[a-zA-Z0-9\-_+=\/]{16,256}$/', $client_secret_posted)) { 179 add_settings_error( 180 'triplea_payment_gateway', 181 'invalid_client_secret', 182 __('Invalid client secret format. Must be 16-256 characters (alphanumeric and -_+=/)', 'triplea-cryptocurrency-payment-gateway-for-woocommerce'), 183 'error' 184 ); 185 return; // Stop processing 186 } 187 } 161 188 162 189 // Check if encryption key is defined … … 200 227 } 201 228 202 $response = wp_remote_post('https://api.triple-a.io/api/v2/oauth/token', array( 203 'headers' => array( 204 'Content-Type' => 'application/x-www-form-urlencoded', 205 ), 206 'body' => array( 207 'client_id' => isset($_POST['woocommerce_triplea_payment_gateway_client_id']) ? sanitize_text_field(wp_unslash($_POST['woocommerce_triplea_payment_gateway_client_id'])) : '', 229 $client_id_posted = ''; 230 if (!empty($_POST['woocommerce_triplea_payment_gateway_client_id'])) { 231 $client_id_posted = wp_unslash($_POST['woocommerce_triplea_payment_gateway_client_id']); 232 233 // Validate format: alphanumeric + common special chars 234 if (!preg_match('/^[a-zA-Z0-9\-_]{8,128}$/', $client_id_posted)) { 235 add_settings_error( 236 'triplea_payment_gateway', 237 'invalid_client_id', 238 __('Invalid client ID format. Must be 8-128 characters (alphanumeric and -_)', 'triplea-cryptocurrency-payment-gateway-for-woocommerce'), 239 'error' 240 ); 241 return; 242 } 243 } 244 245 $response = $this->secure_post( 246 'https://api.triple-a.io/api/v2/oauth/token', 247 [ 248 'client_id' => $client_id_posted, 208 249 'client_secret' => $client_secret_raw, 209 'grant_type' => 'client_credentials', 210 ), 211 )); 212 213 if (!is_wp_error($response)) { 214 // The request went through successfully, check the response code against 215 // what we're expecting 216 if (200 == wp_remote_retrieve_response_code($response)) { 217 // Do something with the response 218 $body = json_decode(wp_remote_retrieve_body($response)); 219 } else { 220 // The response code was not what we were expecting, record the message 221 $error_message = wp_remote_retrieve_response_message($response); 222 } 250 'grant_type' => 'client_credentials', 251 ] 252 ); 253 254 if (!$response['error'] && $response['code'] === 200) { 255 $body = json_decode($response['body']); 223 256 } else { 224 257 // There was an error making the request 225 $error_message = $response ->get_error_message();258 $error_message = $response['error'] ?: 'HTTP ' . $response['code']; 226 259 } 227 260 //exit; 228 261 229 $this->settings['oauth_token'] = $body->access_token; 230 $this->settings['oauth_token_expiry'] = $body->expires_in; 262 if (isset($body->access_token)) { 263 $this->settings['oauth_token'] = $this->encrypt_credential($body->access_token); 264 $this->settings['oauth_token_expiry'] = time() + $body->expires_in; 265 } 231 266 } 232 267 … … 747 782 $this->oauthToken = $new_token_data->access_token; 748 783 $this->oauthTokenExpiry = $date_now + $new_token_data->expires_in; 749 $this->update_option('oauth_token', $this-> oauthToken);784 $this->update_option('oauth_token', $this->encrypt_credential($this->oauthToken)); 750 785 $this->update_option('oauth_token_expiry', $this->oauthTokenExpiry); 751 786 $this->logger->write_log('refreshOauthToken() Obtained and saved a new oauth token.', $this->debugLog); … … 779 814 $buffer_time = 600; // 10 min buffer time, so new token will generated after 50 min 780 815 $current_token_expiry = intval($this->get_option('oauth_token_expiry')); 781 $current_token = $this->get_option('oauth_token'); 816 $current_token_encrypted = $this->get_option('oauth_token'); 817 $current_token = $this->decrypt_credential($current_token_encrypted); 782 818 783 819 if ($this->isOauthTokenInvalid()) { … … 800 836 $this->oauthToken = $new_token_data->access_token; 801 837 $this->oauthTokenExpiry = $date_now + $new_token_data->expires_in; 802 $this->update_option('oauth_token', $this-> oauthToken);838 $this->update_option('oauth_token', $this->encrypt_credential($this->oauthToken)); 803 839 $this->update_option('oauth_token_expiry', $this->oauthTokenExpiry); 804 840 … … 831 867 { 832 868 833 $post_url = 'https://api.triple-a.io/api/v2/oauth/token'; 834 $body = [ 835 'client_id' => $client_id, 836 'client_secret' => $client_secret, 837 'grant_type' => 'client_credentials', 838 ]; 839 840 // $this->logger->write_log( 'Making an oauth token request with body: \n' . wc_print_r($body, TRUE), $this->debugLog ); 841 $this->logger->write_log('Making an oauth token request with clinet id: \n' . wc_print_r($client_id, true), $this->debugLog); 842 843 $result = wp_remote_post($post_url, [ 844 'method' => 'POST', 845 'headers' => [ 846 'content-type' => 'application/x-www-form-urlencoded; charset=utf-8', 847 ], 848 //'sslverify' => false, 849 'body' => $body, 850 'data_format' => 'body', 851 ]); 852 853 if (is_wp_error($result)) { 869 $this->logger->write_log('Making an oauth token request with client id: \n' . wc_print_r($client_id, true), $this->debugLog); 870 871 $response = $this->secure_post( 872 'https://api.triple-a.io/api/v2/oauth/token', 873 [ 874 'client_id' => $client_id, 875 'client_secret' => $client_secret, 876 'grant_type' => 'client_credentials', 877 ] 878 ); 879 880 if ($response['error'] || $response['code'] !== 200) { 881 $this->logger->write_log('OAuth token request failed with code: ' . $response['code'], $this->debugLog); 854 882 return ['error' => 'Error happened, could not complete the oauth token request.']; 855 883 } 856 884 857 $this->logger->write_log( "Oauth token request object: \n" . wc_print_r($result['body'], true), $this->debugLog);858 859 return json_decode($res ult['body']);885 $this->logger->write_log('OAuth token request completed successfully', $this->debugLog); 886 887 return json_decode($response['body']); 860 888 } 861 889 public static function custom_user_agent($user_agent, $url) … … 912 940 $self->logger->write_log('Making a payment form API request with body: ' . wc_print_r($body, true), $self->debugLog); 913 941 914 $result = wp_remote_post($post_url, [ 915 'method' => 'POST', 916 'headers' => [ 942 $response = $self->secure_post( 943 'https://api.triple-a.io/api/v2/payment', 944 json_encode($body), 945 [ 917 946 'Authorization' => 'Bearer ' . $oauth_token, 918 947 'Content-Type' => 'application/json; charset=utf-8', 919 ], 920 //'sslverify' => false, 921 'body' => json_encode($body), 922 'data_format' => 'body', 923 ]); 924 925 if (is_wp_error($result)) { 948 ] 949 ); 950 951 if ($response['error']) { 926 952 return ['error' => 'Error happened, could not complete the payment form request.']; 927 953 } 928 $self->logger->write_log('Payment form request response: \n' . wc_print_r($result['body'], true), $self->debugLog); 929 930 if ($result['response']['code'] > 299) { 954 955 $self->logger->write_log('Payment form request completed with code: ' . $response['code'], $self->debugLog); 956 957 if ($response['code'] > 299) { 931 958 return json_encode([ 932 959 'error' => 'Error happened, could not complete the payment form request.', 933 'code' => $res ult['response']['code'],934 'message' => $result['response']['message'],960 'code' => $response['code'], 961 'message' => 'HTTP Error', 935 962 ]); 936 963 } 937 964 938 $json_result = json_decode($res ult['body']);965 $json_result = json_decode($response['body']); 939 966 if (!isset($json_result->payment_reference)) { 940 967 return json_encode([ … … 1643 1670 { 1644 1671 1645 $oauth_token = $this-> get_option('oauth_token');1672 $oauth_token = $this->decrypt_credential($this->get_option('oauth_token')); 1646 1673 if (empty($oauth_token)) { 1647 1674 wp_die('Missing oauth token for bitcoin payments with local currency settlement.'); 1648 1675 } 1649 1676 1650 $post_url = "https://api.triple-a.io/api/v2/payment/$payment_reference"; 1651 1652 $result = wp_remote_get($post_url, [ 1653 'headers' => [ 1654 'Authorization' => 'Bearer ' . $oauth_token, 1655 ], 1656 //'sslverify' => false, 1657 //'body' => json_encode($body), 1658 'data_format' => 'body', 1677 $url = 'https://api.triple-a.io/api/v2/payment/' . urlencode($payment_reference); 1678 1679 $response = $this->secure_get($url, [ 1680 'Authorization' => 'Bearer ' . $oauth_token, 1659 1681 ]); 1660 1682 1661 if (is_wp_error($result)) { 1662 wp_die('Could not complete the payment status API request.'); 1663 } 1664 1665 if ($result['response']['code'] > 299) { 1683 if ($response['error']) { 1684 return (object) [ 1685 'error' => 'Could not complete the payment status API request.', 1686 'code' => 0, 1687 'message' => $response['error'], 1688 ]; 1689 } 1690 1691 if ($response['code'] > 299) { 1666 1692 return (object) [ 1667 1693 'error' => 'Error happened, could not complete the payment form request.', 1668 'code' => $res ult['response']['code'],1669 'message' => $result['response']['message'],1694 'code' => $response['code'], 1695 'message' => 'HTTP Error', 1670 1696 ]; 1671 1697 } 1672 1698 1673 $json_result = json_decode($res ult['body']);1699 $json_result = json_decode($response['body']); 1674 1700 if (!isset($json_result->payment_reference)) { 1675 1701 return [ … … 2573 2599 return true; 2574 2600 } 2601 2602 /** 2603 * Secure POST request bypassing WordPress HTTP filters 2604 * Prevents credential interception by third-party plugins 2605 * 2606 * @param string $url 2607 * @param array|string $body 2608 * @param array $headers 2609 * @return array 2610 */ 2611 private function secure_post($url, $body, $headers = []) 2612 { 2613 // Validate API endpoint - only allow TripleA API calls 2614 if (strpos($url, 'https://api.triple-a.io/') !== 0) { 2615 if (isset($this->logger)) { 2616 $this->logger->write_log('secure_post(): Blocked invalid API endpoint: ' . $url, true); 2617 } 2618 return [ 2619 'body' => '', 2620 'code' => 0, 2621 'error' => 'Invalid API endpoint', 2622 ]; 2623 } 2624 2625 $ch = curl_init($url); 2626 2627 $header_array = []; 2628 $has_content_type = false; 2629 2630 // Add User-Agent header matching existing custom_user_agent() format 2631 $version = get_option('wc_triplea_crypto_payment_version'); 2632 $default_user_agent = 'WordPress/' . get_bloginfo('version') . '; ' . get_bloginfo('url'); 2633 $header_array[] = 'User-Agent: ' . $default_user_agent . '; wc_triplea_crypto_payment:' . $version; 2634 2635 foreach ($headers as $key => $value) { 2636 $header_array[] = "$key: $value"; 2637 if (strtolower($key) === 'content-type') { 2638 $has_content_type = true; 2639 } 2640 } 2641 2642 if (is_array($body)) { 2643 $body = http_build_query($body); 2644 if (!$has_content_type) { 2645 $header_array[] = 'Content-Type: application/x-www-form-urlencoded'; 2646 } 2647 } 2648 2649 curl_setopt_array($ch, [ 2650 CURLOPT_POST => true, 2651 CURLOPT_POSTFIELDS => $body, 2652 CURLOPT_HTTPHEADER => $header_array, 2653 CURLOPT_RETURNTRANSFER => true, 2654 CURLOPT_TIMEOUT => 30, 2655 CURLOPT_SSL_VERIFYPEER => true, 2656 CURLOPT_SSL_VERIFYHOST => 2, 2657 ]); 2658 2659 $result = curl_exec($ch); 2660 $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); 2661 $error = curl_error($ch); 2662 curl_close($ch); 2663 2664 return [ 2665 'body' => $result, 2666 'code' => $code, 2667 'error' => $error ?: null, 2668 ]; 2669 } 2670 2671 /** 2672 * Secure GET request bypassing WordPress HTTP filters 2673 * 2674 * @param string $url 2675 * @param array $headers 2676 * @return array 2677 */ 2678 private function secure_get($url, $headers = []) 2679 { 2680 // Validate API endpoint - only allow TripleA API calls 2681 if (strpos($url, 'https://api.triple-a.io/') !== 0) { 2682 if (isset($this->logger)) { 2683 $this->logger->write_log('secure_get(): Blocked invalid API endpoint: ' . $url, true); 2684 } 2685 return [ 2686 'body' => '', 2687 'code' => 0, 2688 'error' => 'Invalid API endpoint', 2689 ]; 2690 } 2691 2692 $ch = curl_init($url); 2693 2694 $header_array = []; 2695 // Add User-Agent header matching existing custom_user_agent() format 2696 $version = get_option('wc_triplea_crypto_payment_version'); 2697 $default_user_agent = 'WordPress/' . get_bloginfo('version') . '; ' . get_bloginfo('url'); 2698 $header_array[] = 'User-Agent: ' . $default_user_agent . '; wc_triplea_crypto_payment:' . $version; 2699 2700 foreach ($headers as $key => $value) { 2701 $header_array[] = "$key: $value"; 2702 } 2703 2704 curl_setopt_array($ch, [ 2705 CURLOPT_HTTPGET => true, 2706 CURLOPT_HTTPHEADER => $header_array, 2707 CURLOPT_RETURNTRANSFER => true, 2708 CURLOPT_TIMEOUT => 30, 2709 CURLOPT_SSL_VERIFYPEER => true, 2710 CURLOPT_SSL_VERIFYHOST => 2, 2711 ]); 2712 2713 $result = curl_exec($ch); 2714 $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); 2715 $error = curl_error($ch); 2716 curl_close($ch); 2717 2718 return [ 2719 'body' => $result, 2720 'code' => $code, 2721 'error' => $error ?: null, 2722 ]; 2723 } 2724 2575 2725 } -
triplea-cryptocurrency-payment-gateway-for-woocommerce/trunk/readme.txt
r3449218 r3462156 7 7 Requires at least: 5.5 8 8 Tested up to: 6.9 9 Stable tag: 2.0.2 69 Stable tag: 2.0.27 10 10 Requires PHP: 7.0 11 11 License: GPLv2 or later … … 104 104 == Changelog == 105 105 106 = 2.0.26 - 2026-01-26 = 106 = 2.0.27 = 107 108 * Improved error handling for API request failures 109 * Added URL allowlist validation for API endpoints 110 * User-Agent header added to all API requests 111 * Requires TRIPLEA_ENCRYPTION_KEY in wp-config.php (see installation instructions) 112 113 = 2.0.26 = 107 114 * Improved: Code quality and performance enhancements 108 115 * Fix: WordPress 6.9 compatibility … … 331 338 == Upgrade Notice == 332 339 340 = 2.0.27 = 341 CRITICAL SECURITY UPDATE - Immediate update recommended. Before updating, add TRIPLEA_ENCRYPTION_KEY to wp-config.php. Generate key with: openssl rand -base64 32. Then add: define('TRIPLEA_ENCRYPTION_KEY', 'your-generated-key'); Existing credentials will be automatically migrated to encrypted storage. See installation instructions for full details. 342 333 343 = 2.0.22 = 334 344 Simply install the update. No further action is needed. -
triplea-cryptocurrency-payment-gateway-for-woocommerce/trunk/triplea-cryptocurrency-payment-gateway-for-woocommerce.php
r3449218 r3462156 17 17 * Plugin URI: https://wordpress.org/plugins/triplea-cryptocurrency-payment-gateway-for-woocommerce/ 18 18 * Description: Offer cryptocurrency as a payment option on your website and get access to even more clients. Receive payments in cryptocurrency or in your local currency, directly in your bank account. Enjoy an easy setup, no cryptocurrency expertise required. Powered by Triple-A. 19 * Version: 2.0.2 619 * Version: 2.0.27 20 20 * Author: Triple-A Team 21 21 * Author URI: https://triple-a.io … … 49 49 * $var string 50 50 */ 51 public const version = '2.0.2 6';51 public const version = '2.0.27'; 52 52 53 53 /*
Note: See TracChangeset
for help on using the changeset viewer.