Skip to content

Commit

Permalink
Add validations in callback controller
Browse files Browse the repository at this point in the history
  • Loading branch information
oriolauge committed Apr 1, 2022
1 parent 9c0d2bb commit cefc020
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 42 deletions.
109 changes: 84 additions & 25 deletions Controller/Callback/Processpayment.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
use Magento\Framework\Controller\Result\JsonFactory;
use OAG\Redsys\Model\Signature;
use OAG\Redsys\Model\QuoteRepository;
use OAG\Redsys\Model\MerchantParameters\TotalAmount;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Api\CartManagementInterface;


class Processpayment extends Action implements CsrfAwareActionInterface, HttpPostActionInterface
{
/**
* @var OAG\Redsys\Model\Base64Url
* @var Base64Url
*/
private $base64Url;

Expand All @@ -35,7 +37,7 @@ class Processpayment extends Action implements CsrfAwareActionInterface, HttpPos
private $signature;

/**
* @var OAG\Redsys\Model\QuoteRepository
* @var QuoteRepository
*/
private $quoteRepository;

Expand All @@ -50,7 +52,21 @@ class Processpayment extends Action implements CsrfAwareActionInterface, HttpPos
private $quoteManagement;

/**
* @var TotalAmount
*/
protected $totalAmount;

/**
* @inheritDoc
*
* @param Context $context
* @param Base64Url $base64Url
* @param JsonFactory $resultJsonFactory
* @param Signature $signature
* @param QuoteRepository $quoteRepository
* @param CartRepositoryInterface $cartRepository
* @param CartManagementInterface $quoteManagement
* @param TotalAmount $totalAmount
*/
public function __construct(
Context $context,
Expand All @@ -59,7 +75,8 @@ public function __construct(
Signature $signature,
QuoteRepository $quoteRepository,
CartRepositoryInterface $cartRepository,
CartManagementInterface $quoteManagement
CartManagementInterface $quoteManagement,
TotalAmount $totalAmount
)
{
parent::__construct($context);
Expand All @@ -69,9 +86,14 @@ public function __construct(
$this->quoteRepository = $quoteRepository;
$this->cartRepository = $cartRepository;
$this->quoteManagement = $quoteManagement;
$this->totalAmount = $totalAmount;
}


/**
* Execute controller action
*
* @return jsonResponse
*/
public function execute()
{
$merchantParametersJson = $this->base64Url->decode(
Expand All @@ -95,21 +117,39 @@ public function execute()
return $this->returnJsonError('Signature not match');
}

$quote = $this->getQuote($merchantParameters);
if (!$quote || !$quote->getId()) {
return $this->returnJsonError('Quote not found');
if (!empty($merchantParameters['Ds_Response']) && intval($merchantParameters['Ds_Response']) <= 99) {
$quote = $this->getQuote($merchantParameters);
if (!$quote || !$quote->getId()) {
return $this->returnJsonError('Quote not found');
}

if (empty($merchantParameters['Ds_Amount']) ||
$this->totalAmount->execute($quote) != $merchantParameters['Ds_Amount']) {
return $this->returnJsonError('Quote amount is not the same');
}

/**
* This is an extra validation because if the order has some problem,
* we will be sure that we can contact to the client
*/
if (!$quote->getCustomerEmail()) {
return $this->returnJsonError('Quote has not an email');
}

try {
$order = $this->placeQuote($quote);
} catch(\Exception $e) {
return $this->returnJsonError($e->getMessage());
}

$resultPage = $this->resultJsonFactory->create();
$resultPage->setData([
'success' => true,
'message' => __('Order completed: ' . $order->getId())
]);
return $resultPage;
}

$order = $this->placeQuote($quote);

//@todo: create order and invoce.

$resultPage = $this->resultJsonFactory->create();
$resultPage->setData([
'success' => true,
'message' => __('Order completed: ' . $order->getId())
]);
return $resultPage;
return $this->returnJsonError('Transaction not autorized');
}

/**
Expand All @@ -131,6 +171,9 @@ public function createCsrfValidationException(

/**
* Validate if Redsys send us the required params
*
* @param RequestInterface $request
* @return boolean|null
*/
public function validateForCsrf(RequestInterface $request): ?bool
{
Expand All @@ -143,6 +186,12 @@ public function validateForCsrf(RequestInterface $request): ?bool
return false;
}

/**
* Convert message to json response
*
* @param string $message
* @return jsonObjetc
*/
protected function returnJsonError(string $message)
{
$resultPage = $this->resultJsonFactory->create();
Expand All @@ -160,10 +209,10 @@ protected function returnJsonError(string $message)
* so it's more efficient to load quote by his entity_id.
*
* if for some reason we don't have the quote_id, we will try to load quote by
* reserve_order_id
* reserve_order_id (worst case)
*
* @param array $merchantParameters
* @return Quote
* @return Quote|boolean
*/
protected function getQuote(array $merchantParameters)
{
Expand All @@ -177,14 +226,24 @@ protected function getQuote(array $merchantParameters)
true
);

if ($merchantData && !empty($merchantData['quote_id']) && is_numeric($merchantData['quote_id'])) {
$quote = $this->cartRepository->getActive($merchantData['quote_id']);
} else {
$quote = $this->quoteRepository->loadQuoteByReservedOrderId($merchantParameters['Ds_Order']);
try {
if ($merchantData && !empty($merchantData['quote_id']) && is_numeric($merchantData['quote_id'])) {
$quote = $this->cartRepository->getActive($merchantData['quote_id']);
} else {
$quote = $this->quoteRepository->getActiveByReservedOrderId($merchantParameters['Ds_Order']);
}
return $quote;
} catch (\Exception $e) {
return false;
}
return $quote;
}

/**
* Place order
*
* @param Quote $quote
* @return Order
*/
protected function placeQuote($quote)
{
$quote->collectTotals();
Expand Down
26 changes: 12 additions & 14 deletions Model/MerchantParameters.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use OAG\Redsys\Model\MerchantParameters\Currency;
use OAG\Redsys\Model\MerchantParameters\Language;
use OAG\Redsys\Model\MerchantParameters\ProductDescription;
use OAG\Redsys\Model\MerchantParameters\TotalAmount;
use OAG\Redsys\Model\ConfigInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
Expand Down Expand Up @@ -38,6 +39,12 @@ class MerchantParameters
*/
protected $url;

/**
* @var TotalAmount
* @todo: conver to interface
*/
protected $totalAmount;

/**
* Construct function
*
Expand All @@ -51,13 +58,15 @@ public function __construct(
Currency $currency,
Language $language,
ProductDescription $productDescription,
UrlInterface $url
UrlInterface $url,
TotalAmount $totalAmount
) {
$this->scopeConfig = $scopeConfig;
$this->currency = $currency;
$this->language = $language;
$this->productDescription = $productDescription;
$this->url = $url;
$this->totalAmount = $totalAmount;
}

/**
Expand All @@ -80,7 +89,7 @@ public function execute(Quote $quote): string
* DS_MERCHANT_EMV3DS
*/
$result = [
'Ds_Merchant_Amount' => $this->convertAmountToRedsysFormat($quote->getGrandTotal()),
'Ds_Merchant_Amount' => $this->totalAmount->execute($quote),
'Ds_Merchant_Order' => $quote->getReservedOrderId(),
'Ds_Merchant_MerchantCode' => $merchantCode,
'Ds_Merchant_Currency' => $this->currency->getCurrency($quote->getQuoteCurrencyCode()),
Expand All @@ -96,15 +105,4 @@ public function execute(Quote $quote): string
];
return base64_encode(json_encode($result));
}

/**
* Convert amount to Redsys format
*
* @param float $amount
* @return float
*/
protected function convertAmountToRedsysFormat($amount): float
{
return floatval($amount) * 100;
}
}
}
20 changes: 20 additions & 0 deletions Model/MerchantParameters/TotalAmount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
namespace OAG\Redsys\Model\MerchantParameters;

/**
* Class TotalAmount
* @package OAG\Redsys\Model\MerchantParameters
*/
class TotalAmount
{
/**
* Convert amount to Redsys format
*
* @param float $amount
* @return float
*/
public function execute($quote): float
{
return floatval($quote->getGrandTotal()) * 100;
}
}
1 change: 1 addition & 0 deletions Model/PaymentInformationManagement.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public function getPaymentInformation($cartId)
'Ds_Signature' => $this->signature->generateRequestSignature($incrementId, $merchantParameters)
]);
} catch (\Exception $e) {
//@todo: test the error exceptions in frontend
$this->logger->debug($e->getMessage());
return json_encode([$e->getMessage()]);
}
Expand Down
10 changes: 7 additions & 3 deletions Model/QuoteRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
namespace OAG\Redsys\Model;

use Magento\Quote\Model\QuoteFactory;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Quote\Model\ResourceModel\Quote as QuoteResource;

class QuoteRepository
Expand Down Expand Up @@ -29,8 +30,11 @@ public function __construct(
/** @return \Magento\Quote\Model\Quote **/
public function loadQuoteByReservedOrderId(string $incrementId)
{
$quote = $this->quoteFactory->create();
$this->quoteResource->load($quote, $incrementId, self::RESERVED_ORDER_FIELD);
return $quote;
$quote = $this->quoteFactory->create();
$this->quoteResource->load($quote, $incrementId, self::RESERVED_ORDER_FIELD);
if (!$quote->getIsActive()) {
throw NoSuchEntityException::singleField(self::RESERVED_ORDER_FIELD, $incrementId);
}
return $quote;
}
}

0 comments on commit cefc020

Please sign in to comment.