Changeset 3463303
- Timestamp:
- 02/17/2026 10:09:06 AM (6 weeks ago)
- Location:
- easy-payment-gateway-for-razorpay-and-for-woocommerce
- Files:
-
- 51 added
- 5 edited
-
tags/1.0.6 (added)
-
tags/1.0.6/LICENSE.txt (added)
-
tags/1.0.6/admin (added)
-
tags/1.0.6/admin/class-easy-payment-gateway-for-razorpay-and-for-woocommerce-admin.php (added)
-
tags/1.0.6/admin/css (added)
-
tags/1.0.6/admin/css/easy-payment-gateway-for-razorpay-and-for-woocommerce-admin.css (added)
-
tags/1.0.6/admin/feedback (added)
-
tags/1.0.6/admin/feedback/css (added)
-
tags/1.0.6/admin/feedback/css/deactivation-feedback-modal.css (added)
-
tags/1.0.6/admin/feedback/deactivation-feedback-form.php (added)
-
tags/1.0.6/admin/feedback/fonts (added)
-
tags/1.0.6/admin/feedback/fonts/icomoon.eot (added)
-
tags/1.0.6/admin/feedback/fonts/icomoon.svg (added)
-
tags/1.0.6/admin/feedback/fonts/icomoon.ttf (added)
-
tags/1.0.6/admin/feedback/fonts/icomoon.woff (added)
-
tags/1.0.6/admin/feedback/js (added)
-
tags/1.0.6/admin/feedback/js/deactivation-feedback-modal.js (added)
-
tags/1.0.6/admin/index.php (added)
-
tags/1.0.6/admin/js (added)
-
tags/1.0.6/admin/js/easy-payment-gateway-for-razorpay-and-for-woocommerce-admin.js (added)
-
tags/1.0.6/admin/js/pgrpw-review-ajax.js (added)
-
tags/1.0.6/checkout-block (added)
-
tags/1.0.6/checkout-block/easy_razorpay.js (added)
-
tags/1.0.6/checkout-block/razorpay-block.php (added)
-
tags/1.0.6/easy-payment-gateway-for-razorpay-and-for-woocommerce.php (added)
-
tags/1.0.6/images (added)
-
tags/1.0.6/images/easy-razorpay-popup.svg (added)
-
tags/1.0.6/images/razorpay.png (added)
-
tags/1.0.6/includes (added)
-
tags/1.0.6/includes/class-easy-payment-gateway-for-razorpay-and-for-woocommerce-activator.php (added)
-
tags/1.0.6/includes/class-easy-payment-gateway-for-razorpay-and-for-woocommerce-api.php (added)
-
tags/1.0.6/includes/class-easy-payment-gateway-for-razorpay-and-for-woocommerce-deactivator.php (added)
-
tags/1.0.6/includes/class-easy-payment-gateway-for-razorpay-and-for-woocommerce-function.php (added)
-
tags/1.0.6/includes/class-easy-payment-gateway-for-razorpay-and-for-woocommerce-gateway.php (added)
-
tags/1.0.6/includes/class-easy-payment-gateway-for-razorpay-and-for-woocommerce-loader.php (added)
-
tags/1.0.6/includes/class-easy-payment-gateway-for-razorpay-and-for-woocommerce-webhook.php (added)
-
tags/1.0.6/includes/class-easy-payment-gateway-for-razorpay-and-for-woocommerce.php (added)
-
tags/1.0.6/includes/index.php (added)
-
tags/1.0.6/index.php (added)
-
tags/1.0.6/languages (added)
-
tags/1.0.6/languages/easy-payment-gateway-for-razorpay-and-for-woocommerce.pot (added)
-
tags/1.0.6/public (added)
-
tags/1.0.6/public/class-easy-payment-gateway-for-razorpay-and-for-woocommerce-public.php (added)
-
tags/1.0.6/public/css (added)
-
tags/1.0.6/public/css/easy-payment-gateway-for-razorpay-and-for-woocommerce-public.css (added)
-
tags/1.0.6/public/index.php (added)
-
tags/1.0.6/public/js (added)
-
tags/1.0.6/public/js/easy-payment-gateway-for-razorpay-and-for-woocommerce-checkout.js (added)
-
tags/1.0.6/public/js/easy-payment-gateway-for-razorpay-and-for-woocommerce-public.js (added)
-
tags/1.0.6/readme.txt (added)
-
tags/1.0.6/uninstall.php (added)
-
trunk/easy-payment-gateway-for-razorpay-and-for-woocommerce.php (modified) (3 diffs)
-
trunk/includes/class-easy-payment-gateway-for-razorpay-and-for-woocommerce-api.php (modified) (3 diffs)
-
trunk/includes/class-easy-payment-gateway-for-razorpay-and-for-woocommerce-gateway.php (modified) (10 diffs)
-
trunk/public/js/easy-payment-gateway-for-razorpay-and-for-woocommerce-public.js (modified) (2 diffs)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
easy-payment-gateway-for-razorpay-and-for-woocommerce/trunk/easy-payment-gateway-for-razorpay-and-for-woocommerce.php
r3425197 r3463303 6 6 * Plugin URI: https://wordpress.org/plugins/easy-payment-gateway-for-razorpay-and-for-woocommerce/ 7 7 * Description: Accept payments through UPI, Cards, and Net Banking — developed by an official Razorpay Partner. 8 * Version: 1.0. 58 * Version: 1.0.6 9 9 * Author: Easy Payment 10 10 * Author URI: https://profiles.wordpress.org/easypayment// … … 16 16 * Requires PHP: 7.4 17 17 * Requires Plugins: woocommerce 18 * Tested up to: 6.9 18 * Tested up to: 6.9.1 19 19 * WC requires at least: 3.4 20 * WC tested up to: 10. 4.220 * WC tested up to: 10.5.2 21 21 */ 22 22 // If this file is called directly, abort. … … 29 29 } 30 30 if (!defined('EASY_RAZORPAY_FOR_WOOCOMMERCE_VERSION')) { 31 define('EASY_RAZORPAY_FOR_WOOCOMMERCE_VERSION', '1.0. 5');31 define('EASY_RAZORPAY_FOR_WOOCOMMERCE_VERSION', '1.0.6'); 32 32 } 33 33 if (!defined('EASY_RAZORPAY_FOR_WOOCOMMERCE_ASSET_URL')) { -
easy-payment-gateway-for-razorpay-and-for-woocommerce/trunk/includes/class-easy-payment-gateway-for-razorpay-and-for-woocommerce-api.php
r3325605 r3463303 8 8 private $logger; 9 9 private $is_sandbox; 10 11 public function __construct($api_key, $api_secret, $is_sandbox = false) { 10 private $invoice_prefix; 11 12 public function __construct($api_key, $api_secret, $invoice_prefix, $is_sandbox = false) { 12 13 $this->api_key = $api_key; 13 14 $this->api_secret = $api_secret; 14 15 $this->is_sandbox = $is_sandbox; 16 $this->invoice_prefix = $invoice_prefix; 15 17 $this->api_url = $this->is_sandbox ? 'https://api.razorpay.com/v1/' : 'https://api.razorpay.com/v1/'; 16 18 $this->logger = defined('WP_DEBUG') && WP_DEBUG ? wc_get_logger() : null; 19 add_filter('easy_razorpay_create_order_payload', array($this, 'easy_razorpay_create_order_payload'), 10, 2); 17 20 } 18 21 … … 91 94 } 92 95 93 public function create_order($amount, $currency = 'INR', $receipt = '', $payment_capture = 1) { 94 return $this->request('POST', 'orders', [ 95 'amount' => (int) $amount, 96 'currency' => $currency, 97 'receipt' => sanitize_text_field($receipt), 98 'payment_capture' => (int) $payment_capture 99 ]); 96 /** 97 * Create Razorpay customer and return cust_xxx 98 */ 99 public function create_rp_customer(WC_Order $order) { 100 101 $name = trim($order->get_billing_first_name() . ' ' . $order->get_billing_last_name()); 102 $email = $order->get_billing_email(); 103 $phone = $order->get_billing_phone(); 104 105 // Razorpay expects contact like 9123... or +91..., keep as provided by store 106 $payload = array( 107 'name' => $name ?: 'Customer', 108 'contact' => $phone ?: '', 109 'email' => $email ?: '', 110 'fail_existing' => '0', 111 'notes' => array( 112 'wc_order_id' => (string) $order->get_id(), 113 ), 114 ); 115 116 $resp = $this->request('POST', 'customers', $payload); 117 118 // If success 119 if (is_array($resp) && !empty($resp['id']) && strpos($resp['id'], 'cust_') === 0) { 120 return $resp['id']; 121 } 122 123 // If error, return empty (order can still be created without customer_id if needed) 124 return ''; 125 } 126 127 public function create_order($amount, $currency = 'INR', $receipt = '', $payment_capture = 1, $order = null) { 128 129 $data = [ 130 'amount' => (int) $amount, 131 'currency' => $currency, 132 'receipt' => sanitize_text_field($receipt), 133 'payment_capture' => (int) $payment_capture, 134 ]; 135 136 if ($order instanceof WC_Order) { 137 138 // 1) Create/reuse Razorpay customer_id (cust_xxx) 139 $rp_customer_id = $this->create_rp_customer($order); 140 if ($rp_customer_id) { 141 $data['customer_id'] = $rp_customer_id; 142 } 143 144 // 2) Pass customer_details + shipping_address (as per your required JSON) 145 $name = trim($order->get_billing_first_name() . ' ' . $order->get_billing_last_name()); 146 $email = $order->get_billing_email(); 147 $phone = $order->get_billing_phone(); 148 149 $country = $order->get_shipping_country() ?: $order->get_billing_country(); 150 151 $country = $order->get_shipping_country() ?: $order->get_billing_country(); 152 $state_code = $order->get_shipping_state() ?: $order->get_billing_state(); 153 154 // Convert state code to full state name 155 $state_name = $state_code; 156 if ($country && $state_code) { 157 $states = WC()->countries->get_states($country); 158 if (!empty($states[$state_code])) { 159 $state_name = $states[$state_code]; 160 } 161 } 162 163 164 $country = ($country === 'IN') ? 'IND' : $country; 165 166 $data['customer_details'] = [ 167 'name' => $name ?: 'Customer', 168 'email' => $email ?: '', 169 'contact' => $phone ?: '', 170 'shipping_address' => [ 171 'line1' => $order->get_shipping_address_1() ?: $order->get_billing_address_1(), 172 'line2' => $order->get_shipping_address_2() ?: $order->get_billing_address_2(), 173 'city' => $order->get_shipping_city() ?: $order->get_billing_city(), 174 'country' => $country ?: '', 175 'state' => $state_name ?: '', 176 'zipcode' => $order->get_shipping_postcode() ?: $order->get_billing_postcode(), 177 // latitude/longitude only if you have them stored somewhere 178 ], 179 ]; 180 } 181 182 if (empty($data['notes']) || !is_array($data['notes'])) { 183 $data['notes'] = array('wc_order_id' => $order->get_id()); 184 } 185 $data['notes'] = array('invoice_number' => $this->invoice_prefix . $order->get_id()); 186 187 // keep your extensibility 188 $data = apply_filters('easy_razorpay_create_order_payload', $data, $order, $this); 189 190 return $this->request('POST', 'orders', $data); 100 191 } 101 192 … … 129 220 return strtoupper($secret); 130 221 } 222 223 public function easy_razorpay_create_order_payload($data, $order) { 224 if ($order instanceof WC_Order) { 225 foreach ($order->get_items() as $item) { 226 $product = $item->get_product(); 227 if (!$product) { 228 continue; 229 } 230 $tags = wp_get_post_terms($product->get_id(), 'product_tag', ['fields' => 'names']); 231 foreach ($tags as $tag) { 232 if (strpos(strtolower($tag), 'hs_code:') === 0) { 233 $data['notes']['hs_code'] = preg_replace('/[^0-9]/', '', $tag); 234 break 2; 235 } 236 } 237 } 238 } 239 240 return $data; 241 } 131 242 } -
easy-payment-gateway-for-razorpay-and-for-woocommerce/trunk/includes/class-easy-payment-gateway-for-razorpay-and-for-woocommerce-gateway.php
r3425197 r3463303 13 13 public $hide_redirect_icon; 14 14 public $redirect_icon; 15 public $enabled_rp_methods; 16 public $invoice_prefix; 15 17 private static $receipt_hook_added = false; 16 18 private static $pgrpw_notice_rendered = false; … … 45 47 $this->enabled = $this->get_option('enabled', 'no'); 46 48 $this->hide_redirect_icon = 'yes' === $this->get_option('hide_redirect_icon', 'no'); 49 $this->enabled_rp_methods = (array) $this->get_option('enabled_rp_methods', array('card', 'netbanking', 'wallet', 'upi', 'emi', 'paylater')); 50 $this->invoice_prefix = (string) $this->get_option('invoice_prefix', 'INV_'); 51 $this->invoice_prefix = preg_replace('/[^A-Za-z0-9_\-]/', '', $this->invoice_prefix); 47 52 $this->order_button_text = __('Pay with Razorpay', 'easy-payment-gateway-for-razorpay-and-for-woocommerce'); 48 53 if (!class_exists('Easy_Razorpay_Payment_API')) { … … 55 60 add_action('woocommerce_api_' . strtolower('Easy_Razorpay_Payment_Webhook'), array($razorpay_webhook, 'handler')); 56 61 add_action('woocommerce_api_' . strtolower(get_class($this)), array($this, 'handle_callback')); 57 $this->razorpay = new Easy_Razorpay_Payment_API($this->api_key, $this->api_secret, $this->i s_sandbox);62 $this->razorpay = new Easy_Razorpay_Payment_API($this->api_key, $this->api_secret, $this->invoice_prefix, $this->is_sandbox); 58 63 add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']); 59 64 add_action('wp_enqueue_scripts', [$this, 'enqueue_order_pay_scripts']); … … 68 73 } 69 74 } 70 75 71 76 public function admin_options() { 72 77 $return_url = admin_url('admin.php?page=wc-settings&tab=checkout'); … … 102 107 WC()->api_request_url('Easy_Razorpay_Payment_Webhook') 103 108 ); 104 $this->razorpay = new Easy_Razorpay_Payment_API($this->api_key, $this->api_secret, $this->i s_sandbox);109 $this->razorpay = new Easy_Razorpay_Payment_API($this->api_key, $this->api_secret, $this->invoice_prefix, $this->is_sandbox); 105 110 $this->razorpay->create_webhook($webhook_url); 106 111 } … … 189 194 'type' => 'title', 190 195 'class' => 'easy-razorpay-collapsible-section' 196 ], 197 'enabled_rp_methods' => [ 198 'title' => __('Enabled Payment Options', 'easy-payment-gateway-for-razorpay-and-for-woocommerce'), 199 'type' => 'multiselect', 200 'class' => 'wc-enhanced-select', 201 'css' => 'width: 400px;', 202 'description' => __('Select which payment options should be shown in Razorpay Checkout.', 'easy-payment-gateway-for-razorpay-and-for-woocommerce'), 203 'default' => array('card', 'netbanking', 'wallet', 'upi', 'emi', 'paylater'), 204 'options' => array( 205 'card' => __('Card', 'easy-payment-gateway-for-razorpay-and-for-woocommerce'), 206 'netbanking' => __('Netbanking', 'easy-payment-gateway-for-razorpay-and-for-woocommerce'), 207 'wallet' => __('Wallet', 'easy-payment-gateway-for-razorpay-and-for-woocommerce'), 208 'upi' => __('UPI', 'easy-payment-gateway-for-razorpay-and-for-woocommerce'), 209 'emi' => __('EMI', 'easy-payment-gateway-for-razorpay-and-for-woocommerce'), 210 'paylater' => __('Pay Later', 'easy-payment-gateway-for-razorpay-and-for-woocommerce'), 211 ), 212 'desc_tip' => true, 213 ], 214 'invoice_prefix' => [ 215 'title' => __('Invoice prefix', 'easy-payment-gateway-for-razorpay-and-for-woocommerce'), 216 'type' => 'text', 217 'description' => __('Prefix used in Razorpay invoice number.', 'easy-payment-gateway-for-razorpay-and-for-woocommerce'), 218 'default' => 'INV_', 219 'desc_tip' => true, 191 220 ], 192 221 'hide_redirect_icon' => [ … … 321 350 } 322 351 } 323 352 324 353 public function handle_callback() { 325 354 /* phpcs:disable WordPress.Security.NonceVerification.Recommended */ … … 353 382 $amount = intval(round($order->get_total() * 100)); 354 383 $currency = esc_js($order->get_currency()); 355 $razorpay_order = $this->razorpay->create_order($amount, $currency, 'order-' . $order->get_id()); 356 if (isset($razorpay_order['error'])) { 357 return "console.error('Razorpay Order Error: " . esc_js($razorpay_order['error']['description']) . "');"; 358 } 359 $razorpay_order_id = esc_js($razorpay_order['id']); 360 update_post_meta($order_id, '_razorpay_order_id', $razorpay_order_id); 384 385 $existing_rp_order_id = get_post_meta($order_id, '_razorpay_order_id', true); 386 387 if (!empty($existing_rp_order_id)) { 388 $razorpay_order_id = esc_js($existing_rp_order_id); 389 } else { 390 $razorpay_order = $this->razorpay->create_order($amount, $currency, 'order-' . $order->get_id(), 1, $order); 391 if (isset($razorpay_order['error'])) { 392 return "console.error('Razorpay Order Error: " . esc_js($razorpay_order['error']['description']) . "');"; 393 } 394 $razorpay_order_id = esc_js($razorpay_order['id']); 395 update_post_meta($order_id, '_razorpay_order_id', $razorpay_order_id); 396 } 361 397 $redirect_url = add_query_arg( 362 array( 363 'easy_razorpay_action' => 'process_payment', 364 'order_id' => $order_id, 365 ), 366 WC()->api_request_url('Easy_WC_Gateway_Razorpay') 367 ); 368 369 wp_enqueue_script('easy-razorpay-checkout', EASY_RAZORPAY_FOR_WOOCOMMERCE_ASSET_URL . 'public/js/easy-payment-gateway-for-razorpay-and-for-woocommerce-public.js', array('jquery'), EASY_RAZORPAY_FOR_WOOCOMMERCE_VERSION, false); 398 array( 399 'easy_razorpay_action' => 'process_payment', 400 'order_id' => $order_id, 401 ), 402 WC()->api_request_url('Easy_WC_Gateway_Razorpay') 403 ); 404 405 wp_enqueue_script( 406 'easy-razorpay-checkout', 407 EASY_RAZORPAY_FOR_WOOCOMMERCE_ASSET_URL . 'public/js/easy-payment-gateway-for-razorpay-and-for-woocommerce-public.js', 408 array('jquery'), 409 EASY_RAZORPAY_FOR_WOOCOMMERCE_VERSION, 410 false 411 ); 412 413 $product_category = ''; 414 415 foreach ($order->get_items() as $item) { 416 417 $product = $item->get_product(); 418 if (!$product) { 419 continue; 420 } 421 422 $terms = get_the_terms($product->get_id(), 'product_cat'); 423 424 if (!empty($terms) && !is_wp_error($terms)) { 425 $product_category = $terms[0]->name; // First category 426 break; 427 } 428 } 429 430 $razorpay_customer_id = $this->razorpay->create_rp_customer($order); 431 432 $selected_methods = is_array($this->enabled_rp_methods) ? $this->enabled_rp_methods : array(); 433 434 $method = array( 435 'card' => in_array('card', $selected_methods, true), 436 'netbanking' => in_array('netbanking', $selected_methods, true), 437 'wallet' => in_array('wallet', $selected_methods, true), 438 'upi' => in_array('upi', $selected_methods, true), 439 'emi' => in_array('emi', $selected_methods, true), 440 'paylater' => in_array('paylater', $selected_methods, true), 441 ); 442 370 443 wp_localize_script( 371 444 'easy-razorpay-checkout', … … 373 446 array( 374 447 'key' => $this->api_key, 375 'amount' => $amount, // in paise448 'amount' => $amount, 376 449 'currency' => $currency, 377 450 'site_name' => get_bloginfo('name'), 378 451 'order_id' => $razorpay_order_id, 379 'redirect_url' => $redirect_url, 380 'currency_code' => get_woocommerce_currency() 452 'callback_url' => $redirect_url, 453 'customer_id' => $razorpay_customer_id, 454 'description' => 'Order #' . $order->get_id(), 455 'image' => get_site_icon_url(), 456 'prefill' => array( 457 'name' => trim($order->get_billing_first_name() . ' ' . $order->get_billing_last_name()), 458 'email' => $order->get_billing_email(), 459 'contact' => $order->get_billing_phone(), 460 ), 461 'notes' => array( 462 'invoice_number' => $this->invoice_prefix . $order->get_id(), 463 'goods_description' => trim(mb_substr($product_category, 0, 235)), 464 ), 465 'method' => $method, 381 466 ) 382 467 ); … … 412 497 private function log_debug($message) { 413 498 if ('yes' === $this->get_option('debug', 'no')) { 414 wc_get_logger()->debug('[Easy Razorpay] ' . $message, ['source' => ' easy-razorpay']);499 wc_get_logger()->debug('[Easy Razorpay] ' . $message, ['source' => 'razorpay']); 415 500 } 416 501 } -
easy-payment-gateway-for-razorpay-and-for-woocommerce/trunk/public/js/easy-payment-gateway-for-razorpay-and-for-woocommerce-public.js
r3367179 r3463303 5 5 console.warn("Razorpay checkout data is not defined."); 6 6 return; 7 } 7 } 8 8 const options = { 9 key: razorpay_checkout_data.key, 10 amount: razorpay_checkout_data.amount, 11 currency: razorpay_checkout_data.currency, 12 name: razorpay_checkout_data.site_name, 13 order_id: razorpay_checkout_data.order_id, 14 theme: { 15 color: '#3399cc' 9 "key": razorpay_checkout_data.key, 10 "amount": razorpay_checkout_data.amount, 11 "currency": razorpay_checkout_data.currency, 12 "name": razorpay_checkout_data.site_name, 13 "description": razorpay_checkout_data.description || "", 14 "image": razorpay_checkout_data.image || "", 15 "customer_id": razorpay_checkout_data.customer_id || "", 16 "order_id": razorpay_checkout_data.order_id, 17 "prefill": { 18 "name": (razorpay_checkout_data.prefill && razorpay_checkout_data.prefill.name) ? razorpay_checkout_data.prefill.name : "", 19 "email": (razorpay_checkout_data.prefill && razorpay_checkout_data.prefill.email) ? razorpay_checkout_data.prefill.email : "", 20 "contact": (razorpay_checkout_data.prefill && razorpay_checkout_data.prefill.contact) ? razorpay_checkout_data.prefill.contact : "" 21 }, 22 23 "notes": { 24 "invoice_number": (razorpay_checkout_data.notes && razorpay_checkout_data.notes.invoice_number) ? razorpay_checkout_data.notes.invoice_number : "", 25 "goods_description": (razorpay_checkout_data.notes && razorpay_checkout_data.notes.goods_description) ? razorpay_checkout_data.notes.goods_description : "" 26 }, 27 28 "theme": { 29 "color": "#0C61F7" 16 30 }, 17 31 handler: function (response) { 18 32 try { 33 console.log(response); 19 34 if (!response || !response.razorpay_payment_id) { 20 35 throw new Error("Invalid Razorpay response."); 21 36 } 22 window.location.href = 23 razorpay_checkout_data.redirect_url + 24 '&razorpay_payment_id=' + 25 encodeURIComponent(response.razorpay_payment_id); 37 window.location.href = razorpay_checkout_data.callback_url + '&razorpay_payment_id=' + encodeURIComponent(response.razorpay_payment_id); 26 38 } catch (handlerError) { 27 39 console.error("Error in Razorpay handler:", handlerError); … … 29 41 } 30 42 }; 43 if (razorpay_checkout_data.method) { 44 options.method = razorpay_checkout_data.method; 45 } 31 46 if (typeof Razorpay === 'undefined') { 32 47 throw new Error("Razorpay SDK is not loaded."); -
easy-payment-gateway-for-razorpay-and-for-woocommerce/trunk/readme.txt
r3425197 r3463303 3 3 Tags: Razorpay, UPI, Credit Cards 4 4 Requires at least: 6.0 5 Tested up to: 6.9 5 Tested up to: 6.9.1 6 6 Requires PHP: 7.4 7 Stable tag: 1.0. 57 Stable tag: 1.0.6 8 8 License: GPL-2.0+ 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.txt … … 93 93 == Changelog == 94 94 95 = 1.0.6 = 96 * Added - Support for Goods Flow under Payment Aggregator → Cross Border (PACB). 97 95 98 = 1.0.5 = 96 99 * Enhanced - Improved gateway settings panel text.
Note: See TracChangeset
for help on using the changeset viewer.