Changeset 3652810
- Timestamp:
- 08/18/2026 12:10:19 PM (2 months ago)
- Location:
- cashflows-payments-by-ideal-checkout
- Files:
-
- 25 added
- 1 deleted
- 5 edited
-
tags/2.3.8 (added)
-
tags/2.3.8/blocks (added)
-
tags/2.3.8/blocks/cards.php (added)
-
tags/2.3.8/blocks/paypal.php (added)
-
tags/2.3.8/build (added)
-
tags/2.3.8/build/blocks.asset.php (added)
-
tags/2.3.8/build/blocks.js (added)
-
tags/2.3.8/gateways (added)
-
tags/2.3.8/gateways/abstract.php (added)
-
tags/2.3.8/gateways/cards.php (added)
-
tags/2.3.8/gateways/cashflows.cls.php (added)
-
tags/2.3.8/gateways/paypal.php (added)
-
tags/2.3.8/ic-cashflows-for-woo.php (added)
-
tags/2.3.8/includes (added)
-
tags/2.3.8/includes/functions.php (added)
-
tags/2.3.8/index.php (added)
-
tags/2.3.8/languages (added)
-
tags/2.3.8/languages/ic-cashflows-for-woo-nl_NL.mo (added)
-
tags/2.3.8/languages/ic-cashflows-for-woo-nl_NL.po (added)
-
tags/2.3.8/readme.txt (added)
-
tags/2.3.8/temp (added)
-
tags/2.3.8/temp/cache (added)
-
tags/2.3.8/temp/cache/index.php (added)
-
tags/2.3.8/temp/logs (added)
-
tags/2.3.8/temp/logs/index.php (added)
-
trunk/controllers (deleted)
-
trunk/gateways/abstract.php (modified) (7 diffs)
-
trunk/gateways/cashflows.cls.php (modified) (1 diff)
-
trunk/ic-cashflows-for-woo.php (modified) (6 diffs)
-
trunk/includes/functions.php (modified) (1 diff)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
cashflows-payments-by-ideal-checkout/trunk/gateways/abstract.php
r3608738 r3652810 5 5 6 6 use Automattic\WooCommerce\StoreApi\Exceptions\RouteException; 7 use Automattic\WooCommerce\Enums\PaymentGatewayFeature; 8 use Automattic\WooCommerce\Enums\OrderStatus; 7 9 8 10 class iccf_abstract extends WC_Payment_Gateway 9 11 { 10 12 private $additionalData = []; 13 private static $callbackRegistered = false; 14 15 public static function initCallbacks() 16 { 17 if (self::$callbackRegistered) { 18 return; 19 } 20 21 add_action('woocommerce_api_iccf_gateway_return', [__CLASS__, 'process_return']); 22 add_action('woocommerce_api_iccf_gateway_return_failure', [__CLASS__, 'process_return_failure']); 23 add_action('woocommerce_api_iccf_gateway_notify', [__CLASS__, 'process_notify']); 24 25 self::$callbackRegistered = true; 26 } 27 28 private static function acquireOrderLock($orderId) 29 { 30 $lockKey = 'iccf_order_lock_' . absint($orderId); 31 32 if (false !== get_transient($lockKey)) { 33 return false; 34 } 35 36 return set_transient($lockKey, wp_generate_uuid4(), 30); 37 } 38 39 private static function releaseOrderLock($orderId) 40 { 41 $lockKey = 'iccf_order_lock_' . absint($orderId); 42 delete_transient($lockKey); 43 } 44 45 private static function redirectAndExit($url) 46 { 47 wp_safe_redirect($url); 48 exit; 49 } 11 50 12 51 public function __construct() … … 18 57 $this->method_description = sprintf(__('Enable this method to receive transactions with Cashflows', 'ic-cashflows-for-woo').' - '.$this->getPaymentName()); 19 58 20 $this->supports = ['products', 'refunds']; 59 $this->supports = [ 60 PaymentGatewayFeature::PRODUCTS, 61 PaymentGatewayFeature::REFUNDS, 62 ]; 21 63 22 64 $this->init_form_fields(); … … 27 69 28 70 add_action('woocommerce_update_options_payment_gateways_'.$this->id, [$this, 'process_admin_options']); 71 72 self::initCallbacks(); 29 73 } 30 74 … … 179 223 $paymentCode = $this->getPaymentCode(); 180 224 181 $paymentMethod = strtolower(s trtolower(substr($paymentCode, 10)));225 $paymentMethod = strtolower(substr($paymentCode, 10)); 182 226 183 227 // Change cardsinline to card … … 282 326 } 283 327 328 /** 329 * Process payment implementation for Cashflows. This method is called when the user clicks the "Place Order" button on the checkout page. 330 * @param mixed $orderId 331 * @throws RouteException 332 * @return array{redirect: mixed, result: string} 333 */ 284 334 public function process_payment($orderId) 285 335 { 286 global $woocommerce;287 336 global $wp_version; 288 337 … … 544 593 } 545 594 595 /** 596 * Refund implementation for CashFlows 597 * @param mixed $refundId 598 * @param mixed $refundAmount 599 * @param mixed $refundReason 600 * @return WP_Error|WP_REST_Response 601 */ 546 602 public function process_refund($refundId, $refundAmount = null, $refundReason = '') 547 603 { … … 645 701 } 646 702 } 703 704 705 /** 706 * Return URL of the Cashflows implementation 707 */ 708 public static function process_return() 709 { 710 $debugEnabled = iccf_isDebugEnabled(); 711 712 if (empty($_GET['real_id']) || empty($_GET['paymentjobref']) || empty($_GET['paymentref']) || empty($_GET['ordernumber'])) { 713 if ($debugEnabled) { 714 iccf_log('Customer return called with empty data, redirecting to cart'); 715 } 716 717 wp_redirect(wc_get_cart_url()); 718 } 719 720 $orderId = sanitize_text_field($_GET['real_id']); 721 $utmOverride = array_key_exists('utm_nooverride', $_GET); 722 $paymentJobReference = sanitize_text_field($_GET['paymentjobref']); 723 724 if ($debugEnabled) { 725 iccf_log('Customer returned with orderID: '.$orderId.' and Payment Job Reference: '.$paymentJobReference); 726 } 727 728 $order = wc_get_order($orderId); 729 730 if (!$order || ($order->get_meta('cf_transaction_id') !== $paymentJobReference)) { 731 if ($debugEnabled) { 732 iccf_log('CashFlows return for Order ID: '.$orderId.' but no order found or transaction ID does not match Payment Job Reference. Redirecting to cart'); 733 } 734 735 wp_redirect(wc_get_cart_url().($utmOverride ? '?utm_nooverride=1' : '')); 736 } 737 738 $orderStatus = $order->get_status(); 739 740 if (in_array($orderStatus, wc_get_is_paid_statuses(), true)) { 741 if ($debugEnabled) { 742 iccf_log('Customer return for Order ID: '.$orderId.' but order is already completed, redirecting to order received page'); 743 } 744 745 $orderReceivedUrl = $order->get_checkout_order_received_url(); 746 747 self::redirectAndExit($orderReceivedUrl . ($utmOverride ? (str_contains($orderReceivedUrl, '?') ? '&' : '?') . 'utm_nooverride=1' : '')); 748 } 749 750 $lockToken = self::acquireOrderLock($orderId); 751 752 if (!$lockToken) { 753 if ($debugEnabled) { 754 iccf_log('Customer return for Order ID: '.$orderId.' could not acquire order lock; redirecting to order received page'); 755 } 756 757 self::redirectAndExit($order->get_checkout_order_received_url().($utmOverride ? '?utm_nooverride=1' : '')); 758 } 759 760 if ($debugEnabled) { 761 iccf_log('Customer return acquired lock for Order ID: '.$orderId.' and is processing payment status'); 762 } 763 764 try { 765 $cashflowsPayment = new CashflowsPayment(iccf_getApiKey(), iccf_getConfigurationId()); 766 $cashflowsPayment->setTestmode(iccf_getIntegrationMode()); 767 768 $transactionStatus = $cashflowsPayment->getStatus($paymentJobReference); 769 $paymentMethod = $cashflowsPayment->getUsedPaymentMethod(); 770 771 if ($debugEnabled) { 772 iccf_log('Transaction status: '.$transactionStatus.' and Payment method: '.$paymentMethod); 773 } 774 775 if (strcasecmp($transactionStatus, 'SUCCESS') === 0) { 776 $order->add_order_note(__('Status received from CashFlows Pull (status changed)', 'ic-cashflows-for-woo').': '.$transactionStatus.' '.__('with Paymentjob', 'ic-cashflows-for-woo').':<br>'.$paymentJobReference.'<br>'.__('Payment-method', 'ic-cashflows-for-woo').': <b>'.$paymentMethod.'</b>'); 777 778 $order->payment_complete($paymentJobReference); 779 780 if ($debugEnabled) { 781 iccf_log('Customer return completed order '.$orderId.' with payment job '.$paymentJobReference.' and redirected to order received page'); 782 } 783 784 self::redirectAndExit($order->get_checkout_order_received_url().($utmOverride ? '?utm_nooverride=1' : '')); 785 } 786 787 $order->add_order_note(__('Status received from CashFlows Pull', 'ic-cashflows-for-woo').': '.$transactionStatus.' '.__('with Paymentjob', 'ic-cashflows-for-woo').':<br>'.$paymentJobReference.'<br>'.__('Payment-method', 'ic-cashflows-for-woo').': <b>'.$paymentMethod.'</b>'); 788 789 $holdStock = get_option('woocommerce_hold_stock_minutes'); 790 791 if (!empty($holdStock) && ($holdStock > 0)) { 792 $message = __('<br>If the payment is cancelled or expired, it will be cancelled automatically by WooCommerce .', 'ic-cashflows-for-woo'); 793 $order->add_order_note($message); 794 } else { 795 if (strcmp($transactionStatus, 'FAILURE') === 0) { 796 $message = __('<br>Update order status: Failed.', 'ic-cashflows-for-woo'); 797 $order->add_order_note($message); 798 $order->update_status('failed'); 799 } elseif (strcmp($transactionStatus, 'CANCELLED') === 0) { 800 $message = __('<br>Update order status: Cancelled', 'ic-cashflows-for-woo'); 801 $order->add_order_note($message); 802 $order->update_status('cancelled'); 803 } else { 804 $message = __('<br>Status: Unknown', 'ic-cashflows-for-woo'); 805 $order->add_order_note($message); 806 } 807 } 808 809 self::redirectAndExit(wc_get_cart_url().($utmOverride ? '?utm_nooverride=1' : '')); 810 } finally { 811 self::releaseOrderLock($orderId); 812 } 813 } 814 815 public static function process_return_failure() 816 { 817 $debugEnabled = iccf_isDebugEnabled(); 818 819 if (empty($_GET['real_id']) || empty($_GET['paymentjobref'])) { 820 if ($debugEnabled) { 821 iccf_log('Customer return failure called with empty data, redirecting to cart'); 822 } 823 824 self::redirectAndExit(wc_get_cart_url()); 825 } else { 826 $orderId = sanitize_text_field($_GET['real_id']); 827 $utmOverride = array_key_exists('utm_nooverride', $_GET); 828 829 if ($debugEnabled) { 830 iccf_log('Customer return failure called with data: '.$orderId); 831 } 832 833 $order = wc_get_order($orderId); 834 835 if ($order) { 836 if (array_key_exists('status', $_GET)) { 837 $order->add_order_note(__('Customer Return: <b>Cancelled</b>', 'ic-cashflows-for-woo')); 838 } else { 839 $order->add_order_note(__('Customer Return: <b>Failure</b>', 'ic-cashflows-for-woo')); 840 } 841 } 842 843 self::redirectAndExit(wc_get_cart_url().($utmOverride ? '?utm_nooverride=1' : '')); 844 } 845 846 return false; 847 } 848 849 public static function process_notify() 850 { 851 $debugEnabled = iccf_isDebugEnabled(); 852 853 $jsonData = @file_get_contents('php://input'); 854 $orderId = sanitize_text_field($_GET['real_id']); 855 856 if ($debugEnabled) { 857 iccf_log('CashFlows Notify called with data: '.$jsonData.' for Order ID: '.$orderId); 858 } 859 860 if (empty($jsonData) || empty($orderId)) { 861 if ($debugEnabled) { 862 iccf_log('CashFlows Notify called with empty data or Order ID, returning 406 Not Acceptable'); 863 } 864 865 http_response_code(406); 866 header('HTTP/1.1 406 Not Acceptable'); 867 exit('Not Acceptable'); 868 } 869 870 $postData = json_decode($jsonData, true); 871 872 if (isset($postData['paymentJobReference'])) { 873 $paymentJobReference = sanitize_text_field($postData['paymentJobReference']); 874 $jsonResponse = json_encode([ 875 'paymentJobReference' => sanitize_text_field($postData['paymentJobReference']), 876 'paymentReference' => sanitize_text_field($postData['paymentReference']), 877 ]); 878 } elseif (isset($postData['PaymentJobReference'])) { 879 $paymentJobReference = sanitize_text_field($postData['PaymentJobReference']); 880 $jsonResponse = json_encode([ 881 'PaymentJobReference' => sanitize_text_field($postData['PaymentJobReference']), 882 'PaymentReference' => sanitize_text_field($postData['PaymentReference']), 883 ]); 884 } else { 885 $paymentJobReference = ''; 886 $jsonResponse = json_encode([]); 887 } 888 889 $cashflowsPayment = new CashflowsPayment(iccf_getApiKey(), iccf_getConfigurationId()); 890 $cashflowsPayment->setTestmode(iccf_getIntegrationMode()); 891 892 $order = wc_get_order($orderId); 893 894 if (!$order || ($order->get_meta('cf_transaction_id') !== $paymentJobReference)) { 895 if ($debugEnabled) { 896 iccf_log('CashFlows Notify called with Order ID: '.$orderId.' but no order found or transaction ID does not match Payment Job Reference. Returning 406 Not Acceptable'); 897 } 898 899 http_response_code(406); 900 header('HTTP/1.1 406 Not Acceptable'); 901 exit('Not Acceptable'); 902 } 903 904 $orderStatus = $order->get_status(); 905 906 if (in_array($orderStatus, wc_get_is_paid_statuses(), true)) { 907 if ($debugEnabled) { 908 iccf_log('CashFlows Notify ignored for Order ID: '.$orderId.' because the order is already paid.'); 909 } 910 911 http_response_code(200); 912 header('HTTP/1.1 200 OK'); 913 exit($jsonResponse); 914 } 915 916 $lockToken = self::acquireOrderLock($orderId); 917 918 if (!$lockToken) { 919 if ($debugEnabled) { 920 iccf_log('CashFlows Notify skipped for Order ID: '.$orderId.' because the order is already being processed by return flow.'); 921 } 922 923 http_response_code(200); 924 header('HTTP/1.1 200 OK'); 925 exit($jsonResponse); 926 } 927 928 if ($debugEnabled) { 929 iccf_log('CashFlows Notify acquired lock for Order ID: '.$orderId.' and is processing payment status'); 930 } 931 932 try { 933 $transactionStatus = $cashflowsPayment->getStatus($paymentJobReference); 934 935 if (empty($transactionStatus)) { 936 $order->add_order_note(__('Unable to fetch status from CashFlows Notify with Paymentjob', 'ic-cashflows-for-woo')); 937 938 if ($debugEnabled) { 939 iccf_log('CashFlows Notify called with Payment Job Reference: '.$paymentJobReference.' but no status found. Returning 406 Not Acceptable'); 940 } 941 942 http_response_code(406); 943 exit('Not Acceptable'); 944 } 945 946 if ($debugEnabled) { 947 iccf_log('CashFlows Notify called with Payment Job Reference: '.$paymentJobReference.' and status: '.$transactionStatus.' for Order ID: '.$orderId); 948 } 949 950 $paymentMethod = $cashflowsPayment->getUsedPaymentMethod(); 951 952 if (in_array($orderStatus, ['pending', 'failed', 'cancelled', 'on-hold'], true)) { 953 if (strcasecmp($transactionStatus, 'SUCCESS') === 0) { 954 $order->add_order_note(__('Status received from CashFlows Notify (status changed)', 'ic-cashflows-for-woo').': '.$transactionStatus.' '.__('with Paymentjob', 'ic-cashflows-for-woo').':<br>'.$paymentJobReference.'<br>'.__('Payment-method', 'ic-cashflows-for-woo').': <b>'.$paymentMethod.'</b>'); 955 $order->payment_complete($paymentJobReference); 956 957 if ($debugEnabled) { 958 iccf_log('CashFlows Notify completed order '.$orderId.' with payment job '.$paymentJobReference.' via notify callback'); 959 } 960 } else { 961 $order->add_order_note(__('Status received from CashFlows Notify', 'ic-cashflows-for-woo').': '.$transactionStatus.' '.__('with Paymentjob', 'ic-cashflows-for-woo').':<br>'.$paymentJobReference.'<br>'.__('Payment-method', 'ic-cashflows-for-woo').': <b>'.$paymentMethod.'</b>'); 962 963 $holdStock = get_option('woocommerce_hold_stock_minutes'); 964 965 if (!empty($holdStock) && ($holdStock > 0)) { 966 $message = __('<br>If the payment is cancelled or expired, it will be cancelled automatically by WooCommerce .', 'ic-cashflows-for-woo'); 967 $order->add_order_note($message); 968 } else { 969 if (strcmp($transactionStatus, 'FAILURE') === 0) { 970 $message = __('<br>Update order status: Failed.', 'ic-cashflows-for-woo'); 971 $order->add_order_note($message); 972 $order->update_status('failed'); 973 } elseif (strcmp($transactionStatus, 'CANCELLED') === 0) { 974 $message = __('<br>Update order status: Cancelled', 'ic-cashflows-for-woo'); 975 $order->add_order_note($message); 976 $order->update_status('cancelled'); 977 } else { 978 $message = __('<br>Status: Unknown', 'ic-cashflows-for-woo'); 979 $order->add_order_note($message); 980 } 981 } 982 } 983 } else { 984 $order->add_order_note(__('Status received from CashFlows Notify (no status change)', 'ic-cashflows-for-woo').': '.$transactionStatus.' '.__('with Paymentjob', 'ic-cashflows-for-woo').':<br>'.$paymentJobReference.'<br>'.__('Payment-method', 'ic-cashflows-for-woo').': <b>'.$paymentMethod.'</b>'); 985 } 986 } finally { 987 self::releaseOrderLock($orderId); 988 } 989 990 if ($debugEnabled) { 991 iccf_log('CashFlows Notify processed, preparing JSON response for Order ID: '.$orderId.' statuscode 200 OK'); 992 } 993 994 http_response_code(200); 995 header('HTTP/1.1 200 OK'); 996 997 exit($jsonResponse); 998 } 647 999 } -
cashflows-payments-by-ideal-checkout/trunk/gateways/cashflows.cls.php
r3366335 r3652810 39 39 40 40 private $aTransaction = []; 41 private $aTransactionResults = false;42 41 private $aPaymentJob = []; 43 private $aErrors = [];44 45 // Payment intent46 private $intentTotal;47 private $intentCurrency;48 private $intentMethod;49 private $intentBillingData;50 private $intentBillingIdentity;51 52 private $intentPaymentJob;53 private $intentToken;54 42 private $requestOrigin; 55 43 -
cashflows-payments-by-ideal-checkout/trunk/ic-cashflows-for-woo.php
r3608738 r3652810 11 11 * Plugin URI: https://payocity.nl/en/payment-service-provider/cashflows 12 12 * Description: Cashflows Payment Gateway accepts card payments for eCommerce transactions 13 * Version: 2.3. 713 * Version: 2.3.8 14 14 * Requires at least: 5.8 15 15 * Tested up to: 7.0.1 … … 36 36 37 37 // Define the plugin version 38 define('ICCF_VERSION', '2.3. 7');38 define('ICCF_VERSION', '2.3.8'); 39 39 40 40 // Load default plugin functions … … 56 56 } 57 57 add_action('admin_notices', 'iccf_doShowCurlError'); 58 }59 60 // Is WooCommerce active on this Wordpress installation?61 if (is_plugin_active('woocommerce/woocommerce.php') || is_plugin_active_for_network('woocommerce/woocommerce.php')) {62 include ICCF_ROOT_PATH . DIRECTORY_SEPARATOR . 'controllers' . DIRECTORY_SEPARATOR . 'woocommerce-cashflows.php';63 IdealcheckoutCashflowsForWooCommerce::init();64 } else {65 // Woocommerce isn't active, show error66 function iccf_doShowWoocommerceError()67 {68 echo '<div class="error"><p>Cashflows for WooCommerce plugin requires WooCommerce to be active</p></div>';69 }70 add_action('admin_notices', 'iccf_doShowWoocommerceError');71 58 } 72 59 … … 330 317 iccf_removeLogFiles(); // Clean up old log files 331 318 319 $clearLogUrl = wp_nonce_url( 320 add_query_arg([ 321 'page' => 'wc-settings', 322 'tab' => 'cashflows_settings_tab', 323 'iccf_clear_log' => '1', 324 ], admin_url('admin.php')), 325 'iccf_clear_log' 326 ); 327 332 328 // Output the field 333 329 $html .= ' … … 345 341 <p><code>' . esc_html($logFile) . '</code></p> 346 342 <p>' . __('The log file is shown below. The log file is rotated when it exceeds 5MB in size. Old log files are automatically removed after the selected number of days.', 'ic-cashflows-for-woo') . '</p> 343 <p><a href="' . esc_url($clearLogUrl) . '" class="button button-secondary">' . esc_html__('Clear log', 'ic-cashflows-for-woo') . '</a></p> 347 344 <pre style="background: #f9f9f9; border: 1px solid #ddd; padding: 10px; max-height: 400px; overflow: auto;">' . $logFileContents . '</pre>'; 348 345 } else { 349 346 $html .= '<p>' . __('No log file found.', 'ic-cashflows-for-woo') . '</p>'; 347 $html .= '<p><a href="' . esc_url($clearLogUrl) . '" class="button button-secondary">' . esc_html__('Clear log', 'ic-cashflows-for-woo') . '</a></p>'; 350 348 } 351 349 … … 358 356 359 357 add_action('woocommerce_admin_field_cashflows_logs_renderer', 'cashflows_render_logs_field'); 358 359 add_action('admin_init', 'iccf_handleClearLogRequest'); 360 361 function iccf_handleClearLogRequest() 362 { 363 if (!isset($_GET['iccf_clear_log']) || sanitize_text_field(wp_unslash($_GET['iccf_clear_log'])) !== '1') { 364 return; 365 } 366 367 if (!isset($_GET['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'])), 'iccf_clear_log')) { 368 wp_die(esc_html__('Invalid request.', 'ic-cashflows-for-woo')); 369 } 370 371 if (!current_user_can('manage_woocommerce')) { 372 wp_die(esc_html__('You do not have permission to clear the log.', 'ic-cashflows-for-woo')); 373 } 374 375 iccf_clearLogFiles(); 376 377 wp_safe_redirect( 378 add_query_arg([ 379 'page' => 'wc-settings', 380 'tab' => 'cashflows_settings_tab', 381 'iccf_log_cleared' => '1', 382 ], admin_url('admin.php')) 383 ); 384 exit; 385 } 386 387 add_action('admin_notices', 'iccf_showLogClearedNotice'); 388 389 function iccf_showLogClearedNotice() 390 { 391 if (isset($_GET['iccf_log_cleared']) && sanitize_text_field(wp_unslash($_GET['iccf_log_cleared'])) === '1') { 392 echo '<div class="updated notice notice-success"><p>' . esc_html__('Cashflows log cleared.', 'ic-cashflows-for-woo') . '</p></div>'; 393 } 394 } -
cashflows-payments-by-ideal-checkout/trunk/includes/functions.php
r3608738 r3652810 135 135 fclose($stream); 136 136 } 137 } 138 139 /** 140 * Clear all Cashflows debug log files. 141 * 142 * @return bool True when the log files were cleared successfully. 143 */ 144 function iccf_clearLogFiles() 145 { 146 $logDir = ICCF_ROOT_PATH . 'temp' . DIRECTORY_SEPARATOR . 'logs'; 147 $logFile = $logDir . DIRECTORY_SEPARATOR . 'cashflows_debug.log'; 148 149 if (!is_dir($logDir)) { 150 wp_mkdir_p($logDir); 151 } 152 153 $logFiles = glob($logDir . DIRECTORY_SEPARATOR . 'cashflows_debug*.log'); 154 155 if (!empty($logFiles) && is_array($logFiles)) { 156 foreach ($logFiles as $file) { 157 @unlink($file); 158 } 159 } 160 161 if (!file_exists($logFile)) { 162 $handle = @fopen($logFile, 'w'); 163 if ($handle) { 164 @fclose($handle); 165 @chmod($logFile, 0600); 166 } 167 } 168 169 return true; 137 170 } 138 171 -
cashflows-payments-by-ideal-checkout/trunk/readme.txt
r3608738 r3652810 4 4 Requires Plugins: woocommerce 5 5 WC requires at least: 9.6 6 WC tested up to: 1 0.9.46 WC tested up to: 11.0.1 7 7 Requires at least: 5.8.0 8 Tested up to: 7. 0.19 Stable tag: 2.3. 78 Tested up to: 7.1 9 Stable tag: 2.3.8 10 10 Requires PHP: 7.4 11 11 License: GPLv2 or later … … 85 85 86 86 == Changelog == 87 88 = 2.3.8 = 89 * Added a clear log button, to clear our logfile. 90 * Moved the return and notify to the abstract controller and included locking. 91 * Checked compatibility with Wordpress 7.1 and WooCommerce 11.0.1 87 92 88 93 = 2.3.7 =
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)