AddressManagement.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. /**
  3. * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License").
  6. * You may not use this file except in compliance with the License.
  7. * A copy of the License is located at
  8. *
  9. * http://aws.amazon.com/apache2.0
  10. *
  11. * or in the "license" file accompanying this file. This file is distributed
  12. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  13. * express or implied. See the License for the specific language governing
  14. * permissions and limitations under the License.
  15. */
  16. namespace Amazon\Payment\Model;
  17. use Amazon\Core\Client\ClientFactoryInterface;
  18. use Amazon\Core\Domain\AmazonAddressFactory;
  19. use Amazon\Core\Exception\AmazonServiceUnavailableException;
  20. use Amazon\Payment\Api\AddressManagementInterface;
  21. use Amazon\Payment\Api\Data\QuoteLinkInterfaceFactory;
  22. use Amazon\Payment\Helper\Address;
  23. use Exception;
  24. use Magento\Checkout\Model\Session;
  25. use Magento\Directory\Model\ResourceModel\Country\CollectionFactory;
  26. use Magento\Framework\Exception\SessionException;
  27. use Magento\Framework\Validator\Exception as ValidatorException;
  28. use Magento\Framework\Validator\Factory;
  29. use Magento\Framework\Webapi\Exception as WebapiException;
  30. use Magento\Quote\Model\Quote;
  31. use AmazonPay\ResponseInterface;
  32. use Psr\Log\LoggerInterface;
  33. /**
  34. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  35. */
  36. class AddressManagement implements AddressManagementInterface
  37. {
  38. /**
  39. * @var ClientFactoryInterface
  40. */
  41. private $clientFactory;
  42. /**
  43. * @var Address
  44. */
  45. private $addressHelper;
  46. /**
  47. * @var QuoteLinkInterfaceFactory
  48. */
  49. private $quoteLinkFactory;
  50. /**
  51. * @var Session
  52. */
  53. private $session;
  54. /**
  55. * @var CollectionFactory
  56. */
  57. private $countryCollectionFactory;
  58. /**
  59. * @var AmazonAddressFactory
  60. */
  61. private $amazonAddressFactory;
  62. /**
  63. * @var Factory
  64. */
  65. private $validatorFactory;
  66. /**
  67. * @var LoggerInterface
  68. */
  69. private $logger;
  70. /**
  71. * @param ClientFactoryInterface $clientFactory
  72. * @param Address $addressHelper
  73. * @param QuoteLinkInterfaceFactory $quoteLinkFactory
  74. * @param Session $session
  75. * @param CollectionFactory $countryCollectionFactory
  76. * @param AmazonAddressFactory $amazonAddressFactory
  77. * @param Factory $validatorFactory
  78. * @param LoggerInterface $logger
  79. */
  80. public function __construct(
  81. ClientFactoryInterface $clientFactory,
  82. Address $addressHelper,
  83. QuoteLinkInterfaceFactory $quoteLinkFactory,
  84. Session $session,
  85. CollectionFactory $countryCollectionFactory,
  86. AmazonAddressFactory $amazonAddressFactory,
  87. Factory $validatorFactory,
  88. LoggerInterface $logger
  89. ) {
  90. $this->clientFactory = $clientFactory;
  91. $this->addressHelper = $addressHelper;
  92. $this->quoteLinkFactory = $quoteLinkFactory;
  93. $this->session = $session;
  94. $this->countryCollectionFactory = $countryCollectionFactory;
  95. $this->amazonAddressFactory = $amazonAddressFactory;
  96. $this->validatorFactory = $validatorFactory;
  97. $this->logger = $logger;
  98. }
  99. /**
  100. * {@inheritdoc}
  101. */
  102. public function getShippingAddress($amazonOrderReferenceId, $addressConsentToken)
  103. {
  104. try {
  105. $data = $this->getOrderReferenceDetails($amazonOrderReferenceId, $addressConsentToken);
  106. $this->updateQuoteLink($amazonOrderReferenceId);
  107. if (isset($data['OrderReferenceDetails']['Destination']['PhysicalDestination'])) {
  108. $shippingAddress = $data['OrderReferenceDetails']['Destination']['PhysicalDestination'];
  109. return $this->convertToMagentoAddress($shippingAddress, true);
  110. }
  111. throw new Exception();
  112. } catch (SessionException $e) {
  113. throw $e;
  114. } catch (WebapiException $e) {
  115. throw $e;
  116. } catch (ValidatorException $e) {
  117. throw $e;
  118. } catch (Exception $e) {
  119. $this->logger->error($e);
  120. $this->throwUnknownErrorException();
  121. }
  122. }
  123. /**
  124. * {@inheritdoc}
  125. */
  126. public function getBillingAddress($amazonOrderReferenceId, $addressConsentToken)
  127. {
  128. try {
  129. $data = $this->getOrderReferenceDetails($amazonOrderReferenceId, $addressConsentToken);
  130. $this->updateQuoteLink($amazonOrderReferenceId);
  131. if (isset($data['OrderReferenceDetails']['BillingAddress']['PhysicalAddress'])) {
  132. $billingAddress = $data['OrderReferenceDetails']['BillingAddress']['PhysicalAddress'];
  133. if (!isset($billingAddress['Phone']) || !$billingAddress['Phone']) {
  134. $billingAddress['Phone'] = '000-000-0000';
  135. }
  136. return $this->convertToMagentoAddress($billingAddress);
  137. } elseif (isset($data['OrderReferenceDetails']['Destination']['PhysicalDestination'])) {
  138. $billingAddress = $data['OrderReferenceDetails']['Destination']['PhysicalDestination'];
  139. return $this->convertToMagentoAddress($billingAddress);
  140. }
  141. throw new Exception();
  142. } catch (WebapiException $e) {
  143. throw $e;
  144. } catch (Exception $e) {
  145. $this->throwUnknownErrorException();
  146. }
  147. }
  148. protected function throwUnknownErrorException()
  149. {
  150. throw new WebapiException(
  151. __('Amazon could not process your request.'),
  152. 0,
  153. WebapiException::HTTP_INTERNAL_ERROR
  154. );
  155. }
  156. protected function convertToMagentoAddress(array $address, $isShippingAddress = false)
  157. {
  158. $amazonAddress = $this->amazonAddressFactory->create(['address' => $address]);
  159. $magentoAddress = $this->addressHelper->convertToMagentoEntity($amazonAddress);
  160. if ($isShippingAddress) {
  161. $validator = $this->validatorFactory->createValidator('amazon_address', 'on_select');
  162. if (! $validator->isValid($magentoAddress)) {
  163. throw new ValidatorException(null, null, [$validator->getMessages()]);
  164. }
  165. $countryCollection = $this->countryCollectionFactory->create();
  166. $collectionSize = $countryCollection->loadByStore()
  167. ->addFieldToFilter('country_id', ['eq' => $magentoAddress->getCountryId()])
  168. ->setPageSize(1)
  169. ->setCurPage(1)
  170. ->getSize();
  171. if (1 != $collectionSize) {
  172. throw new WebapiException(__('the country for your address is not allowed for this store'));
  173. }
  174. }
  175. return [$this->addressHelper->convertToArray($magentoAddress)];
  176. }
  177. protected function getOrderReferenceDetails($amazonOrderReferenceId, $addressConsentToken)
  178. {
  179. $client = $this->clientFactory->create();
  180. /**
  181. * @var ResponseInterface $response
  182. */
  183. $response = $client->getOrderReferenceDetails(
  184. [
  185. 'amazon_order_reference_id' => $amazonOrderReferenceId,
  186. 'address_consent_token' => $addressConsentToken
  187. ]
  188. );
  189. $data = $response->toArray();
  190. if (200 != $data['ResponseStatus'] || ! isset($data['GetOrderReferenceDetailsResult'])) {
  191. throw new AmazonServiceUnavailableException();
  192. }
  193. return $data['GetOrderReferenceDetailsResult'];
  194. }
  195. protected function updateQuoteLink($amazonOrderReferenceId)
  196. {
  197. $quote = $this->session->getQuote();
  198. if (! $quote->getId()) {
  199. throw new SessionException(__('Your session has expired, please reload the page and try again.'));
  200. }
  201. $quoteLink = $this->quoteLinkFactory->create()->load($quote->getId(), 'quote_id');
  202. if ($quoteLink->getAmazonOrderReferenceId() != $amazonOrderReferenceId) {
  203. $quoteLink
  204. ->setAmazonOrderReferenceId($amazonOrderReferenceId)
  205. ->setQuoteId($quote->getId())
  206. ->setConfirmed(false)
  207. ->save();
  208. }
  209. }
  210. }