Files
2026-04-28 15:13:50 +02:00

181 lines
5.6 KiB
PHP

<?php
/**
* Payment method definition registry.
*
* @package WCPay\PaymentMethods\Configs\Registry
*/
namespace WCPay\PaymentMethods\Configs\Registry;
use WCPay\PaymentMethods\Configs\Definitions\AffirmDefinition;
use WCPay\PaymentMethods\Configs\Definitions\AfterpayDefinition;
use WCPay\PaymentMethods\Configs\Definitions\CardDefinition;
use WCPay\PaymentMethods\Configs\Definitions\AlipayDefinition;
use WCPay\PaymentMethods\Configs\Definitions\AmazonPayDefinition;
use WCPay\PaymentMethods\Configs\Definitions\ApplePayDefinition;
use WCPay\PaymentMethods\Configs\Definitions\BancontactDefinition;
use WCPay\PaymentMethods\Configs\Definitions\BecsDefinition;
use WCPay\PaymentMethods\Configs\Definitions\EpsDefinition;
use WCPay\PaymentMethods\Configs\Definitions\GiropayDefinition;
use WCPay\PaymentMethods\Configs\Definitions\GooglePayDefinition;
use WCPay\PaymentMethods\Configs\Definitions\GrabPayDefinition;
use WCPay\PaymentMethods\Configs\Definitions\IdealDefinition;
use WCPay\PaymentMethods\Configs\Definitions\KlarnaDefinition;
use WCPay\PaymentMethods\Configs\Definitions\LinkDefinition;
use WCPay\PaymentMethods\Configs\Definitions\MultibancoDefinition;
use WCPay\PaymentMethods\Configs\Definitions\P24Definition;
use WCPay\PaymentMethods\Configs\Definitions\SepaDefinition;
use WCPay\PaymentMethods\Configs\Definitions\SofortDefinition;
use WCPay\PaymentMethods\Configs\Definitions\WechatPayDefinition;
use WCPay\PaymentMethods\Configs\Interfaces\PaymentMethodDefinitionInterface;
/**
* Registry for payment method definitions.
*/
class PaymentMethodDefinitionRegistry {
/**
* Singleton instance.
*
* @var PaymentMethodDefinitionRegistry|null
*/
private static $instance = null;
/**
* List of all available payment method definitions.
*
* @var array<class-string<PaymentMethodDefinitionInterface>>
*/
private $available_definitions = [
// Add new payment method definitions here.
CardDefinition::class,
AffirmDefinition::class,
AfterpayDefinition::class,
AlipayDefinition::class,
BancontactDefinition::class,
BecsDefinition::class,
EpsDefinition::class,
GiropayDefinition::class,
GrabPayDefinition::class,
IdealDefinition::class,
LinkDefinition::class,
MultibancoDefinition::class,
KlarnaDefinition::class,
P24Definition::class,
SepaDefinition::class,
SofortDefinition::class,
WechatPayDefinition::class,
ApplePayDefinition::class,
GooglePayDefinition::class,
];
/**
* Payment method definitions that have been registered for use.
*
* @var array<string,class-string<PaymentMethodDefinitionInterface>>
*/
private $payment_methods = [];
/**
* Constructor is private to enforce singleton pattern.
*/
private function __construct() {}
/**
* Get the singleton instance.
*
* @return PaymentMethodDefinitionRegistry
*/
public static function instance(): self {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Initialize the registry by registering all available payment method definitions.
*
* @return void
*/
public function init(): void {
foreach ( $this->available_definitions as $definition ) {
$this->register_payment_method( $definition );
}
// When Amazon Pay is promoted from feature flag, we can register it directly in the `available_definitions` array.
if ( \WC_Payments_Features::is_amazon_pay_enabled() ) {
$this->register_payment_method( AmazonPayDefinition::class );
}
}
/**
* Get all available payment method definitions.
*
* @return array<class-string<PaymentMethodDefinitionInterface>> Array of payment method definition class names.
*/
public function get_available_definitions(): array {
return $this->available_definitions;
}
/**
* Register a payment method definition.
*
* @param class-string<PaymentMethodDefinitionInterface> $definition_class The payment method definition class to register.
* @throws \InvalidArgumentException If the class does not exist or does not implement PaymentMethodDefinitionInterface.
*/
public function register_payment_method( $definition_class ): void {
if ( ! class_exists( $definition_class ) ) {
throw new \InvalidArgumentException(
sprintf(
'Payment method definition class "%s" does not exist.',
$definition_class
)
);
}
$interfaces = class_implements( $definition_class );
if ( ! isset( $interfaces[ PaymentMethodDefinitionInterface::class ] ) ) {
throw new \InvalidArgumentException(
sprintf(
'Payment method definition class "%s" must implement %s.',
$definition_class,
PaymentMethodDefinitionInterface::class
)
);
}
/**
* Ensure type safety for the payment method definition class.
*
* @var class-string<PaymentMethodDefinitionInterface> $definition_class
*/
$this->payment_methods[ $definition_class::get_id() ] = $definition_class;
}
/**
* Get all registered payment method definitions.
*
* @return class-string<PaymentMethodDefinitionInterface>[] All registered payment method definition classes.
*/
public function get_all_payment_method_definitions(): array {
return $this->payment_methods;
}
/**
* Get all available payment method definitions for a given account and currency.
*
* @param string $account_country The account country.
* @param string $currency The currency.
* @return string[] All available payment method definition classes.
*/
public function get_available_payment_method_definitions( string $account_country, string $currency ): array {
return array_filter(
$this->payment_methods,
function ( $definition_class ) use ( $account_country, $currency ) {
return $definition_class::is_available_for( $currency, $account_country );
}
);
}
}