IntegrationsManager.php 5.05 KB
Newer Older
Ketan's avatar
Ketan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Magento\InstantPurchase\PaymentMethodIntegration;

use Magento\Framework\Exception\LocalizedException;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Vault\Api\Data\PaymentTokenInterface;
use Magento\Vault\Model\PaymentMethodList;
use Magento\Vault\Model\VaultPaymentInterface;

/**
 * Payment method integrations management.
 *
 * Avoid usage of methods for automatic store detection if possible.
 */
class IntegrationsManager
{
    /**
     * @var PaymentMethodList
     */
    private $paymentMethodList;

    /**
     * @var IntegrationFactory
     */
    private $integrationFactory;

    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var array
     */
    private $integrations;

    /**
     * IntegrationsManager constructor.
     * @param PaymentMethodList $paymentMethodList
     * @param IntegrationFactory $integrationFactory
     * @param StoreManagerInterface $storeManager
     */
    public function __construct(
        PaymentMethodList $paymentMethodList,
        IntegrationFactory $integrationFactory,
        StoreManagerInterface $storeManager
    ) {
        $this->paymentMethodList = $paymentMethodList;
        $this->integrationFactory = $integrationFactory;
        $this->storeManager = $storeManager;
        $this->integrations = [];
    }

    /**
     * Provides list of implemented integrations.
     *
     * @param int $storeId
     * @return array
     */
    public function getList(int $storeId): array
    {
        if (!isset($this->integrations[$storeId])) {
            $this->integrations[$storeId] = $this->findIntegrations($storeId);
        }
        return $this->integrations[$storeId];
    }

    /**
     * Determines integration that may be used with token.
     *
     * @param PaymentTokenInterface $paymentToken
     * @param int $storeId
     * @return Integration
     * @throws LocalizedException if integration is not implemented.
     */
    public function getByToken(PaymentTokenInterface $paymentToken, int $storeId): Integration
    {
        foreach ($this->getList($storeId) as $integration) {
            if ($integration->getVaultProviderCode() === $paymentToken->getPaymentMethodCode()) {
                return $integration;
            }
        }
        throw new LocalizedException(__('Instant purchase integration not available for token.'));
    }

    /**
     * Provides list of implemented integrations with store detection.
     * This method rely on global state. Use getList if possible.
     *
     * @return array
     */
    public function getListForCurrentStore(): array
    {
        return $this->getList($this->storeManager->getStore()->getId());
    }

    /**
     * Determines integration that may be used with token with store detection.
     * This method rely on global state. Use getByToken if possible.
     *
     * @param PaymentTokenInterface $paymentToken
     * @return Integration
     * @throws LocalizedException if integration is not implemented.
     */
    public function getByTokenForCurrentStore(PaymentTokenInterface $paymentToken): Integration
    {
        return $this->getByToken($paymentToken, $this->storeManager->getStore()->getId());
    }

    /**
     * Find implemented integrations for active vault payment methods.
     *
     * @param int $storeId
     * @return array
     */
    private function findIntegrations(int $storeId): array
    {
        $integrations = [];
        foreach ($this->paymentMethodList->getActiveList($storeId) as $paymentMethod) {
            if ($this->isIntegrationAvailable($paymentMethod, $storeId)) {
                $integrations[] = $this->integrationFactory->create($paymentMethod, $storeId);
            }
        }
        return $integrations;
    }

    /**
     * Checks if integration implemented for vault payment method.
     *
     * Implemented integration is if it configured in payment config:
     * 1. Basic integration (not recommended):
     *    <instant_purchase>
     *      <supported>1</supported>
     *    </instant_purchase>
     * 2. Customized integration (at least one option is required):
     *    <instant_purchase>
     *       <available>Implementation_Of_AvailabilityCheckerInterface</available>
     *       <tokenFormat>Implementation_Of_PaymentTokenFormatterInterface</tokenFormat>
     *       <additionalInformation>
     *           Implementation_Of_PaymentAdditionalInformationProviderInterface
     *       </additionalInformation>
     *    </instant_purchase>
     *
     * @param VaultPaymentInterface $paymentMethod
     * @param int|string|null|\Magento\Store\Model\Store $storeId
     * @return bool
     */
    private function isIntegrationAvailable(VaultPaymentInterface $paymentMethod, $storeId): bool
    {
        $data = $paymentMethod->getConfigData('instant_purchase', $storeId);
        if (!is_array($data)) {
            return false;
        }
        if (isset($data['supported']) && $data['supported'] !== '1') {
            return false;
        }
        return true;
    }
}