app/Plugin/PayPalCheckout42/Service/PayPalAcdcService.php line 70

Open in your IDE?
  1. <?php
  2. namespace Plugin\PayPalCheckout42\Service;
  3. use Plugin\PayPalCheckout42\Contracts\GenerateClientTokenResponse;
  4. use Plugin\PayPalCheckout42\Contracts\GeneratePaymentTokenResponse;
  5. use Plugin\PayPalCheckout42\Entity\Config;
  6. use Plugin\PayPalCheckout42\Exception\PayPalCheckoutException;
  7. use Plugin\PayPalCheckout42\Repository\ConfigRepository;
  8. use Plugin\PayPalCheckout42\Util\StringUtil;
  9. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  10. /**
  11.  * Class PayPalAcdcService
  12.  * @package Plugin\PayPalCheckout42\Service
  13.  */
  14. class PayPalAcdcService
  15. {
  16.     /**
  17.      * @var SessionInterface
  18.      */
  19.     private $session;
  20.     /**
  21.      * @var PayPalAcdcRequestService
  22.      */
  23.     private $client;
  24.     /**
  25.      * @var LoginService
  26.      */
  27.     private $loginService;
  28.     /**
  29.      * @var Logger
  30.      */
  31.     private $logger;
  32.     /**
  33.      * @var Config
  34.      */
  35.     private $config;
  36.     /**
  37.      * @var StringUtil
  38.      */
  39.     private $stringUtil;
  40.     /**
  41.      * PayPalService constructor.
  42.      * @param SessionInterface $session
  43.      * @param PayPalAcdcRequestService $PayPalAcdcRequestService
  44.      * @param LoginService $loginService
  45.      * @param LoggerService $loggerService
  46.      * @param ConfigRepository $configRepository
  47.      * @param StringUtil $stringUtil
  48.      */
  49.     public function __construct(
  50.         SessionInterface $session,
  51.         PayPalAcdcRequestService $PayPalAcdcRequestService,
  52.         LoginService $loginService,
  53.         LoggerService $loggerService,
  54.         ConfigRepository $configRepository,
  55.         StringUtil $stringUtil
  56.     ) {
  57.         $this->session $session;
  58.         $this->config $configRepository->get();
  59.         $this->client $PayPalAcdcRequestService;
  60.         $isSandbox $this->config->getUseSandbox();
  61.         $this->client->setEnv($this->config->getClientId(), $this->config->getClientSecret(), $isSandbox);
  62.         $this->loginService $loginService;
  63.         $this->logger $loggerService;
  64.         $this->stringUtil $stringUtil;
  65.     }
  66.     /**
  67.      * @return bool
  68.      */
  69.     public function isDebug(): bool
  70.     {
  71.         return $this->eccubeConfig->get('paypal.debug') ?? false;
  72.     }
  73.     /**
  74.      * vaultが利用できるか否かを返す
  75.      *
  76.      * @return bool
  77.      */
  78.     public function canUseVault(): bool
  79.     {
  80.         return $this->config->getUseVault() && $this->loginService->isLoginUser();
  81.     }
  82.     /**
  83.      * @param string $vaultId
  84.      */
  85.     public function setVaultIdToSession(string $vaultId): void
  86.     {
  87.         $this->session->set('createOrderRequest.vaultId'$vaultId);
  88.     }
  89.     /**
  90.      * @return string $vaultId
  91.      */
  92.     public function getVaultIdFromSession(): string
  93.     {
  94.         return $this->session->get('createOrderRequest.vaultId''');
  95.     }
  96.     /**
  97.      * vault id を取り出して消す
  98.      *
  99.      * @return string
  100.      */
  101.     public function extractVaultIdFromSession(): string
  102.     {
  103.         $vaultId $this->session->get('createOrderRequest.vaultId''');
  104.         $this->session->remove('createOrderRequest.vaultId');
  105.         return $vaultId;
  106.     }
  107.     /**
  108.      * vault に保存するか否かを保存する
  109.      *
  110.      * @param string $saveVault
  111.      */
  112.     public function setSaveVaultToSession(string $saveVault): void
  113.     {
  114.         $this->session->set('createOrderRequest.saveVault'$saveVault === '1');
  115.     }
  116.     /**
  117.      * FraudNetで使用する、セッション毎のIDを生成し保存する
  118.      *
  119.      * @return string
  120.      */
  121.     public function createAndSaveFraudNetSessionIdentifierToSession(): string
  122.     {
  123.         $identifier $this->stringUtil::createRandomString(30);
  124.         $this->session->set('createOrderRequest.fraudNetSessionIdentifier'$identifier);
  125.         return $identifier;
  126.     }
  127.     /**
  128.      * FraudNetで使用する、セッション毎のIDを取得し削除する
  129.      *
  130.      * @return string
  131.      */
  132.     public function extractFraudNetSessionIdentifierFromSession(): string
  133.     {
  134.         $identifier $this->session->get('createOrderRequest.fraudNetSessionIdentifier'false);
  135.         $this->session->remove('createOrderRequest.fraudNetSessionIdentifier');
  136.         return $identifier;
  137.     }
  138.     /**
  139.      * FraudNetで使用する、サイトごとに一意のIDを取得する
  140.      *
  141.      * @return string
  142.      */
  143.     public function getSourceWebsiteIdentifier(): string
  144.     {
  145.         // 「ECCUBE_クライアントIDの先頭13文字_BA」のルールで生成
  146.         $clientId substr($this->config->getClientId(), 013);
  147.         return "ECCUBE_${clientId}_BA";
  148.     }
  149.     /**
  150.      * vault を保存するか否かを取り出して消す
  151.      *
  152.      * @return bool
  153.      */
  154.     public function extractSaveVaultFromSession(): bool
  155.     {
  156.         $saveVault $this->session->get('createOrderRequest.saveVault'false);
  157.         $this->session->remove('createOrderRequest.saveVault');
  158.         return $saveVault;
  159.     }
  160.     /**
  161.      * 現在存在する vault を一括削除します
  162.      */
  163.     public function bulkDeleteExistingVault(): void
  164.     {
  165.         $vaults $this->getVaults();
  166.         if (count($vaults) === 0) {
  167.             return;
  168.         }
  169.         // 全て消し切るまで削除を繰り返す
  170.         $retryCount 3;
  171.         $i 0;
  172.         do {
  173.             foreach ($vaults as $vault) {
  174.                 $this->deleteVaultFromId($vault['id']);
  175.             }
  176.             $vaults $this->getVaults();
  177.             if (count($vaults) === 0) {
  178.                 break;
  179.             }
  180.             $i++;
  181.         } while ($i $retryCount);
  182.         // リトライ回数すべて失敗した場合にエラー
  183.         if ($i >= $retryCount) {
  184.             throw new PayPalCheckoutException('vault の削除に失敗しました');
  185.         }
  186.     }
  187.     /**
  188.      * 指定の vault id のデータを削除します
  189.      *
  190.      * @param $vaultId
  191.      * @return bool
  192.      * @throws PayPalCheckoutException
  193.      * @throws \Plugin\PayPalCheckout42\Exception\PayPalRequestException
  194.      */
  195.     public function deleteVaultFromId($vaultId): bool
  196.     {
  197.         $request $this->client->prepareDeleteVault($vaultId);
  198.         return $this->client->deleteVault($request);
  199.     }
  200.     /**
  201.      * クライアントトークンを取得する
  202.      *
  203.      * @param string $useVault vaultを利用するか否か
  204.      * @return string
  205.      * @throws \Plugin\PayPalCheckout42\Exception\PayPalRequestException
  206.      */
  207.     public function getClientToken($useVault false): string
  208.     {
  209.         $customerId null;
  210.         if ($useVault && $this->canUseVault()) {
  211.             $customerId $this->generateCustomerIdForVault();
  212.         }
  213.         $request $this->client->prepareClientToken($customerId);
  214.         /** @var GenerateClientTokenResponse $response */
  215.         $response $this->client->getClientToken($request);
  216.         return $response->getClientToken();
  217.     }
  218.     /**
  219.      * @return ?array
  220.      * @throws \Plugin\PayPalCheckout42\Exception\PayPalRequestException
  221.      */
  222.     public function getVaults(): array
  223.     {
  224.         if (!$this->canUseVault()) {
  225.             return [];
  226.         }
  227.         $customerId $this->generateCustomerIdForVault();
  228.         $request $this->client->preparePaymentToken($customerId);
  229.         /** @var GeneratePaymentTokenResponse $response */
  230.         $response $this->client->getPaymentToken($request);
  231.         $paymentTokens $response->getPaymentTokens();
  232.         return json_decode(json_encode($paymentTokens), true);
  233.     }
  234.     /**
  235.      * vault 利用のための顧客IDを生成する
  236.      *
  237.      * 顧客IDは複数サイトで一意となる必要がある(PayPalのクライアンドIDが使いまわされる可能性があるため)。
  238.      * サイト一意の文字列 + 顧客一意の文字列 をキーとする。
  239.      *
  240.      * サイト一意の文字列:ECCUBE_AUTH_MAGIC
  241.      *     ドメイン名やIPアドレスは変更される可能性があるため、 site_unique_key を利用する。
  242.      *     文字数制限的にここの文字列が多すぎると顧客IDの数を圧迫してしまうが、12文字までにすることで10億の顧客まで対応できるため問題ないと考える。
  243.      * 顧客一意の文字列:customer_id
  244.      *     メールアドレスや電話番号は変更される可能性があるため、サイト内で一意となる customer_id を使う。
  245.      *
  246.      * @return string|null
  247.      */
  248.     private function generateCustomerIdForVault()
  249.     {
  250.         $customer $this->loginService->getCustomer();
  251.         $customerId $customer->getId() ?? null;
  252.         if (empty($customerId)) {
  253.             return null;
  254.         }
  255.         $siteUniqueKey substr($this->config->getSiteUniqueKey(), 012);
  256.         return $siteUniqueKey.$customerId;
  257.     }
  258. }