<?php /** * This file is part of the Klarna KP module * * (c) Klarna Bank AB (publ) * * For the full copyright and license information, please view the NOTICE * and LICENSE files that were distributed with this source code. */ namespace Klarna\Kp\Model\Api\Builder; use Klarna\Core\Exception as KlarnaException; use Klarna\Core\Helper\ConfigHelper; use Klarna\Core\Helper\DataConverter; use Klarna\Core\Helper\KlarnaConfig; use Klarna\Core\Model\Api\Exception as KlarnaApiException; use Klarna\Core\Model\Checkout\Orderline\Collector; use Klarna\Core\Model\Fpt\Rate; use Klarna\Kp\Api\Data\RequestInterface; use Klarna\Kp\Model\Api\Request; use Klarna\Kp\Model\Payment\Kp; use Magento\Directory\Helper\Data as DirectoryHelper; use Magento\Framework\DataObject; use Magento\Framework\DataObjectFactory; use Magento\Framework\Event\ManagerInterface as EventManager; use Magento\Framework\Url; use Magento\Quote\Model\Quote\Address; /** * Class Kasper * * @package Klarna\Kp\Model\Api\Builder * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Kasper extends \Klarna\Core\Model\Api\Builder { /** * @var Request\Builder */ private $requestBuilder; /** * @var DataConverter */ private $dataConverter; /** @var Rate $rate */ private $rate; /** * Kasper constructor. * * @param EventManager $eventManager * @param Collector $collector * @param Url $url * @param ConfigHelper $configHelper * @param Rate $rate * @param DirectoryHelper $directoryHelper * @param \Magento\Framework\Stdlib\DateTime\DateTime $coreDate * @param DataObject\Copy $objCopyService * @param \Magento\Customer\Model\AddressRegistry $addressRegistry * @param KlarnaConfig $klarnaConfig * @param DataConverter $dataConverter * @param Request\Builder $requestBuilder * @param DataObjectFactory $dataObjectFactory * @param array $data * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( EventManager $eventManager, Collector $collector, Url $url, ConfigHelper $configHelper, Rate $rate, DirectoryHelper $directoryHelper, \Magento\Framework\Stdlib\DateTime\DateTime $coreDate, \Magento\Framework\DataObject\Copy $objCopyService, \Magento\Customer\Model\AddressRegistry $addressRegistry, KlarnaConfig $klarnaConfig, DataConverter $dataConverter, Request\Builder $requestBuilder, DataObjectFactory $dataObjectFactory, array $data = [] ) { parent::__construct( $eventManager, $collector, $url, $configHelper, $directoryHelper, $coreDate, $objCopyService, $addressRegistry, $klarnaConfig, $dataObjectFactory, $data ); $this->prefix = 'kp'; $this->dataConverter = $dataConverter; $this->requestBuilder = $requestBuilder; $this->rate = $rate; } /** * Generate request * * @param string $type * @return $this * @throws \Klarna\Core\Exception * @throws \Magento\Framework\Exception\LocalizedException */ public function generateRequest($type = self::GENERATE_TYPE_CREATE) { $this->resetOrderLines(); parent::generateRequest($type); switch ($type) { case self::GENERATE_TYPE_CREATE: case self::GENERATE_TYPE_UPDATE: return $this->generateCreateUpdate(); case self::GENERATE_TYPE_PLACE: return $this->generatePlace(); } return $this; } /** * Generate Create/Update Request * * @return $this * @throws KlarnaApiException * @throws KlarnaException * @throws \Magento\Framework\Exception\LocalizedException */ private function generateCreateUpdate() { $requiredAttributes = [ 'purchase_country', 'purchase_currency', 'locale', 'order_amount', 'orderlines' ]; /** @var \Magento\Quote\Model\Quote $quote */ $quote = $this->getObject(); $store = $quote->getStore(); $options = array_map('trim', array_filter($this->configHelper->getCheckoutDesignConfig($store))); /** * Pre-fill customer details */ $this->prefillAddresses($quote, $store); $address = $quote->isVirtual() ? $quote->getBillingAddress() : $quote->getShippingAddress(); $tax = $address->getBaseTaxAmount(); if ($this->configHelper->isFptEnabled($store) && !$this->configHelper->getDisplayInSubtotalFpt($store)) { $fptResult = $this->rate->getFptTax($quote); $tax += $fptResult['tax']; } $this->requestBuilder->setPurchaseCountry($this->directoryHelper->getDefaultCountry($store)) ->setPurchaseCurrency($quote->getBaseCurrencyCode()) ->setLocale(str_replace('_', '-', $this->configHelper->getLocaleCode())) ->setOptions($options) ->setOrderAmount((int)$this->dataConverter->toApiFloat($address->getBaseGrandTotal())) ->addOrderlines($this->getOrderLines($quote->getStore())) ->setOrderTaxAmount((int)$this->dataConverter->toApiFloat($tax)) ->setMerchantUrls($this->processMerchantUrls()) ->validate($requiredAttributes, self::GENERATE_TYPE_CREATE); return $this; } /** * @param $quote * @param $store */ public function prefillAddresses($quote, $store) { if (!$this->configHelper->isPaymentConfigFlag('data_sharing', $store, Kp::METHOD_CODE)) { return; } if ($this->configHelper->getApiConfig('api_version', $store) !== 'kp_na') { return; } $billingAddress = $this->getAddressData($quote, Address::TYPE_BILLING); if (!isset($billingAddress['country']) || $billingAddress['country'] !== 'US') { return; } $this->addBillingAddress($billingAddress); $this->addShippingAddress($this->getAddressData($quote, Address::TYPE_SHIPPING)); return; } /** * @param array $create */ private function addBillingAddress($address) { if ($this->validateAddress($address)) { $this->requestBuilder->setBillingAddress($address); } } /** * @param array $address * @return bool */ private function validateAddress($address = null) { if ($address === null) { return false; } if (!is_array($address)) { return false; } if (!isset($address['email'])) { return false; } return true; } /** * @param array $create */ private function addShippingAddress($address) { if ($this->validateAddress($address)) { $this->requestBuilder->setShippingAddress($address); } } /** * Pre-process Merchant URLs * * @param bool $nosid * @param bool $forced_secure * @return string[] */ public function processMerchantUrls($nosid = true, $forced_secure = true) { /** * Urls */ $urlParams = [ '_nosid' => $nosid, '_forced_secure' => $forced_secure ]; $merchantUrls = $this->dataObjectFactory->create([ 'data' => [ 'confirmation' => $this->url->getDirectUrl('checkout/onepage/success', $urlParams), 'notification' => $this->url->getDirectUrl('klarna/api/disabled', $urlParams) ] ]); $this->eventManager->dispatch( 'klarna_prepare_merchant_urls', [ 'urls' => $merchantUrls, 'url_params' => $this->dataObjectFactory->create(['data' => $urlParams]) ] ); $data = $merchantUrls->toArray(); $data['notification'] = preg_replace('/\/id\/{checkout\.order\.id}/', '', $data['notification']); unset($data['push']); return $data; } /** * Generate place order body * * @return Kasper * @throws \Klarna\Core\Exception * @throws \Klarna\Core\Model\Api\Exception * @throws \Magento\Framework\Exception\LocalizedException */ private function generatePlace() { $requiredAttributes = [ 'purchase_country', 'purchase_currency', 'locale', 'order_amount', 'orderlines', 'merchant_urls', 'billing_address', 'shipping_address' ]; /** @var \Magento\Quote\Model\Quote $quote */ $quote = $this->getObject(); $store = $quote->getStore(); $address = $quote->isVirtual() ? $quote->getBillingAddress() : $quote->getShippingAddress(); /** * Get customer addresses (shipping and billing) */ $this->addBillingAddress($this->getAddressData($quote, Address::TYPE_BILLING)); $this->addShippingAddress($this->getAddressData($quote, Address::TYPE_SHIPPING)); $tax = $address->getBaseTaxAmount(); if ($this->configHelper->isFptEnabled($store) && !$this->configHelper->getDisplayInSubtotalFpt($store)) { $fptResult = $this->rate->getFptTax($quote); $tax += $fptResult['tax']; } $this->requestBuilder->setPurchaseCountry($this->directoryHelper->getDefaultCountry($store)) ->setPurchaseCurrency($quote->getBaseCurrencyCode()) ->setLocale(str_replace('_', '-', $this->configHelper->getLocaleCode())) ->setOrderAmount((int)$this->dataConverter->toApiFloat($address->getBaseGrandTotal())) ->addOrderlines($this->getOrderLines($quote->getStore())) ->setOrderTaxAmount((int)$this->dataConverter->toApiFloat($tax)) ->setMerchantUrls($this->processMerchantUrls()) ->setMerchantReferences($this->getMerchantReferences($quote)) ->validate($requiredAttributes, self::GENERATE_TYPE_PLACE); return $this; } /** * Get request * * @return RequestInterface * * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function getRequest() { return $this->requestBuilder->getRequest(); } }