PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 10.4.2
WooCommerce v10.4.2
10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / includes / class-wc-payment-gateways.php
woocommerce / includes Last commit date
abstracts 6 months ago admin 6 months ago blocks 10 months ago cli 7 months ago customizer 6 months ago data-stores 5 months ago emails 6 months ago export 1 year ago gateways 5 months ago import 11 months ago integrations 2 years ago interfaces 1 year ago legacy 1 year ago libraries 1 year ago log-handlers 1 year ago payment-tokens 5 years ago product-usage 1 year ago queue 4 years ago react-admin 6 months ago rest-api 6 months ago shipping 6 months ago shortcodes 10 months ago theme-support 2 years ago tracks 6 months ago traits 5 years ago walkers 5 years ago wccom-site 9 months ago widgets 6 months ago class-wc-ajax.php 6 months ago class-wc-auth.php 1 year ago class-wc-autoloader.php 7 months ago class-wc-background-emailer.php 5 years ago class-wc-background-updater.php 5 years ago class-wc-brands-brand-settings-manager.php 1 year ago class-wc-brands-coupons.php 1 year ago class-wc-brands.php 6 months ago class-wc-breadcrumb.php 5 years ago class-wc-cache-helper.php 7 months ago class-wc-cart-fees.php 2 years ago class-wc-cart-session.php 6 months ago class-wc-cart-totals.php 10 months ago class-wc-cart.php 7 months ago class-wc-checkout.php 1 year ago class-wc-cli.php 9 months ago class-wc-comments.php 9 months ago class-wc-countries.php 7 months ago class-wc-coupon.php 6 months ago class-wc-customer-download-log.php 5 years ago class-wc-customer-download.php 1 year ago class-wc-customer.php 9 months ago class-wc-data-exception.php 8 years ago class-wc-data-store.php 3 years ago class-wc-datetime.php 4 years ago class-wc-deprecated-action-hooks.php 2 years ago class-wc-deprecated-filter-hooks.php 3 years ago class-wc-discounts.php 10 months ago class-wc-download-handler.php 1 year ago class-wc-emails.php 10 months ago class-wc-embed.php 1 year ago class-wc-form-handler.php 6 months ago class-wc-frontend-scripts.php 6 months ago class-wc-geo-ip.php 7 months ago class-wc-geolite-integration.php 6 years ago class-wc-geolocation.php 1 year ago class-wc-https.php 2 years ago class-wc-install.php 6 months ago class-wc-integrations.php 5 years ago class-wc-log-levels.php 2 years ago class-wc-logger.php 1 year ago class-wc-meta-data.php 4 years ago class-wc-order-factory.php 2 years ago class-wc-order-item-coupon.php 4 years ago class-wc-order-item-fee.php 1 year ago class-wc-order-item-meta.php 4 years ago class-wc-order-item-product.php 7 months ago class-wc-order-item-shipping.php 1 year ago class-wc-order-item-tax.php 4 years ago class-wc-order-item.php 7 months ago class-wc-order-query.php 4 years ago class-wc-order-refund.php 1 year ago class-wc-order.php 6 months ago class-wc-payment-gateways.php 7 months ago class-wc-payment-tokens.php 3 years ago class-wc-post-data.php 6 months ago class-wc-post-types.php 1 year ago class-wc-privacy-background-process.php 1 year ago class-wc-privacy-erasers.php 9 months ago class-wc-privacy-exporters.php 4 years ago class-wc-privacy.php 11 months ago class-wc-product-attribute.php 4 years ago class-wc-product-download.php 2 years ago class-wc-product-external.php 1 year ago class-wc-product-factory.php 1 year ago class-wc-product-grouped.php 10 months ago class-wc-product-query.php 1 year ago class-wc-product-simple.php 10 months ago class-wc-product-variable.php 10 months ago class-wc-product-variation.php 1 year ago class-wc-query.php 6 months ago class-wc-rate-limiter.php 4 years ago class-wc-regenerate-images-request.php 3 years ago class-wc-regenerate-images.php 1 year ago class-wc-register-wp-admin-settings.php 4 years ago class-wc-rest-authentication.php 1 year ago class-wc-rest-exception.php 5 years ago class-wc-session-handler.php 7 months ago class-wc-shipping-rate.php 11 months ago class-wc-shipping-zone.php 5 years ago class-wc-shipping-zones.php 6 months ago class-wc-shipping.php 1 year ago class-wc-shortcodes.php 1 year ago class-wc-structured-data.php 6 months ago class-wc-tax.php 10 months ago class-wc-template-loader.php 6 months ago class-wc-tracker.php 7 months ago class-wc-validation.php 2 years ago class-wc-webhook.php 7 months ago class-woocommerce.php 5 months ago wc-account-functions.php 6 months ago wc-attribute-functions.php 9 months ago wc-brands-functions.php 1 year ago wc-cart-functions.php 9 months ago wc-conditional-functions.php 10 months ago wc-core-functions.php 5 months ago wc-coupon-functions.php 10 months ago wc-deprecated-functions.php 9 months ago wc-formatting-functions.php 6 months ago wc-notice-functions.php 11 months ago wc-order-functions.php 6 months ago wc-order-item-functions.php 3 years ago wc-order-step-logger-functions.php 6 months ago wc-page-functions.php 1 year ago wc-product-functions.php 7 months ago wc-rest-functions.php 6 months ago wc-stock-functions.php 6 months ago wc-template-functions.php 7 months ago wc-template-hooks.php 9 months ago wc-term-functions.php 6 months ago wc-update-functions.php 6 months ago wc-user-functions.php 6 months ago wc-webhook-functions.php 1 year ago wc-widget-functions.php 5 years ago
class-wc-payment-gateways.php
532 lines
1 <?php
2 /**
3 * WooCommerce Payment Gateways
4 *
5 * Loads payment gateways via hooks for use in the store.
6 *
7 * @version 2.2.0
8 * @package WooCommerce\Classes\Payment
9 */
10
11 use Automattic\WooCommerce\Enums\PaymentGatewayFeature;
12 use Automattic\WooCommerce\Internal\Admin\Settings\Payments as SettingsPaymentsService;
13 use Automattic\WooCommerce\Internal\Admin\Settings\PaymentsProviders;
14 use Automattic\WooCommerce\Internal\Logging\SafeGlobalFunctionProxy;
15 use Automattic\WooCommerce\Proxies\LegacyProxy;
16 use Automattic\WooCommerce\Utilities\ArrayUtil;
17
18 defined( 'ABSPATH' ) || exit;
19
20 /**
21 * Payment gateways class.
22 */
23 class WC_Payment_Gateways {
24
25 /**
26 * Payment gateway classes.
27 *
28 * @var array
29 */
30 public $payment_gateways = array();
31
32 /**
33 * The single instance of the class.
34 *
35 * @var WC_Payment_Gateways
36 * @since 2.1.0
37 */
38 protected static $_instance = null;
39
40 /**
41 * Main WC_Payment_Gateways Instance.
42 *
43 * Ensures only one instance of WC_Payment_Gateways is loaded or can be loaded.
44 *
45 * @since 2.1
46 * @return WC_Payment_Gateways Main instance
47 */
48 public static function instance() {
49 if ( is_null( self::$_instance ) ) {
50 self::$_instance = new self();
51 }
52 return self::$_instance;
53 }
54
55 /**
56 * Cloning is forbidden.
57 *
58 * @since 2.1
59 */
60 public function __clone() {
61 wc_doing_it_wrong( __FUNCTION__, __( 'Cloning is forbidden.', 'woocommerce' ), '2.1' );
62 }
63
64 /**
65 * Unserializing instances of this class is forbidden.
66 *
67 * @since 2.1
68 */
69 public function __wakeup() {
70 wc_doing_it_wrong( __FUNCTION__, __( 'Unserializing instances of this class is forbidden.', 'woocommerce' ), '2.1' );
71 }
72
73 /**
74 * Initialize payment gateways.
75 */
76 public function __construct() {
77 $this->init();
78 }
79
80 /**
81 * Load gateways and hook in functions.
82 */
83 public function init() {
84 $load_gateways = array(
85 'WC_Gateway_BACS',
86 'WC_Gateway_Cheque',
87 'WC_Gateway_COD',
88 'WC_Gateway_Paypal',
89 );
90
91 // Filter.
92 $load_gateways = apply_filters( 'woocommerce_payment_gateways', $load_gateways );
93
94 // Get sort order option.
95 $ordering = (array) get_option( 'woocommerce_gateway_order' );
96 $order_end = 999;
97
98 // Load gateways in order.
99 foreach ( $load_gateways as $gateway ) {
100 if ( is_string( $gateway ) && class_exists( $gateway ) ) {
101 $gateway = new $gateway();
102 }
103
104 if ( is_a( $gateway, 'WC_Gateway_Paypal' ) ) {
105 WC_Gateway_Paypal::set_instance( $gateway );
106 if ( ! $this->should_load_paypal_standard() ) {
107 continue;
108 }
109 }
110
111 // Gateways need to be valid and extend WC_Payment_Gateway.
112 if ( ! is_a( $gateway, 'WC_Payment_Gateway' ) ) {
113 continue;
114 }
115
116 if ( isset( $ordering[ $gateway->id ] ) && is_numeric( $ordering[ $gateway->id ] ) ) {
117 // Add in position.
118 $this->payment_gateways[ $ordering[ $gateway->id ] ] = $gateway;
119 } else {
120 // Add to end of the array.
121 $this->payment_gateways[ $order_end ] = $gateway;
122 ++$order_end;
123 }
124 }
125
126 ksort( $this->payment_gateways );
127
128 add_action( 'wc_payment_gateways_initialized', array( $this, 'on_payment_gateways_initialized' ) );
129 /**
130 * Hook that is called when the payment gateways have been initialized.
131 *
132 * @param WC_Payment_Gateways $wc_payment_gateways The payment gateways instance.
133 * @since 8.5.0
134 */
135 do_action( 'wc_payment_gateways_initialized', $this );
136 }
137
138 // phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.Found
139
140 /**
141 * Hook into payment gateway settings changes.
142 *
143 * @param WC_Payment_Gateways $wc_payment_gateways The WC_Payment_Gateways instance.
144 * @since 8.5.0
145 *
146 * @internal For exclusive usage of WooCommerce core, backwards compatibility not guaranteed.
147 */
148 public function on_payment_gateways_initialized( WC_Payment_Gateways $wc_payment_gateways ) {
149 foreach ( $this->payment_gateways as $gateway ) {
150 $option_key = $gateway->get_option_key();
151 add_action(
152 'add_option_' . $option_key,
153 function ( $option, $value ) use ( $gateway ) {
154 $this->payment_gateway_settings_option_changed( $gateway, $value, $option );
155 },
156 10,
157 2
158 );
159 add_action(
160 'update_option_' . $option_key,
161 function ( $old_value, $value, $option ) use ( $gateway ) {
162 $this->payment_gateway_settings_option_changed( $gateway, $value, $option, $old_value );
163 },
164 10,
165 3
166 );
167 }
168 }
169
170 // phpcs:enable Generic.CodeAnalysis.UnusedFunctionParameter.Found
171
172 /**
173 * Callback for when a gateway settings option was added or updated.
174 *
175 * @param WC_Payment_Gateway $gateway The gateway for which the option was added or updated.
176 * @param mixed $value New value.
177 * @param string $option Option name.
178 * @param mixed $old_value Old value. `null` when called via add_option_ hook.
179 * @since 8.5.0
180 */
181 private function payment_gateway_settings_option_changed( $gateway, $value, $option, $old_value = null ) {
182 if ( $this->was_gateway_enabled( $value, $old_value ) ) {
183 // This is a change to a payment gateway's settings and it was just enabled. Let's send an email to the admin.
184 // "untitled" shouldn't happen, but just in case.
185 $this->notify_admin_payment_gateway_enabled( $gateway );
186
187 // Track the gateway enable.
188 $this->record_gateway_event( 'enable', $gateway );
189 }
190
191 if ( $this->was_gateway_disabled( $value, $old_value ) ) {
192 // This is a change to a payment gateway's settings and it was just disabled. Let's track it.
193 $this->record_gateway_event( 'disable', $gateway );
194 }
195 }
196
197 /**
198 * Email the site admin when a payment gateway has been enabled.
199 *
200 * @param WC_Payment_Gateway $gateway The gateway that was enabled.
201 * @return bool Whether the email was sent or not.
202 * @since 8.5.0
203 */
204 private function notify_admin_payment_gateway_enabled( $gateway ) {
205 $admin_email = get_option( 'admin_email' );
206 $user = get_user_by( 'email', $admin_email );
207 $username = $user ? $user->user_login : $admin_email;
208 $gateway_title = $gateway->get_method_title();
209 $gateway_settings_url = esc_url_raw( self_admin_url( 'admin.php?page=wc-settings&tab=checkout&section=' . $gateway->id ) );
210 $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
211 $site_url = home_url();
212 /**
213 * Allows adding to the addresses that receive payment gateway enabled notifications.
214 *
215 * @param array $email_addresses The array of email addresses to notify.
216 * @param WC_Payment_Gateway $gateway The gateway that was enabled.
217 * @return array The augmented array of email addresses to notify.
218 * @since 8.5.0
219 */
220 $email_addresses = apply_filters( 'wc_payment_gateway_enabled_notification_email_addresses', array(), $gateway );
221 $email_addresses[] = $admin_email;
222 $email_addresses = array_unique(
223 array_filter(
224 $email_addresses,
225 function ( $email_address ) {
226 return filter_var( $email_address, FILTER_VALIDATE_EMAIL );
227 }
228 )
229 );
230
231 $logger = wc_get_container()->get( LegacyProxy::class )->call_function( 'wc_get_logger' );
232 $logger->info( sprintf( 'Payment gateway enabled: "%s"', $gateway_title ) );
233
234 $email_text = sprintf(
235 /* translators: Payment gateway enabled notification email. 1: Username, 2: Gateway Title, 3: Site URL, 4: Gateway Settings URL, 5: Admin Email, 6: Site Name, 7: Site URL. */
236 __(
237 'Howdy %1$s,
238
239 The payment gateway "%2$s" was just enabled on this site:
240 %3$s
241
242 If this was intentional you can safely ignore and delete this email.
243
244 If you did not enable this payment gateway, please log in to your site and consider disabling it here:
245 %4$s
246
247 This email has been sent to %5$s
248
249 Regards,
250 All at %6$s
251 %7$s',
252 'woocommerce'
253 ),
254 $username,
255 $gateway_title,
256 $site_url,
257 $gateway_settings_url,
258 $admin_email,
259 $site_name,
260 $site_url
261 );
262
263 if ( '' !== get_option( 'blogname' ) ) {
264 $site_title = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
265 } else {
266 $site_title = wp_parse_url( home_url(), PHP_URL_HOST );
267 }
268
269 return wp_mail(
270 $email_addresses,
271 sprintf(
272 /* translators: Payment gateway enabled notification email subject. %s1: Site title, $s2: Gateway title. */
273 __( '[%1$s] Payment gateway "%2$s" enabled', 'woocommerce' ),
274 $site_title,
275 $gateway_title
276 ),
277 $email_text
278 );
279 }
280
281 /**
282 * Determines from changes in settings if a gateway was enabled.
283 *
284 * @param array $value New value.
285 * @param array $old_value Old value.
286 * @return bool Whether the gateway was enabled or not.
287 */
288 private function was_gateway_enabled( $value, $old_value = null ) {
289 if ( null === $old_value ) {
290 // There was no old value, so this is a new option.
291 if ( ! empty( $value ) && is_array( $value ) && isset( $value['enabled'] ) && 'yes' === $value['enabled'] && isset( $value['title'] ) ) {
292 return true;
293 }
294 return false;
295 }
296 // There was an old value, so this is an update.
297 if (
298 ArrayUtil::get_value_or_default( $value, 'enabled' ) === 'yes' &&
299 ArrayUtil::get_value_or_default( $old_value, 'enabled' ) !== 'yes' ) {
300 return true;
301 }
302 return false;
303 }
304
305 /**
306 * Determines from changes in settings if a gateway was disabled.
307 *
308 * @param array $value New value.
309 * @param array $old_value Old value.
310 * @return bool Whether the gateway was disabled or not.
311 */
312 private function was_gateway_disabled( $value, $old_value = null ) {
313 if ( null === $old_value ) {
314 // There was no old value, so this is a new option.
315 // We don't consider a new option for determining if a gateway was disabled.
316 return false;
317 }
318
319 // There was an old value, so this is an update.
320 if (
321 ArrayUtil::get_value_or_default( $value, 'enabled' ) === 'no' &&
322 ArrayUtil::get_value_or_default( $old_value, 'enabled' ) !== 'no' ) {
323 return true;
324 }
325
326 return false;
327 }
328
329 /**
330 * Get gateways.
331 *
332 * @return array
333 */
334 public function payment_gateways() {
335 $_available_gateways = array();
336
337 if ( count( $this->payment_gateways ) > 0 ) {
338 foreach ( $this->payment_gateways as $gateway ) {
339 $_available_gateways[ $gateway->id ] = $gateway;
340 }
341 }
342
343 return $_available_gateways;
344 }
345
346 /**
347 * Get array of registered gateway ids
348 *
349 * @since 2.6.0
350 * @return array of strings
351 */
352 public function get_payment_gateway_ids() {
353 return wp_list_pluck( $this->payment_gateways, 'id' );
354 }
355
356 /**
357 * Get available gateways for checkout.
358 *
359 * This should be used when displaying the available gateways/payment methods to the user,
360 * not in the WP admin or REST API contexts where there is no WC session.
361 * This is because the logic that hooks into the available gateways filter
362 * may try to rely on the existence of a WC session - a valid thing to do,
363 * and cause fatal errors when the session is not available.
364 *
365 * @return array The available payment gateways.
366 */
367 public function get_available_payment_gateways() {
368 $_available_gateways = array();
369
370 foreach ( $this->payment_gateways as $gateway ) {
371 if ( $gateway->is_available() ) {
372 if ( ! is_add_payment_method_page() ) {
373 $_available_gateways[ $gateway->id ] = $gateway;
374 } elseif ( $gateway->supports( PaymentGatewayFeature::ADD_PAYMENT_METHOD ) || $gateway->supports( PaymentGatewayFeature::TOKENIZATION ) ) {
375 $_available_gateways[ $gateway->id ] = $gateway;
376 }
377 }
378 }
379
380 return array_filter( (array) apply_filters( 'woocommerce_available_payment_gateways', $_available_gateways ), array( $this, 'filter_valid_gateway_class' ) );
381 }
382
383 /**
384 * Callback for array filter. Returns true if gateway is of correct type.
385 *
386 * @since 3.6.0
387 * @param object $gateway Gateway to check.
388 * @return bool
389 */
390 protected function filter_valid_gateway_class( $gateway ) {
391 return $gateway && is_a( $gateway, 'WC_Payment_Gateway' );
392 }
393
394 /**
395 * Set the current, active gateway.
396 *
397 * @param array $gateways Available payment gateways.
398 */
399 public function set_current_gateway( $gateways ) {
400 // Be on the defensive.
401 if ( ! is_array( $gateways ) || empty( $gateways ) ) {
402 return;
403 }
404
405 $current_gateway = false;
406
407 if ( WC()->session ) {
408 $current = WC()->session->get( 'chosen_payment_method' );
409
410 if ( $current && isset( $gateways[ $current ] ) ) {
411 $current_gateway = $gateways[ $current ];
412 }
413 }
414
415 if ( ! $current_gateway ) {
416 $current_gateway = current( $gateways );
417 }
418
419 // Ensure we can make a call to set_current() without triggering an error.
420 if ( $current_gateway && is_callable( array( $current_gateway, 'set_current' ) ) ) {
421 $current_gateway->set_current();
422 }
423 }
424
425 /**
426 * Save options in admin.
427 */
428 public function process_admin_options() {
429 $gateway_order = isset( $_POST['gateway_order'] ) ? wc_clean( wp_unslash( $_POST['gateway_order'] ) ) : ''; // WPCS: input var ok, CSRF ok.
430 $order = array();
431
432 if ( is_array( $gateway_order ) && count( $gateway_order ) > 0 ) {
433 $loop = 0;
434 foreach ( $gateway_order as $gateway_id ) {
435 $order[ esc_attr( $gateway_id ) ] = $loop;
436 ++$loop;
437 }
438 }
439
440 update_option( 'woocommerce_gateway_order', $order );
441 }
442
443 /**
444 * Determines if PayPal Standard should be loaded.
445 *
446 * @since 5.5.0
447 * @return bool Whether PayPal Standard should be loaded or not.
448 */
449 protected function should_load_paypal_standard() {
450 $paypal = WC_Gateway_Paypal::get_instance();
451 return $paypal->should_load();
452 }
453
454 /**
455 * Send a Tracks event.
456 *
457 * By default, Woo adds `url`, `blog_lang`, `blog_id`, `store_id`, `products_count`, and `wc_version`
458 * properties to every event.
459 *
460 * @param string $name The event name.
461 * If it is not prefixed, it will be with the standard prefix.
462 * @param WC_Payment_Gateway $gateway The payment gateway object.
463 *
464 * @return void
465 */
466 private function record_gateway_event( string $name, $gateway ) {
467 if ( ! function_exists( 'wc_admin_record_tracks_event' ) ) {
468 return;
469 }
470
471 if ( ! is_a( $gateway, 'WC_Payment_Gateway' ) ) {
472 // If the gateway is not a valid payment gateway, we don't record the event.
473 return;
474 }
475
476 // If the event name is empty, we don't record it.
477 if ( empty( $name ) ) {
478 return;
479 }
480
481 // If the event name is not prefixed, we prefix it.
482 $prefix = SettingsPaymentsService::EVENT_PREFIX . 'provider_';
483 if ( ! str_starts_with( $name, $prefix ) ) {
484 $name = $prefix . $name;
485 }
486
487 $properties = array(
488 'provider_id' => $gateway->id,
489 'business_country' => WC()->countries->get_base_country(),
490 );
491
492 try {
493 /**
494 * The Payments Settings [page] service.
495 *
496 * @var SettingsPaymentsService $settings_payments_service
497 */
498 $settings_payments_service = wc_get_container()->get( SettingsPaymentsService::class );
499 // Get the business country from the Payments Settings service.
500 $properties['business_country'] = $settings_payments_service->get_country();
501
502 /**
503 * The Payments Providers service.
504 *
505 * @var PaymentsProviders $payments_providers_service
506 */
507 $payments_providers_service = wc_get_container()->get( PaymentsProviders::class );
508
509 $gateway_details = $payments_providers_service->get_payment_gateway_details( $gateway, 0, $properties['business_country'] );
510 // If the gateway details have a suggestion ID, we add it to the properties.
511 if ( ! empty( $gateway_details['_suggestion_id'] ) ) {
512 $properties['suggestion_id'] = $gateway_details['_suggestion_id'];
513 }
514 if ( ! empty( $gateway_details['plugin']['slug'] ) ) {
515 $properties['provider_extension_slug'] = $gateway_details['plugin']['slug'];
516 }
517 } catch ( \Throwable $e ) {
518 // Do nothing but log so we can investigate.
519 SafeGlobalFunctionProxy::wc_get_logger()->debug(
520 'Failed to gather provider-specific details for gateway: ' . $e->getMessage(),
521 array(
522 'gateway' => $gateway->id,
523 'source' => 'settings-payments',
524 'exception' => $e,
525 )
526 );
527 }
528
529 wc_admin_record_tracks_event( $name, $properties );
530 }
531 }
532