PageRenderTime 259ms CodeModel.GetById 23ms RepoModel.GetById 3ms app.codeStats 0ms

/vendor/magento/module-braintree/Model/Vault.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 394 lines | 248 code | 30 blank | 116 comment | 34 complexity | 7026f61d4908e84874a1a9ad09549de6 MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Braintree\Model;
  7. use Magento\Braintree\Model\Adapter\BraintreeCreditCard;
  8. use Magento\Braintree\Model\Adapter\BraintreePaymentMethod;
  9. use \Braintree_Exception;
  10. use Magento\Braintree\Model\Adapter\BraintreeCustomer;
  11. use Magento\Framework\Exception\LocalizedException;
  12. /**
  13. * Class Vault
  14. *
  15. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  16. */
  17. class Vault
  18. {
  19. const CACHE_KEY_CREDIT_CARDS = 'braintree_cc';
  20. /**
  21. * @var \Magento\Braintree\Helper\Data
  22. */
  23. protected $braintreeHelper;
  24. /**
  25. * @var \Magento\Braintree\Helper\Error
  26. */
  27. protected $errorHelper;
  28. /**
  29. * @var \Magento\Customer\Model\Session
  30. */
  31. protected $customerSession;
  32. /**
  33. * @var \Magento\Customer\Model\CustomerFactory
  34. */
  35. protected $customerFactory;
  36. /**
  37. * @var \Magento\Directory\Model\ResourceModel\Country\CollectionFactory
  38. */
  39. protected $countryFactory;
  40. /**
  41. * @var \Magento\Framework\App\Cache\Type\Collection
  42. */
  43. protected $cache;
  44. /**
  45. * @var \Magento\Braintree\Model\Config\Cc
  46. */
  47. protected $config;
  48. /**
  49. * @var \Psr\Log\LoggerInterface
  50. */
  51. protected $logger;
  52. /**
  53. * @var BraintreeCustomer
  54. */
  55. protected $braintreeCustomer;
  56. /**
  57. * @var BraintreeCreditCard
  58. */
  59. protected $braintreeCreditCard;
  60. /**
  61. * @var BraintreePaymentMethod
  62. */
  63. protected $braintreePaymentMethod;
  64. /**
  65. * @param \Magento\Braintree\Helper\Data $braintreeHelper
  66. * @param \Magento\Braintree\Model\Config\Cc $config
  67. * @param \Psr\Log\LoggerInterface $logger
  68. * @param \Magento\Braintree\Helper\Error $errorHelper
  69. * @param \Magento\Framework\App\Cache\Type\Collection $cache
  70. * @param \Magento\Customer\Model\Session $customerSession
  71. * @param \Magento\Customer\Model\CustomerFactory $customerFactory
  72. * @param BraintreeCustomer $braintreeCustomer
  73. * @param BraintreeCreditCard $braintreeCreditCard
  74. * @param BraintreePaymentMethod $braintreePaymentMethod
  75. * @param \Magento\Directory\Model\ResourceModel\Country\CollectionFactory $countryFactory
  76. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  77. */
  78. public function __construct(
  79. \Magento\Braintree\Helper\Data $braintreeHelper,
  80. \Magento\Braintree\Model\Config\Cc $config,
  81. \Psr\Log\LoggerInterface $logger,
  82. \Magento\Braintree\Helper\Error $errorHelper,
  83. \Magento\Framework\App\Cache\Type\Collection $cache,
  84. \Magento\Customer\Model\Session $customerSession,
  85. \Magento\Customer\Model\CustomerFactory $customerFactory,
  86. BraintreeCustomer $braintreeCustomer,
  87. BraintreeCreditCard $braintreeCreditCard,
  88. BraintreePaymentMethod $braintreePaymentMethod,
  89. \Magento\Directory\Model\ResourceModel\Country\CollectionFactory $countryFactory
  90. ) {
  91. $this->config = $config;
  92. $this->braintreeHelper = $braintreeHelper;
  93. $this->logger = $logger;
  94. $this->errorHelper = $errorHelper;
  95. $this->cache = $cache;
  96. $this->customerSession = $customerSession;
  97. $this->customerFactory = $customerFactory;
  98. $this->braintreeCustomer = $braintreeCustomer;
  99. $this->braintreeCreditCard = $braintreeCreditCard;
  100. $this->braintreePaymentMethod = $braintreePaymentMethod;
  101. $this->countryFactory = $countryFactory;
  102. }
  103. /**
  104. * Array of customer credit cards
  105. *
  106. * @return array
  107. */
  108. public function currentCustomerStoredCards()
  109. {
  110. if ($this->config->useVault() && $this->customerSession->isLoggedIn()) {
  111. $customer = $this->customerFactory->create()->load($this->customerSession->getCustomerId());
  112. $customerId = $this->braintreeHelper->generateCustomerId(
  113. $this->customerSession->getCustomerId(),
  114. $customer->getEmail()
  115. );
  116. try {
  117. $ret = $this->braintreeCustomer->find($customerId)->creditCards;
  118. $this->debug($customerId);
  119. $this->debug($ret);
  120. return $ret;
  121. } catch (\Braintree_Exception $e) {
  122. return [];
  123. }
  124. }
  125. return [];
  126. }
  127. /**
  128. * Returns stored card by token
  129. *
  130. * @param string $token
  131. * @return \Braintree_CreditCard|null
  132. */
  133. public function storedCard($token)
  134. {
  135. try {
  136. $ret = $this->braintreeCreditCard->find($token);
  137. $this->debug($token);
  138. $this->debug($ret);
  139. return $ret;
  140. } catch (\Braintree_Exception $e) {
  141. $this->logger->critical($e);
  142. }
  143. return null;
  144. }
  145. /**
  146. * @param string $last4
  147. * @return bool
  148. */
  149. public function canSaveCard($last4)
  150. {
  151. if (!isset($last4) || !preg_match("/[0-9]{4}/", $last4)) {
  152. return false;
  153. }
  154. if (!$this->config->allowDuplicateCards()) {
  155. $storedCards = $this->currentCustomerStoredCards();
  156. if (is_array($storedCards)) {
  157. foreach ($storedCards as $card) {
  158. if ($card->last4 == $last4) {
  159. return false;
  160. }
  161. }
  162. }
  163. }
  164. return true;
  165. }
  166. /**
  167. * Deletes customer
  168. *
  169. * @param int $customerID
  170. * @return $this
  171. */
  172. public function deleteCustomer($customerID)
  173. {
  174. try {
  175. $this->braintreeCustomer->delete($customerID);
  176. } catch (\Braintree_Exception $e) {
  177. $this->logger->critical($e);
  178. }
  179. return $this;
  180. }
  181. /**
  182. * Delete card by token
  183. *
  184. * @param string $token
  185. * @return \Braintree_CreditCard|bool
  186. */
  187. public function deleteCard($token)
  188. {
  189. try {
  190. $ret = $this->braintreeCreditCard->delete($token);
  191. $this->debug($token);
  192. $this->debug($ret);
  193. return $ret;
  194. } catch (\Braintree_Exception $e) {
  195. $this->logger->critical($e);
  196. return false;
  197. }
  198. }
  199. /**
  200. * If customer exists in Braintree
  201. *
  202. * @param int $customerId
  203. * @return bool
  204. */
  205. public function exists($customerId)
  206. {
  207. try {
  208. $this->braintreeCustomer->find($customerId);
  209. } catch (\Braintree_Exception $e) {
  210. $this->logger->critical($e);
  211. return false;
  212. }
  213. return true;
  214. }
  215. /**
  216. * Gets response from braintree api using the nonce
  217. *
  218. * @param string|null $nonce
  219. * @param array|null $options
  220. * @param array|null $billingAddress
  221. * @return $this
  222. * @throws LocalizedException
  223. * @SuppressWarnings(PHPMD.NPathComplexity)
  224. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  225. */
  226. public function processNonce($nonce = null, $options = null, $billingAddress = null)
  227. {
  228. $customerId = $this->customerSession->getCustomerId();
  229. if (!$customerId) {
  230. throw new LocalizedException(__('Invalid Customer ID provided'));
  231. }
  232. $billingCountry = null;
  233. if (is_array($billingAddress)) {
  234. $collection = $this->countryFactory->create()->addCountryCodeFilter($billingAddress['countryCodeAlpha2']);
  235. if ($collection->getSize()) {
  236. $billingCountry = $collection->getFirstItem()->getId();
  237. }
  238. if (!$this->config->canUseForCountry($billingCountry)) {
  239. throw new LocalizedException(__('Selected payment type is not allowed for billing country.'));
  240. }
  241. }
  242. $ccType = null;
  243. if ($options) {
  244. $ccType = $options['ccType'];
  245. }
  246. if ($ccType) {
  247. $error = $this->config->canUseCcTypeForCountry($billingCountry, $ccType);
  248. if ($error) {
  249. throw new LocalizedException($error);
  250. }
  251. }
  252. $customer = $this->customerFactory->create()->load($customerId);
  253. $customerId = $this->braintreeHelper->generateCustomerId($customerId, $customer->getEmail());
  254. if (!$this->exists($customerId)) {
  255. $customerRequest = [
  256. 'id' => $customerId,
  257. 'firstName' => $billingAddress['firstName'],
  258. 'lastName' => $billingAddress['lastName'],
  259. 'email' => $this->customerSession->getCustomerDataObject()->getEmail(),
  260. ];
  261. if (strlen($billingAddress['company'])) {
  262. $customerRequest['company'] = $billingAddress['company'];
  263. }
  264. $result = $this->braintreeCustomer->create($customerRequest);
  265. if (!$result->success) {
  266. throw new LocalizedException($this->errorHelper->parseBraintreeError($result));
  267. }
  268. }
  269. //check if customerId is created on braintree
  270. $requestArray = [
  271. 'customerId' => $customerId,
  272. 'paymentMethodNonce' => $nonce,
  273. 'options' => [
  274. 'makeDefault' => ( $options['default'] == 'true') ? true : false,
  275. 'failOnDuplicatePaymentMethod' => $this->config->allowDuplicateCards() == '1' ? false : true,
  276. 'verifyCard' => $this->config->useCvv() == '1' ? true : false,
  277. ],
  278. ];
  279. if ($this->config->isFraudDetectionEnabled() &&
  280. strlen($options['device_data'])>0) {
  281. $requestArray['deviceData'] = $options['device_data'];
  282. }
  283. if ($options['update'] == 'true') {
  284. $token = $options['token'];
  285. unset($requestArray['customerId']);
  286. unset($requestArray['options']['failOnDuplicatePaymentMethod']);
  287. $requestArray['billingAddress'] = $billingAddress;
  288. $result = $this->braintreePaymentMethod->update($token, $requestArray);
  289. $this->debug($requestArray);
  290. $this->debug($result);
  291. } else {
  292. $result = $this->braintreePaymentMethod->create($requestArray);
  293. $this->debug($requestArray);
  294. $this->debug($result);
  295. }
  296. if (!$result->success) {
  297. throw new LocalizedException($this->errorHelper->parseBraintreeError($result));
  298. }
  299. return $this;
  300. }
  301. /**
  302. * Log debug data to file
  303. *
  304. * @param mixed $debugData
  305. * @return $this
  306. */
  307. protected function debug($debugData)
  308. {
  309. if ($this->config->isDebugEnabled() && !empty($debugData)) {
  310. $this->logger->debug(var_export($debugData, true));
  311. }
  312. return $this;
  313. }
  314. /**
  315. * @param string $token
  316. * @return bool|string
  317. */
  318. public function getSavedCardType($token)
  319. {
  320. $ccType = false;
  321. $useCache = $this->config->useVault();
  322. $cachedValues = $useCache ? $this->cache->load(self::CACHE_KEY_CREDIT_CARDS) : false;
  323. if ($cachedValues) {
  324. try {
  325. $cachedValues = unserialize($cachedValues);
  326. } catch (\Exception $e) {
  327. $cachedValues = [];
  328. }
  329. if (array_key_exists($token, $cachedValues)) {
  330. return $cachedValues[$token];
  331. }
  332. }
  333. try {
  334. $creditCard = $this->braintreeCreditCard->find($token);
  335. $this->debug($token);
  336. $this->debug($creditCard);
  337. $ccType = $this->braintreeHelper->getCcTypeCodeByName($creditCard->cardType);
  338. if (!empty($cachedValues)) {
  339. $cachedValues = array_merge($cachedValues, [$token => $ccType]);
  340. } else {
  341. $cachedValues = [$token => $ccType];
  342. }
  343. if ($useCache) {
  344. $this->cache->save(serialize($cachedValues), self::CACHE_KEY_CREDIT_CARDS);
  345. }
  346. } catch (\Exception $e) {
  347. $this->logger->critical($e);
  348. }
  349. return $ccType;
  350. }
  351. /**
  352. * @param string $token
  353. * @throws LocalizedException
  354. * @return bool|string
  355. */
  356. public function generatePaymentMethodToken($token)
  357. {
  358. $result = $this->braintreePaymentMethod->createNonce($token);
  359. if (!$result->success) {
  360. throw new LocalizedException($this->errorHelper->parseBraintreeError($result));
  361. }
  362. return $result->paymentMethodNonce->nonce;
  363. }
  364. }