123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- declare(strict_types=1);
- namespace Magento\Sales\Model\Service;
- use Magento\Backend\App\Area\FrontNameResolver;
- use Magento\Framework\App\Config\ScopeConfigInterface;
- use Magento\Framework\App\ObjectManager;
- use Magento\Framework\Mail\Template\TransportBuilder;
- use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
- use Magento\Framework\Translate\Inline\StateInterface;
- use Magento\Quote\Api\CartRepositoryInterface;
- use Magento\Quote\Api\Data\CartInterface as Quote;
- use Magento\Sales\Api\PaymentFailuresInterface;
- use Magento\Store\Model\ScopeInterface;
- use Magento\Store\Model\Store;
- use Psr\Log\LoggerInterface;
- /**
- * Service is responsible for handling failed payment transactions.
- *
- * It depends on Stores > Configuration > Sales > Checkout > Payment Failed Emails configuration.
- *
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class PaymentFailuresService implements PaymentFailuresInterface
- {
- /**
- * Store config
- *
- * @var ScopeConfigInterface
- */
- private $scopeConfig;
- /**
- * @var StateInterface
- */
- private $inlineTranslation;
- /**
- * @var TransportBuilder
- */
- private $transportBuilder;
- /**
- * @var TimezoneInterface
- */
- private $localeDate;
- /**
- * @var CartRepositoryInterface
- */
- private $cartRepository;
- /**
- * @var LoggerInterface
- */
- private $logger;
- /**
- * @param ScopeConfigInterface $scopeConfig
- * @param StateInterface $inlineTranslation
- * @param TransportBuilder $transportBuilder
- * @param TimezoneInterface $localeDate
- * @param CartRepositoryInterface $cartRepository
- * @param LoggerInterface|null $logger
- */
- public function __construct(
- ScopeConfigInterface $scopeConfig,
- StateInterface $inlineTranslation,
- TransportBuilder $transportBuilder,
- TimezoneInterface $localeDate,
- CartRepositoryInterface $cartRepository,
- LoggerInterface $logger = null
- ) {
- $this->scopeConfig = $scopeConfig;
- $this->inlineTranslation = $inlineTranslation;
- $this->transportBuilder = $transportBuilder;
- $this->localeDate = $localeDate;
- $this->cartRepository = $cartRepository;
- $this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class);
- }
- /**
- * Sends an email about failed transaction.
- *
- * @param int $cartId
- * @param string $message
- * @param string $checkoutType
- * @return PaymentFailuresInterface
- */
- public function handle(
- int $cartId,
- string $message,
- string $checkoutType = 'onepage'
- ): PaymentFailuresInterface {
- $this->inlineTranslation->suspend();
- $quote = $this->cartRepository->get($cartId);
- $template = $this->getConfigValue('checkout/payment_failed/template', $quote);
- $receiver = $this->getConfigValue('checkout/payment_failed/receiver', $quote);
- $sendTo = [
- [
- 'email' => $this->getConfigValue('trans_email/ident_' . $receiver . '/email', $quote),
- 'name' => $this->getConfigValue('trans_email/ident_' . $receiver . '/name', $quote),
- ],
- ];
- $copyMethod = $this->getConfigValue('checkout/payment_failed/copy_method', $quote);
- $copyTo = $this->getConfigEmails($quote);
- $bcc = [];
- if (!empty($copyTo)) {
- switch ($copyMethod) {
- case 'bcc':
- $bcc = $copyTo;
- break;
- case 'copy':
- foreach ($copyTo as $email) {
- $sendTo[] = ['email' => $email, 'name' => null];
- }
- break;
- }
- }
- foreach ($sendTo as $recipient) {
- $transport = $this->transportBuilder
- ->setTemplateIdentifier($template)
- ->setTemplateOptions([
- 'area' => FrontNameResolver::AREA_CODE,
- 'store' => Store::DEFAULT_STORE_ID,
- ])
- ->setTemplateVars($this->getTemplateVars($quote, $message, $checkoutType))
- ->setFrom($this->getSendFrom($quote))
- ->addTo($recipient['email'], $recipient['name'])
- ->addBcc($bcc)
- ->getTransport();
- try {
- $transport->sendMessage();
- } catch (\Exception $e) {
- $this->logger->critical($e->getMessage());
- }
- }
- $this->inlineTranslation->resume();
- return $this;
- }
- /**
- * Returns mail template variables.
- *
- * @param Quote $quote
- * @param string $message
- * @param string $checkoutType
- * @return array
- */
- private function getTemplateVars(Quote $quote, string $message, string $checkoutType): array
- {
- return [
- 'reason' => $message,
- 'checkoutType' => $checkoutType,
- 'dateAndTime' => $this->getLocaleDate(),
- 'customer' => $this->getCustomerName($quote),
- 'customerEmail' => $quote->getBillingAddress()->getEmail(),
- 'billingAddress' => $quote->getBillingAddress(),
- 'shippingAddress' => $quote->getShippingAddress(),
- 'shippingMethod' => $this->getConfigValue(
- 'carriers/' . $this->getShippingMethod($quote) . '/title',
- $quote
- ),
- 'paymentMethod' => $this->getConfigValue(
- 'payment/' . $this->getPaymentMethod($quote) . '/title',
- $quote
- ),
- 'items' => implode('<br />', $this->getQuoteItems($quote)),
- 'total' => $quote->getCurrency()->getStoreCurrencyCode() . ' ' . $quote->getGrandTotal(),
- ];
- }
- /**
- * Returns scope config value by config path.
- *
- * @param string $configPath
- * @param Quote $quote
- * @return mixed
- */
- private function getConfigValue(string $configPath, Quote $quote)
- {
- return $this->scopeConfig->getValue(
- $configPath,
- ScopeInterface::SCOPE_STORE,
- $quote->getStoreId()
- );
- }
- /**
- * Returns shipping method from quote.
- *
- * @param Quote $quote
- * @return string
- */
- private function getShippingMethod(Quote $quote): string
- {
- $shippingMethod = '';
- $shippingInfo = $quote->getShippingAddress()->getShippingMethod();
- if ($shippingInfo) {
- $data = explode('_', $shippingInfo);
- $shippingMethod = $data[0];
- }
- return $shippingMethod;
- }
- /**
- * Returns payment method title from quote.
- *
- * @param Quote $quote
- * @return string
- */
- private function getPaymentMethod(Quote $quote): string
- {
- $paymentMethod = $quote->getPayment()->getMethod() ?? '';
- return $paymentMethod;
- }
- /**
- * Returns quote visible items.
- *
- * @param Quote $quote
- * @return array
- */
- private function getQuoteItems(Quote $quote): array
- {
- $items = [];
- foreach ($quote->getAllVisibleItems() as $item) {
- $itemData = $item->getProduct()->getName() . ' x ' . $item->getQty() . ' ' .
- $quote->getCurrency()->getStoreCurrencyCode() . ' ' .
- $item->getProduct()->getFinalPrice($item->getQty());
- $items[] = $itemData;
- }
- return $items;
- }
- /**
- * Gets email values by configuration path.
- *
- * @param Quote $quote
- * @return array|false
- */
- private function getConfigEmails(Quote $quote)
- {
- $configData = $this->getConfigValue('checkout/payment_failed/copy_to', $quote);
- if (!empty($configData)) {
- return explode(',', $configData);
- }
- return false;
- }
- /**
- * Returns sender identity.
- *
- * @param Quote $quote
- * @return string
- */
- private function getSendFrom(Quote $quote): string
- {
- return $this->getConfigValue('checkout/payment_failed/identity', $quote);
- }
- /**
- * Returns current locale date and time
- *
- * @return string
- */
- private function getLocaleDate(): string
- {
- return $this->localeDate->formatDateTime(
- new \DateTime(),
- \IntlDateFormatter::MEDIUM,
- \IntlDateFormatter::MEDIUM
- );
- }
- /**
- * Returns customer name.
- *
- * @param Quote $quote
- * @return string
- */
- private function getCustomerName(Quote $quote): string
- {
- $customer = __('Guest')->render();
- if (!$quote->getCustomerIsGuest()) {
- $customer = $quote->getCustomer()->getFirstname() . ' ' .
- $quote->getCustomer()->getLastname();
- }
- return $customer;
- }
- }
|