Completed
Pull Request — master (#1267)
by
unknown
01:45
created

woocommerce-gateway-stripe.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Plugin Name: WooCommerce Stripe Gateway
4
 * Plugin URI: https://wordpress.org/plugins/woocommerce-gateway-stripe/
5
 * Description: Take credit card payments on your store using Stripe.
6
 * Author: WooCommerce
7
 * Author URI: https://woocommerce.com/
8
 * Version: 4.5.0
9
 * Requires at least: 4.4
10
 * Tested up to: 5.4
11
 * WC requires at least: 3.0
12
 * WC tested up to: 4.2
13
 * Text Domain: woocommerce-gateway-stripe
14
 * Domain Path: /languages
15
 *
16
 */
17
18
if ( ! defined( 'ABSPATH' ) ) {
19
	exit;
20
}
21
22
/**
23
 * Required minimums and constants
24
 */
25
define( 'WC_STRIPE_VERSION', '4.5.0' );
26
define( 'WC_STRIPE_MIN_PHP_VER', '5.6.0' );
27
define( 'WC_STRIPE_MIN_WC_VER', '3.0' );
28
define( 'WC_STRIPE_FUTURE_MIN_WC_VER', '3.0' );
29
define( 'WC_STRIPE_MAIN_FILE', __FILE__ );
30
define( 'WC_STRIPE_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
31
define( 'WC_STRIPE_PLUGIN_PATH', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
32
33
// phpcs:disable WordPress.Files.FileName
34
35
/**
36
 * WooCommerce fallback notice.
37
 *
38
 * @since 4.1.2
39
 * @return string
40
 */
41
function woocommerce_stripe_missing_wc_notice() {
42
	/* translators: 1. URL link. */
43
	echo '<div class="error"><p><strong>' . sprintf( esc_html__( 'Stripe requires WooCommerce to be installed and active. You can download %s here.', 'woocommerce-gateway-stripe' ), '<a href="https://woocommerce.com/" target="_blank">WooCommerce</a>' ) . '</strong></p></div>';
44
}
45
46
/**
47
 * WooCommerce not supported fallback notice.
48
 *
49
 * @since 4.4.0
50
 * @return string
51
 */
52
function woocommerce_stripe_wc_not_supported() {
53
	/* translators: $1. Minimum WooCommerce version. $2. Current WooCommerce version. */
54
	echo '<div class="error"><p><strong>' . sprintf( esc_html__( 'Stripe requires WooCommerce %1$s or greater to be installed and active. WooCommerce %2$s is no longer supported.', 'woocommerce-gateway-stripe' ), WC_STRIPE_MIN_WC_VER, WC_VERSION ) . '</strong></p></div>';
55
}
56
57
/**
58
 * WooCommerce country not supported notice.
59
 *
60
 * @since 4.5.1
61
 * @return string
62
 */
63
function woocommerce_stripe_wc_country_not_supported() {
64
	echo '<div class="error"><p><strong>' . __( 'Stripe is not available in your store\'s country and will not be available for buyers to choose during checkout.', 'woocommerce-gateway-stripe' ) . '</strong></p></div>';
65
}
66
67
/**
68
 * Check that the WooCommerce country is supported by Stripe.
69
 * See https://stripe.com/global for list.
70
 *
71
 * @since 4.5.1
72
 * @return bool
73
 */
74
function woocommerce_stripe_wc_country_is_supported_country() {
75
	$wc_default_country = substr( get_option( 'woocommerce_default_country' ), 0, 2 );
76
77
	$supported_countries = apply_filters(
78
		'wc_stripe_supported_countries',
79
		array(
80
			'AT', // Austria
81
			'AU', // Australia
82
			'BE', // Belgium
83
			'BG', // Bulgaria
84
			'CA', // Canada
85
			'CY', // Cyprus
86
			'CZ', // Czech Republic
87
			'DK', // Denmark
88
			'EE', // Estonia
89
			'FI', // Finland
90
			'FR', // France
91
			'DE', // Germany
92
			'GR', // Greece
93
			'HK', // Hong Kong
94
			'IE', // Ireland
95
			'IT', // Italy
96
			'JP', // Japan
97
			'LV', // Latvia
98
			'LT', // Lithuania
99
			'LU', // Luxembourg
100
			'MY', // Malaysia
101
			'MT', // Malta
102
			'MX', // Mexico
103
			'NL', // Netherlands
104
			'NZ', // New Zealand
105
			'NO', // Norway
106
			'PL', // Poland
107
			'PR', // Puerto Rico #1203
108
			'PT', // Portugal
109
			'RO', // Romania
110
			'SG', // Singapore
111
			'SK', // Slovakia
112
			'SI', // Slovenia
113
			'ES', // Spain
114
			'SE', // Sweden
115
			'CH', // Switzerland
116
			'GB', // United Kingdom (UK)
117
			'US'  // United States (US)
118
		)
119
	);
120
121
	return in_array( $wc_default_country, $supported_countries );
122
}
123
124
add_action( 'plugins_loaded', 'woocommerce_gateway_stripe_init' );
125
126
function woocommerce_gateway_stripe_init() {
127
	load_plugin_textdomain( 'woocommerce-gateway-stripe', false, plugin_basename( dirname( __FILE__ ) ) . '/languages' );
128
129
	if ( ! class_exists( 'WooCommerce' ) ) {
130
		add_action( 'admin_notices', 'woocommerce_stripe_missing_wc_notice' );
131
		return;
132
	}
133
134
	if ( version_compare( WC_VERSION, WC_STRIPE_MIN_WC_VER, '<' ) ) {
135
		add_action( 'admin_notices', 'woocommerce_stripe_wc_not_supported' );
136
		return;
137
	}
138
139
	if ( ! woocommerce_stripe_wc_country_is_supported_country() ) {
140
		add_action( 'admin_notices', 'woocommerce_stripe_wc_country_not_supported' );
141
		return;
142
	}
143
144
	if ( ! class_exists( 'WC_Stripe' ) ) :
145
146
		class WC_Stripe {
147
148
			/**
149
			 * @var Singleton The reference the *Singleton* instance of this class
150
			 */
151
			private static $instance;
152
153
			/**
154
			 * Returns the *Singleton* instance of this class.
155
			 *
156
			 * @return Singleton The *Singleton* instance.
157
			 */
158
			public static function get_instance() {
159
				if ( null === self::$instance ) {
160
					self::$instance = new self();
0 ignored issues
show
Documentation Bug introduced by
It seems like new self() of type object<WC_Stripe> is incompatible with the declared type object<Singleton> of property $instance.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
161
				}
162
				return self::$instance;
0 ignored issues
show
Bug Compatibility introduced by
The expression self::$instance; of type WC_Stripe|Singleton adds the type WC_Stripe to the return on line 162 which is incompatible with the return type documented by WC_Stripe::get_instance of type Singleton.
Loading history...
163
			}
164
165
			/**
166
			 * Stripe Connect API
167
			 *
168
			 * @var WC_Stripe_Connect_API
169
			 */
170
			private $api;
171
172
			/**
173
			 * Stripe Connect
174
			 *
175
			 * @var WC_Stripe_Connect
176
			 */
177
			private $connect;
178
179
			/**
180
			 * Private clone method to prevent cloning of the instance of the
181
			 * *Singleton* instance.
182
			 *
183
			 * @return void
184
			 */
185
			private function __clone() {}
186
187
			/**
188
			 * Private unserialize method to prevent unserializing of the *Singleton*
189
			 * instance.
190
			 *
191
			 * @return void
192
			 */
193
			private function __wakeup() {}
194
195
			/**
196
			 * Protected constructor to prevent creating a new instance of the
197
			 * *Singleton* via the `new` operator from outside of this class.
198
			 */
199
			private function __construct() {
200
				add_action( 'admin_init', array( $this, 'install' ) );
201
202
				$this->init();
203
204
				$this->api     = new WC_Stripe_Connect_API();
205
				$this->connect = new WC_Stripe_Connect( $this->api );
206
207
				add_action( 'rest_api_init', array( $this, 'register_connect_routes' ) );
208
209
				if ( get_option( 'stripe_state', false ) ) {
210
					add_action( 'admin_enqueue_scripts', array( $this->connect, 'maybe_connect_oauth' ) );
211
				}
212
			}
213
214
			/**
215
			 * Init the plugin after plugins_loaded so environment variables are set.
216
			 *
217
			 * @since 1.0.0
218
			 * @version 4.0.0
219
			 */
220
			public function init() {
221
				if ( is_admin() ) {
222
					require_once dirname( __FILE__ ) . '/includes/admin/class-wc-stripe-privacy.php';
223
				}
224
225
				require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-exception.php';
226
				require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-logger.php';
227
				require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-helper.php';
228
				include_once dirname( __FILE__ ) . '/includes/class-wc-stripe-api.php';
229
				require_once dirname( __FILE__ ) . '/includes/abstracts/abstract-wc-stripe-payment-gateway.php';
230
				require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-webhook-handler.php';
231
				require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-sepa-payment-token.php';
232
				require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-apple-pay-registration.php';
233
				require_once dirname( __FILE__ ) . '/includes/compat/class-wc-stripe-pre-orders-compat.php';
234
				require_once dirname( __FILE__ ) . '/includes/class-wc-gateway-stripe.php';
235
				require_once dirname( __FILE__ ) . '/includes/payment-methods/class-wc-gateway-stripe-bancontact.php';
236
				require_once dirname( __FILE__ ) . '/includes/payment-methods/class-wc-gateway-stripe-sofort.php';
237
				require_once dirname( __FILE__ ) . '/includes/payment-methods/class-wc-gateway-stripe-giropay.php';
238
				require_once dirname( __FILE__ ) . '/includes/payment-methods/class-wc-gateway-stripe-eps.php';
239
				require_once dirname( __FILE__ ) . '/includes/payment-methods/class-wc-gateway-stripe-ideal.php';
240
				require_once dirname( __FILE__ ) . '/includes/payment-methods/class-wc-gateway-stripe-p24.php';
241
				require_once dirname( __FILE__ ) . '/includes/payment-methods/class-wc-gateway-stripe-alipay.php';
242
				require_once dirname( __FILE__ ) . '/includes/payment-methods/class-wc-gateway-stripe-sepa.php';
243
				require_once dirname( __FILE__ ) . '/includes/payment-methods/class-wc-gateway-stripe-multibanco.php';
244
				require_once dirname( __FILE__ ) . '/includes/payment-methods/class-wc-stripe-payment-request.php';
245
				require_once dirname( __FILE__ ) . '/includes/compat/class-wc-stripe-subs-compat.php';
246
				require_once dirname( __FILE__ ) . '/includes/compat/class-wc-stripe-sepa-subs-compat.php';
247
				require_once dirname( __FILE__ ) . '/includes/connect/class-wc-stripe-connect.php';
248
				require_once dirname( __FILE__ ) . '/includes/connect/class-wc-stripe-connect-api.php';
249
				require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-order-handler.php';
250
				require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-payment-tokens.php';
251
				require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-customer.php';
252
				require_once dirname( __FILE__ ) . '/includes/class-wc-stripe-intent-controller.php';
253
254
				if ( is_admin() ) {
255
					require_once dirname( __FILE__ ) . '/includes/admin/class-wc-stripe-admin-notices.php';
256
				}
257
258
				// REMOVE IN THE FUTURE.
259
				require_once dirname( __FILE__ ) . '/includes/deprecated/class-wc-stripe-apple-pay.php';
260
261
				add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateways' ) );
262
				add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_action_links' ) );
263
				add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
264
265
				// Modify emails emails.
266
				add_filter( 'woocommerce_email_classes', array( $this, 'add_emails' ), 20 );
267
268
				if ( version_compare( WC_VERSION, '3.4', '<' ) ) {
269
					add_filter( 'woocommerce_get_sections_checkout', array( $this, 'filter_gateway_order_admin' ) );
270
				}
271
			}
272
273
			/**
274
			 * Updates the plugin version in db
275
			 *
276
			 * @since 3.1.0
277
			 * @version 4.0.0
278
			 */
279
			public function update_plugin_version() {
280
				delete_option( 'wc_stripe_version' );
281
				update_option( 'wc_stripe_version', WC_STRIPE_VERSION );
282
			}
283
284
			/**
285
			 * Handles upgrade routines.
286
			 *
287
			 * @since 3.1.0
288
			 * @version 3.1.0
289
			 */
290
			public function install() {
291
				if ( ! is_plugin_active( plugin_basename( __FILE__ ) ) ) {
292
					return;
293
				}
294
295
				if ( ! defined( 'IFRAME_REQUEST' ) && ( WC_STRIPE_VERSION !== get_option( 'wc_stripe_version' ) ) ) {
296
					do_action( 'woocommerce_stripe_updated' );
297
298
					if ( ! defined( 'WC_STRIPE_INSTALLING' ) ) {
299
						define( 'WC_STRIPE_INSTALLING', true );
300
					}
301
302
					$this->update_plugin_version();
303
				}
304
			}
305
306
			/**
307
			 * Add plugin action links.
308
			 *
309
			 * @since 1.0.0
310
			 * @version 4.0.0
311
			 */
312
			public function plugin_action_links( $links ) {
313
				$plugin_links = array(
314
					'<a href="admin.php?page=wc-settings&tab=checkout&section=stripe">' . esc_html__( 'Settings', 'woocommerce-gateway-stripe' ) . '</a>',
315
				);
316
				return array_merge( $plugin_links, $links );
317
			}
318
319
			/**
320
			 * Add plugin action links.
321
			 *
322
			 * @since 4.3.4
323
			 * @param  array  $links Original list of plugin links.
324
			 * @param  string $file  Name of current file.
325
			 * @return array  $links Update list of plugin links.
326
			 */
327
			public function plugin_row_meta( $links, $file ) {
328
				if ( plugin_basename( __FILE__ ) === $file ) {
329
					$row_meta = array(
330
						'docs'    => '<a href="' . esc_url( apply_filters( 'woocommerce_gateway_stripe_docs_url', 'https://docs.woocommerce.com/document/stripe/' ) ) . '" title="' . esc_attr( __( 'View Documentation', 'woocommerce-gateway-stripe' ) ) . '">' . __( 'Docs', 'woocommerce-gateway-stripe' ) . '</a>',
331
						'support' => '<a href="' . esc_url( apply_filters( 'woocommerce_gateway_stripe_support_url', 'https://woocommerce.com/my-account/create-a-ticket?select=18627' ) ) . '" title="' . esc_attr( __( 'Open a support request at WooCommerce.com', 'woocommerce-gateway-stripe' ) ) . '">' . __( 'Support', 'woocommerce-gateway-stripe' ) . '</a>',
332
					);
333
					return array_merge( $links, $row_meta );
334
				}
335
				return (array) $links;
336
			}
337
338
			/**
339
			 * Add the gateways to WooCommerce.
340
			 *
341
			 * @since 1.0.0
342
			 * @version 4.0.0
343
			 */
344
			public function add_gateways( $methods ) {
345
				if ( class_exists( 'WC_Subscriptions_Order' ) && function_exists( 'wcs_create_renewal_order' ) ) {
346
					$methods[] = 'WC_Stripe_Subs_Compat';
347
					$methods[] = 'WC_Stripe_Sepa_Subs_Compat';
348
				} else {
349
					$methods[] = 'WC_Gateway_Stripe';
350
					$methods[] = 'WC_Gateway_Stripe_Sepa';
351
				}
352
353
				$methods[] = 'WC_Gateway_Stripe_Bancontact';
354
				$methods[] = 'WC_Gateway_Stripe_Sofort';
355
				$methods[] = 'WC_Gateway_Stripe_Giropay';
356
				$methods[] = 'WC_Gateway_Stripe_Eps';
357
				$methods[] = 'WC_Gateway_Stripe_Ideal';
358
				$methods[] = 'WC_Gateway_Stripe_P24';
359
				$methods[] = 'WC_Gateway_Stripe_Alipay';
360
				$methods[] = 'WC_Gateway_Stripe_Multibanco';
361
362
				return $methods;
363
			}
364
365
			/**
366
			 * Modifies the order of the gateways displayed in admin.
367
			 *
368
			 * @since 4.0.0
369
			 * @version 4.0.0
370
			 */
371
			public function filter_gateway_order_admin( $sections ) {
372
				unset( $sections['stripe'] );
373
				unset( $sections['stripe_bancontact'] );
374
				unset( $sections['stripe_sofort'] );
375
				unset( $sections['stripe_giropay'] );
376
				unset( $sections['stripe_eps'] );
377
				unset( $sections['stripe_ideal'] );
378
				unset( $sections['stripe_p24'] );
379
				unset( $sections['stripe_alipay'] );
380
				unset( $sections['stripe_sepa'] );
381
				unset( $sections['stripe_multibanco'] );
382
383
				$sections['stripe']            = 'Stripe';
384
				$sections['stripe_bancontact'] = __( 'Stripe Bancontact', 'woocommerce-gateway-stripe' );
385
				$sections['stripe_sofort']     = __( 'Stripe SOFORT', 'woocommerce-gateway-stripe' );
386
				$sections['stripe_giropay']    = __( 'Stripe Giropay', 'woocommerce-gateway-stripe' );
387
				$sections['stripe_eps']        = __( 'Stripe EPS', 'woocommerce-gateway-stripe' );
388
				$sections['stripe_ideal']      = __( 'Stripe iDeal', 'woocommerce-gateway-stripe' );
389
				$sections['stripe_p24']        = __( 'Stripe P24', 'woocommerce-gateway-stripe' );
390
				$sections['stripe_alipay']     = __( 'Stripe Alipay', 'woocommerce-gateway-stripe' );
391
				$sections['stripe_sepa']       = __( 'Stripe SEPA Direct Debit', 'woocommerce-gateway-stripe' );
392
				$sections['stripe_multibanco'] = __( 'Stripe Multibanco', 'woocommerce-gateway-stripe' );
393
394
				return $sections;
395
			}
396
397
			/**
398
			 * Adds the failed SCA auth email to WooCommerce.
399
			 *
400
			 * @param WC_Email[] $email_classes All existing emails.
401
			 * @return WC_Email[]
402
			 */
403
			public function add_emails( $email_classes ) {
404
				require_once WC_STRIPE_PLUGIN_PATH . '/includes/compat/class-wc-stripe-email-failed-authentication.php';
405
				require_once WC_STRIPE_PLUGIN_PATH . '/includes/compat/class-wc-stripe-email-failed-renewal-authentication.php';
406
				require_once WC_STRIPE_PLUGIN_PATH . '/includes/compat/class-wc-stripe-email-failed-preorder-authentication.php';
407
				require_once WC_STRIPE_PLUGIN_PATH . '/includes/compat/class-wc-stripe-email-failed-authentication-retry.php';
408
409
				// Add all emails, generated by the gateway.
410
				$email_classes['WC_Stripe_Email_Failed_Renewal_Authentication']  = new WC_Stripe_Email_Failed_Renewal_Authentication( $email_classes );
411
				$email_classes['WC_Stripe_Email_Failed_Preorder_Authentication'] = new WC_Stripe_Email_Failed_Preorder_Authentication( $email_classes );
412
				$email_classes['WC_Stripe_Email_Failed_Authentication_Retry'] = new WC_Stripe_Email_Failed_Authentication_Retry( $email_classes );
413
414
				return $email_classes;
415
			}
416
417
			/**
418
			 * Register Stripe connect rest routes.
419
			 */
420
			public function register_connect_routes() {
421
422
				require_once WC_STRIPE_PLUGIN_PATH . '/includes/connect/class-wc-stripe-connect-rest-controller.php';
423
				require_once WC_STRIPE_PLUGIN_PATH . '/includes/connect/class-wc-stripe-connect-rest-oauth-init-controller.php';
424
				require_once WC_STRIPE_PLUGIN_PATH . '/includes/connect/class-wc-stripe-connect-rest-oauth-connect-controller.php';
425
				require_once WC_STRIPE_PLUGIN_PATH . '/includes/connect/class-wc-stripe-connect-rest-deauthorize-controller.php';
426
427
				$oauth_init    = new WC_Stripe_Connect_REST_Oauth_Init_Controller( $this->connect, $this->api );
428
				$oauth_connect = new WC_Stripe_Connect_REST_Oauth_Connect_Controller( $this->connect, $this->api );
429
				$deauthorize   = new WC_Stripe_Connect_REST_Deauthorize_Controller( $this->connect, $this->api );
430
431
				$oauth_init->register_routes();
432
				$oauth_connect->register_routes();
433
				$deauthorize->register_routes();
434
			}
435
		}
436
437
		WC_Stripe::get_instance();
438
	endif;
439
}
440