Automattic\WooCommerce\Internal\Admin\Settings

PaymentProviders::get_extension_suggestionspublicWC 1.0

Get the payment extension suggestions for the given location.

Method of the class: PaymentProviders{}

No Hooks.

Returns

Array[]. The payment extension suggestions for the given location, split into preferred and other.

Usage

$PaymentProviders = new PaymentProviders();
$PaymentProviders->get_extension_suggestions( $location, $context ): array;
$location(string) (required)
The location for which the suggestions are being fetched.
$context(string)
The context ID of where these extensions are being used.
Default: ''

PaymentProviders::get_extension_suggestions() code WC 9.9.4

public function get_extension_suggestions( string $location, string $context = '' ): array {
	$preferred_psp         = null;
	$preferred_apm         = null;
	$preferred_offline_psp = null;
	$other                 = array();

	$extensions = $this->extension_suggestions->get_country_extensions( $location, $context );
	// Sort them by _priority.
	usort(
		$extensions,
		function ( $a, $b ) {
			return $a['_priority'] <=> $b['_priority'];
		}
	);

	$has_enabled_ecommerce_gateways = $this->has_enabled_ecommerce_gateways();

	// Keep track of the active extensions.
	$active_extensions = array();

	foreach ( $extensions as $extension ) {
		$extension = $this->enhance_extension_suggestion( $extension );

		if ( self::EXTENSION_ACTIVE === $extension['plugin']['status'] ) {
			// If the suggested extension is active, we no longer suggest it.
			// But remember it for later.
			$active_extensions[] = $extension['id'];
			continue;
		}

		// Determine if the suggestion is preferred or not by looking at its tags.
		$is_preferred = in_array( ExtensionSuggestions::TAG_PREFERRED, $extension['tags'], true );

		// Determine if the suggestion is hidden (from the preferred locations).
		$is_hidden = $this->is_payment_extension_suggestion_hidden( $extension );

		if ( ! $is_hidden && $is_preferred ) {
			// If we don't have a preferred offline payments PSP and the suggestion is an offline payments preferred PSP,
			// add it to the preferred list.
			// Check this first so we don't inadvertently "fill" the preferred PSP slot.
			if ( empty( $preferred_offline_psp ) &&
				ExtensionSuggestions::TYPE_PSP === $extension['_type'] &&
				in_array( ExtensionSuggestions::TAG_PREFERRED_OFFLINE, $extension['tags'], true ) ) {

				$preferred_offline_psp = $extension;
				continue;
			}

			// If we don't have a preferred PSP and the suggestion is a preferred PSP, add it to the preferred list.
			if ( empty( $preferred_psp ) && ExtensionSuggestions::TYPE_PSP === $extension['_type'] ) {
				$preferred_psp = $extension;
				continue;
			}

			// If we don't have a preferred APM and the suggestion is a preferred APM, add it to the preferred list.
			// In the preferred APM slot we might surface APMs but also Express Checkouts (PayPal Wallet).
			if ( empty( $preferred_apm ) &&
				in_array( $extension['_type'], array( ExtensionSuggestions::TYPE_APM, ExtensionSuggestions::TYPE_EXPRESS_CHECKOUT ), true ) ) {

				$preferred_apm = $extension;
				continue;
			}
		}

		if ( $is_hidden &&
			ExtensionSuggestions::TYPE_APM === $extension['_type'] &&
			ExtensionSuggestions::PAYPAL_FULL_STACK === $extension['id'] ) {
			// If the PayPal Full Stack suggestion is hidden, we no longer suggest it,
			// because we have the PayPal Express Checkout (Wallet) suggestion.
			continue;
		}

		// If there are no enabled ecommerce gateways (no PSP selected),
		// we don't suggest express checkout, BNPL, or crypto extensions.
		if ( ! $has_enabled_ecommerce_gateways &&
			in_array( $extension['_type'], array( ExtensionSuggestions::TYPE_EXPRESS_CHECKOUT, ExtensionSuggestions::TYPE_BNPL, ExtensionSuggestions::TYPE_CRYPTO ), true )
		) {
			continue;
		}

		// If WooPayments or Stripe is active, we don't suggest other BNPLs.
		if ( ExtensionSuggestions::TYPE_BNPL === $extension['_type'] &&
			(
				in_array( ExtensionSuggestions::STRIPE, $active_extensions, true ) ||
				in_array( ExtensionSuggestions::WOOPAYMENTS, $active_extensions, true )
			)
		) {
			continue;
		}

		// If we made it to this point, the suggestion goes into the other list.
		// But first, make sure there isn't already an extension added to the other list with the same plugin slug.
		// This can happen if the same extension is suggested as both a PSP and an APM.
		// The first entry that we encounter is the one that we keep.
		$extension_slug   = $extension['plugin']['slug'];
		$extension_exists = array_filter(
			$other,
			function ( $suggestion ) use ( $extension_slug ) {
				return $suggestion['plugin']['slug'] === $extension_slug;
			}
		);
		if ( ! empty( $extension_exists ) ) {
			continue;
		}

		$other[] = $extension;
	}

	// Make sure that the preferred suggestions are not among the other list by removing any entries with their plugin slug.
	$other = array_values(
		array_filter(
			$other,
			function ( $suggestion ) use ( $preferred_psp, $preferred_apm ) {
				return ( empty( $preferred_psp ) || $suggestion['plugin']['slug'] !== $preferred_psp['plugin']['slug'] ) &&
						( empty( $preferred_apm ) || $suggestion['plugin']['slug'] !== $preferred_apm['plugin']['slug'] );
			}
		)
	);

	// The preferred PSP gets a recommended tag that instructs the UI to highlight it further.
	if ( ! empty( $preferred_psp ) ) {
		$preferred_psp['tags'][] = ExtensionSuggestions::TAG_RECOMMENDED;
	}

	return array(
		'preferred' => array_values(
			array_filter(
				array(
					// The PSP should naturally have a higher priority than the APM, with the preferred offline PSP last.
					// No need to impose a specific order here.
					$preferred_psp,
					$preferred_apm,
					$preferred_offline_psp,
				)
			)
		),
		'other'     => $other,
	);
}