blob: 6db9bf5adde15452af58f456e98c72e909ed8b0c [file] [log] [blame]
swissChilif0cbdc32023-01-05 17:21:38 -05001<?php
2if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4}
5
6/**
7 * Class that represents admin notices.
8 *
9 * @since 4.1.0
10 */
11class WC_Stripe_Admin_Notices {
12 /**
13 * Notices (array)
14 *
15 * @var array
16 */
17 public $notices = [];
18
19 /**
20 * Constructor
21 *
22 * @since 4.1.0
23 */
24 public function __construct() {
25 add_action( 'admin_notices', [ $this, 'admin_notices' ] );
26 add_action( 'wp_loaded', [ $this, 'hide_notices' ] );
27 add_action( 'woocommerce_stripe_updated', [ $this, 'stripe_updated' ] );
28 }
29
30 /**
31 * Allow this class and other classes to add slug keyed notices (to avoid duplication).
32 *
33 * @since 1.0.0
34 * @version 4.0.0
35 */
36 public function add_admin_notice( $slug, $class, $message, $dismissible = false ) {
37 $this->notices[ $slug ] = [
38 'class' => $class,
39 'message' => $message,
40 'dismissible' => $dismissible,
41 ];
42 }
43
44 /**
45 * Display any notices we've collected thus far.
46 *
47 * @since 1.0.0
48 * @version 4.0.0
49 */
50 public function admin_notices() {
51 if ( ! current_user_can( 'manage_woocommerce' ) ) {
52 return;
53 }
54
55 // Main Stripe payment method.
56 $this->stripe_check_environment();
57
58 // All other payment methods.
59 $this->payment_methods_check_environment();
60
61 foreach ( (array) $this->notices as $notice_key => $notice ) {
62 echo '<div class="' . esc_attr( $notice['class'] ) . '" style="position:relative;">';
63
64 if ( $notice['dismissible'] ) {
65 ?>
66 <a href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wc-stripe-hide-notice', $notice_key ), 'wc_stripe_hide_notices_nonce', '_wc_stripe_notice_nonce' ) ); ?>" class="woocommerce-message-close notice-dismiss" style="position:relative;float:right;padding:9px 0px 9px 9px 9px;text-decoration:none;"></a>
67 <?php
68 }
69
70 echo '<p>';
71 echo wp_kses(
72 $notice['message'],
73 [
74 'a' => [
75 'href' => [],
76 'target' => [],
77 ],
78 ]
79 );
80 echo '</p></div>';
81 }
82 }
83
84 /**
85 * List of available payment methods.
86 *
87 * @since 4.1.0
88 * @return array
89 */
90 public function get_payment_methods() {
91 return [
92 'alipay' => 'WC_Gateway_Stripe_Alipay',
93 'bancontact' => 'WC_Gateway_Stripe_Bancontact',
94 'eps' => 'WC_Gateway_Stripe_EPS',
95 'giropay' => 'WC_Gateway_Stripe_Giropay',
96 'ideal' => 'WC_Gateway_Stripe_Ideal',
97 'multibanco' => 'WC_Gateway_Stripe_Multibanco',
98 'p24' => 'WC_Gateway_Stripe_p24',
99 'sepa' => 'WC_Gateway_Stripe_Sepa',
100 'sofort' => 'WC_Gateway_Stripe_Sofort',
101 'boleto' => 'WC_Gateway_Stripe_Boleto',
102 'oxxo' => 'WC_Gateway_Stripe_Oxxo',
103 ];
104 }
105
106 /**
107 * The backup sanity check, in case the plugin is activated in a weird way,
108 * or the environment changes after activation. Also handles upgrade routines.
109 *
110 * @since 1.0.0
111 * @version 4.0.0
112 */
113 public function stripe_check_environment() {
114 $show_style_notice = get_option( 'wc_stripe_show_style_notice' );
115 $show_ssl_notice = get_option( 'wc_stripe_show_ssl_notice' );
116 $show_keys_notice = get_option( 'wc_stripe_show_keys_notice' );
117 $show_3ds_notice = get_option( 'wc_stripe_show_3ds_notice' );
118 $show_phpver_notice = get_option( 'wc_stripe_show_phpver_notice' );
119 $show_wcver_notice = get_option( 'wc_stripe_show_wcver_notice' );
120 $show_curl_notice = get_option( 'wc_stripe_show_curl_notice' );
121 $show_sca_notice = get_option( 'wc_stripe_show_sca_notice' );
122 $changed_keys_notice = get_option( 'wc_stripe_show_changed_keys_notice' );
123 $options = get_option( 'woocommerce_stripe_settings' );
124 $testmode = ( isset( $options['testmode'] ) && 'yes' === $options['testmode'] ) ? true : false;
125 $test_pub_key = isset( $options['test_publishable_key'] ) ? $options['test_publishable_key'] : '';
126 $test_secret_key = isset( $options['test_secret_key'] ) ? $options['test_secret_key'] : '';
127 $live_pub_key = isset( $options['publishable_key'] ) ? $options['publishable_key'] : '';
128 $live_secret_key = isset( $options['secret_key'] ) ? $options['secret_key'] : '';
129 $three_d_secure = isset( $options['three_d_secure'] ) && 'yes' === $options['three_d_secure'];
130
131 if ( isset( $options['enabled'] ) && 'yes' === $options['enabled'] ) {
132 if ( empty( $show_3ds_notice ) && $three_d_secure ) {
133 $url = 'https://stripe.com/docs/payments/3d-secure#three-ds-radar';
134
135 $message = sprintf(
136 /* translators: 1) HTML anchor open tag 2) HTML anchor closing tag */
137 __( 'WooCommerce Stripe - We see that you had the "Require 3D secure when applicable" setting turned on. This setting is not available here anymore, because it is now replaced by Stripe Radar. You can learn more about it %1$shere%2$s ', 'woocommerce-gateway-stripe' ),
138 '<a href="' . $url . '" target="_blank">',
139 '</a>'
140 );
141
142 $this->add_admin_notice( '3ds', 'notice notice-warning', $message, true );
143 }
144
145 if ( empty( $show_style_notice ) ) {
146 $message = sprintf(
147 /* translators: 1) HTML anchor open tag 2) HTML anchor closing tag */
148 __( 'WooCommerce Stripe - We recently made changes to Stripe that may impact the appearance of your checkout. If your checkout has changed unexpectedly, please follow these %1$sinstructions%2$s to fix.', 'woocommerce-gateway-stripe' ),
149 '<a href="https://woocommerce.com/document/stripe/#new-checkout-experience" target="_blank">',
150 '</a>'
151 );
152
153 $this->add_admin_notice( 'style', 'notice notice-warning', $message, true );
154
155 return;
156 }
157
158 // @codeCoverageIgnoreStart
159 if ( empty( $show_phpver_notice ) ) {
160 if ( version_compare( phpversion(), WC_STRIPE_MIN_PHP_VER, '<' ) ) {
161 /* translators: 1) int version 2) int version */
162 $message = __( 'WooCommerce Stripe - The minimum PHP version required for this plugin is %1$s. You are running %2$s.', 'woocommerce-gateway-stripe' );
163
164 $this->add_admin_notice( 'phpver', 'error', sprintf( $message, WC_STRIPE_MIN_PHP_VER, phpversion() ), true );
165
166 return;
167 }
168 }
169
170 if ( empty( $show_wcver_notice ) ) {
171 if ( WC_Stripe_Helper::is_wc_lt( WC_STRIPE_FUTURE_MIN_WC_VER ) ) {
172 /* translators: 1) int version 2) int version */
173 $message = __( 'WooCommerce Stripe - This is the last version of the plugin compatible with WooCommerce %1$s. All future versions of the plugin will require WooCommerce %2$s or greater.', 'woocommerce-gateway-stripe' );
174 $this->add_admin_notice( 'wcver', 'notice notice-warning', sprintf( $message, WC_VERSION, WC_STRIPE_FUTURE_MIN_WC_VER ), true );
175 }
176 }
177
178 if ( empty( $show_curl_notice ) ) {
179 if ( ! function_exists( 'curl_init' ) ) {
180 $this->add_admin_notice( 'curl', 'notice notice-warning', __( 'WooCommerce Stripe - cURL is not installed.', 'woocommerce-gateway-stripe' ), true );
181 }
182 }
183
184 // @codeCoverageIgnoreEnd
185 if ( empty( $show_keys_notice ) ) {
186 $secret = WC_Stripe_API::get_secret_key();
187 // phpcs:ignore
188 $should_show_notice_on_page = ! ( isset( $_GET['page'], $_GET['section'] ) && 'wc-settings' === $_GET['page'] && 0 === strpos( $_GET['section'], 'stripe' ) );
189
190 if ( empty( $secret ) && $should_show_notice_on_page ) {
191 $setting_link = $this->get_setting_link();
192
193 $notice_message = sprintf(
194 /* translators: 1) HTML anchor open tag 2) HTML anchor closing tag */
195 __( 'Stripe is almost ready. To get started, %1$sset your Stripe account keys%2$s.', 'woocommerce-gateway-stripe' ),
196 '<a href="' . $setting_link . '">',
197 '</a>'
198 );
199 $this->add_admin_notice( 'keys', 'notice notice-warning', $notice_message, true );
200 }
201
202 // Check if keys are entered properly per live/test mode.
203 if ( $testmode ) {
204 $is_test_pub_key = ! empty( $test_pub_key ) && preg_match( '/^pk_test_/', $test_pub_key );
205 $is_test_secret_key = ! empty( $test_secret_key ) && preg_match( '/^[rs]k_test_/', $test_secret_key );
206 if ( ! $is_test_pub_key || ! $is_test_secret_key ) {
207 $setting_link = $this->get_setting_link();
208
209 $notice_message = sprintf(
210 /* translators: 1) HTML anchor open tag 2) HTML anchor closing tag */
211 __( 'Stripe is in test mode however your test keys may not be valid. Test keys start with pk_test and sk_test or rk_test. Please go to your settings and, %1$sset your Stripe account keys%2$s.', 'woocommerce-gateway-stripe' ),
212 '<a href="' . $setting_link . '">',
213 '</a>'
214 );
215
216 $this->add_admin_notice( 'keys', 'notice notice-error', $notice_message, true );
217 }
218 } else {
219 $is_live_pub_key = ! empty( $live_pub_key ) && preg_match( '/^pk_live_/', $live_pub_key );
220 $is_live_secret_key = ! empty( $live_secret_key ) && preg_match( '/^[rs]k_live_/', $live_secret_key );
221 if ( ! $is_live_pub_key || ! $is_live_secret_key ) {
222 $setting_link = $this->get_setting_link();
223
224 $message = sprintf(
225 /* translators: 1) HTML anchor open tag 2) HTML anchor closing tag */
226 __( 'Stripe is in live mode however your live keys may not be valid. Live keys start with pk_live and sk_live or rk_live. Please go to your settings and, %1$sset your Stripe account keys%2$s.', 'woocommerce-gateway-stripe' ),
227 '<a href="' . $setting_link . '">',
228 '</a>'
229 );
230
231 $this->add_admin_notice( 'keys', 'notice notice-error', $message, true );
232 }
233 }
234
235 // Check if Stripe Account data was successfully fetched.
236 $account_data = WC_Stripe::get_instance()->account->get_cached_account_data();
237 if ( ! empty( $secret ) && empty( $account_data ) ) {
238 $setting_link = $this->get_setting_link();
239
240 $message = sprintf(
241 /* translators: 1) HTML anchor open tag 2) HTML anchor closing tag */
242 __( 'Your customers cannot use Stripe on checkout, because we couldn\'t connect to your account. Please go to your settings and, %1$sset your Stripe account keys%2$s.', 'woocommerce-gateway-stripe' ),
243 '<a href="' . $setting_link . '">',
244 '</a>'
245 );
246
247 $this->add_admin_notice( 'keys', 'notice notice-error', $message, true );
248 }
249 }
250
251 if ( empty( $show_ssl_notice ) ) {
252 // Show message if enabled and FORCE SSL is disabled and WordpressHTTPS plugin is not detected.
253 if ( ! wc_checkout_is_https() ) {
254 $message = sprintf(
255 /* translators: 1) HTML anchor open tag 2) HTML anchor closing tag */
256 __( 'Stripe is enabled, but a SSL certificate is not detected. Your checkout may not be secure! Please ensure your server has a valid %1$sSSL certificate%2$s.', 'woocommerce-gateway-stripe' ),
257 '<a href="https://en.wikipedia.org/wiki/Transport_Layer_Security" target="_blank">',
258 '</a>'
259 );
260
261 $this->add_admin_notice( 'ssl', 'notice notice-warning', $message, true );
262 }
263 }
264
265 if ( empty( $show_sca_notice ) ) {
266 $message = sprintf(
267 /* translators: 1) HTML anchor open tag 2) HTML anchor closing tag */
268 __( 'Stripe is now ready for Strong Customer Authentication (SCA) and 3D Secure 2! %1$sRead about SCA%2$s.', 'woocommerce-gateway-stripe' ),
269 '<a href="https://woocommerce.com/posts/introducing-strong-customer-authentication-sca/" target="_blank">',
270 '</a>'
271 );
272
273 $this->add_admin_notice( 'sca', 'notice notice-success', $message, true );
274 }
275
276 if ( 'yes' === $changed_keys_notice ) {
277 $message = sprintf(
278 /* translators: 1) HTML anchor open tag 2) HTML anchor closing tag */
279 __( 'The public and/or secret keys for the Stripe gateway have been changed. This might cause errors for existing customers and saved payment methods. %1$sClick here to learn more%2$s.', 'woocommerce-gateway-stripe' ),
280 '<a href="https://woocommerce.com/document/stripe-fixing-customer-errors" target="_blank">',
281 '</a>'
282 );
283
284 $this->add_admin_notice( 'changed_keys', 'notice notice-warning', $message, true );
285 }
286 }
287 }
288
289 /**
290 * Environment check for all other payment methods.
291 *
292 * @since 4.1.0
293 */
294 public function payment_methods_check_environment() {
295 $payment_methods = $this->get_payment_methods();
296
297 foreach ( $payment_methods as $method => $class ) {
298 $show_notice = get_option( 'wc_stripe_show_' . $method . '_notice' );
299 $gateway = new $class();
300
301 if ( 'yes' !== $gateway->enabled || 'no' === $show_notice ) {
302 continue;
303 }
304
305 if ( ! in_array( get_woocommerce_currency(), $gateway->get_supported_currency(), true ) ) {
306 /* translators: 1) Payment method, 2) List of supported currencies */
307 $this->add_admin_notice( $method, 'notice notice-error', sprintf( __( '%1$s is enabled - it requires store currency to be set to %2$s', 'woocommerce-gateway-stripe' ), $gateway->get_method_title(), implode( ', ', $gateway->get_supported_currency() ) ), true );
308 }
309 }
310
311 if ( ! WC_Stripe_Feature_Flags::is_upe_preview_enabled() || ! WC_Stripe_Feature_Flags::is_upe_checkout_enabled() ) {
312 return;
313 }
314
315 foreach ( WC_Stripe_UPE_Payment_Gateway::UPE_AVAILABLE_METHODS as $method_class ) {
316 if ( WC_Stripe_UPE_Payment_Method_CC::class === $method_class ) {
317 continue;
318 }
319 $method = $method_class::STRIPE_ID;
320 $show_notice = get_option( 'wc_stripe_show_' . $method . '_upe_notice' );
321 $upe_method = new $method_class();
322 if ( ! $upe_method->is_enabled() || 'no' === $show_notice ) {
323 continue;
324 }
325 if ( ! in_array( get_woocommerce_currency(), $upe_method->get_supported_currencies(), true ) ) {
326 /* translators: %1$s Payment method, %2$s List of supported currencies */
327 $this->add_admin_notice( $method . '_upe', 'notice notice-error', sprintf( __( '%1$s is enabled - it requires store currency to be set to %2$s', 'woocommerce-gateway-stripe' ), $upe_method->get_label(), implode( ', ', $upe_method->get_supported_currencies() ) ), true );
328 }
329 }
330 }
331
332 /**
333 * Hides any admin notices.
334 *
335 * @since 4.0.0
336 * @version 4.0.0
337 */
338 public function hide_notices() {
339 if ( isset( $_GET['wc-stripe-hide-notice'] ) && isset( $_GET['_wc_stripe_notice_nonce'] ) ) {
340 if ( ! wp_verify_nonce( wc_clean( wp_unslash( $_GET['_wc_stripe_notice_nonce'] ) ), 'wc_stripe_hide_notices_nonce' ) ) {
341 wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce-gateway-stripe' ) );
342 }
343
344 if ( ! current_user_can( 'manage_woocommerce' ) ) {
345 wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce-gateway-stripe' ) );
346 }
347
348 $notice = wc_clean( wp_unslash( $_GET['wc-stripe-hide-notice'] ) );
349
350 switch ( $notice ) {
351 case 'style':
352 update_option( 'wc_stripe_show_style_notice', 'no' );
353 break;
354 case 'phpver':
355 update_option( 'wc_stripe_show_phpver_notice', 'no' );
356 break;
357 case 'wcver':
358 update_option( 'wc_stripe_show_wcver_notice', 'no' );
359 break;
360 case 'curl':
361 update_option( 'wc_stripe_show_curl_notice', 'no' );
362 break;
363 case 'ssl':
364 update_option( 'wc_stripe_show_ssl_notice', 'no' );
365 break;
366 case 'keys':
367 update_option( 'wc_stripe_show_keys_notice', 'no' );
368 break;
369 case '3ds':
370 update_option( 'wc_stripe_show_3ds_notice', 'no' );
371 break;
372 case 'alipay':
373 update_option( 'wc_stripe_show_alipay_notice', 'no' );
374 break;
375 case 'bancontact':
376 update_option( 'wc_stripe_show_bancontact_notice', 'no' );
377 break;
378 case 'eps':
379 update_option( 'wc_stripe_show_eps_notice', 'no' );
380 break;
381 case 'giropay':
382 update_option( 'wc_stripe_show_giropay_notice', 'no' );
383 break;
384 case 'ideal':
385 update_option( 'wc_stripe_show_ideal_notice', 'no' );
386 break;
387 case 'multibanco':
388 update_option( 'wc_stripe_show_multibanco_notice', 'no' );
389 break;
390 case 'p24':
391 update_option( 'wc_stripe_show_p24_notice', 'no' );
392 break;
393 case 'sepa':
394 update_option( 'wc_stripe_show_sepa_notice', 'no' );
395 break;
396 case 'sofort':
397 update_option( 'wc_stripe_show_sofort_notice', 'no' );
398 break;
399 case 'sca':
400 update_option( 'wc_stripe_show_sca_notice', 'no' );
401 break;
402 case 'changed_keys':
403 update_option( 'wc_stripe_show_changed_keys_notice', 'no' );
404 break;
405 default:
406 if ( false !== strpos( $notice, '_upe' ) ) {
407 update_option( 'wc_stripe_show_' . $notice . '_notice', 'no' );
408 }
409 break;
410 }
411 }
412 }
413
414 /**
415 * Get setting link.
416 *
417 * @since 1.0.0
418 *
419 * @return string Setting link
420 */
421 public function get_setting_link() {
422 return esc_url( admin_url( 'admin.php?page=wc-settings&tab=checkout&section=stripe&panel=settings' ) );
423 }
424
425 /**
426 * Saves options in order to hide notices based on the gateway's version.
427 *
428 * @since 4.3.0
429 */
430 public function stripe_updated() {
431 $previous_version = get_option( 'wc_stripe_version' );
432
433 // Only show the style notice if the plugin was installed and older than 4.1.4.
434 if ( empty( $previous_version ) || version_compare( $previous_version, '4.1.4', 'ge' ) ) {
435 update_option( 'wc_stripe_show_style_notice', 'no' );
436 }
437
438 // Only show the SCA notice on pre-4.3.0 installs.
439 if ( empty( $previous_version ) || version_compare( $previous_version, '4.3.0', 'ge' ) ) {
440 update_option( 'wc_stripe_show_sca_notice', 'no' );
441 }
442 }
443}
444
445new WC_Stripe_Admin_Notices();