diff --git a/Controller/Payment/Order.php b/Controller/Payment/Order.php index ac2bea7d..ad92efb3 100644 --- a/Controller/Payment/Order.php +++ b/Controller/Payment/Order.php @@ -7,12 +7,12 @@ class Order extends \Razorpay\Magento\Controller\BaseController { - protected $quote; + protected $quote; - protected $checkoutSession; + protected $checkoutSession; - protected $_currency = PaymentMethod::CURRENCY; - /** + protected $_currency = PaymentMethod::CURRENCY; + /** * @param \Magento\Framework\App\Action\Context $context * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Checkout\Model\Session $checkoutSession @@ -52,6 +52,13 @@ public function execute() $maze_version = $this->_objectManager->get('Magento\Framework\App\ProductMetadataInterface')->getVersion(); $module_version = $this->_objectManager->get('Magento\Framework\Module\ModuleList')->getOne('Razorpay_Magento')['setup_version']; + + //if already order from same session , let make it's to pending state + $orderModel = $this->_objectManager->get('Magento\Sales\Model\Order')->load($mazeOrder->getEntityId()); + $orderModel->setState('new') + ->setStatus('pending'); + $orderModel->save(); + if ($payment_action === 'authorize') { $payment_capture = 0; diff --git a/Controller/Payment/ResetCart.php b/Controller/Payment/ResetCart.php new file mode 100644 index 00000000..dbcf5717 --- /dev/null +++ b/Controller/Payment/ResetCart.php @@ -0,0 +1,89 @@ +checkoutFactory = $checkoutFactory; + $this->catalogSession = $catalogSession; + $this->config = $config; + } + + public function execute() + { + $lastQuoteId = $this->checkoutSession->getLastQuoteId(); + $lastOrderId = $this->checkoutSession->getLastRealOrder(); + + $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); + + + + if ($lastQuoteId && $lastOrderId) { + $orderModel = $objectManager->get('Magento\Sales\Model\Order')->load($lastOrderId->getEntityId()); + + if($orderModel->canCancel()) { + + $quote = $objectManager->get('Magento\Quote\Model\Quote')->load($lastQuoteId); + $quote->setIsActive(true)->save(); + + //not canceling order as cancled order can't be used again for order processing. + //$orderModel->cancel(); + $orderModel->setStatus('canceled'); + $orderModel->save(); + $this->checkoutSession->setFirstTimeChk('0'); + + $responseContent = [ + 'success' => true, + 'redirect_url' => 'checkout/#payment' + ]; + } + } + + if (!$lastQuoteId || !$lastOrderId) { + $responseContent = [ + 'success' => true, + 'redirect_url' => 'checkout/cart' + ]; + } + + $this->messageManager->addError(__('Payment Failed or Payment closed')); + + $response = $this->resultFactory->create(ResultFactory::TYPE_JSON); + $response->setData($responseContent); + $response->setHttpResponseCode(200); + + return $response; + + } + +} diff --git a/Controller/Payment/Validate.php b/Controller/Payment/Validate.php index 39957891..b270fbf9 100644 --- a/Controller/Payment/Validate.php +++ b/Controller/Payment/Validate.php @@ -34,6 +34,18 @@ class Validate extends \Razorpay\Magento\Controller\BaseController implements Cs const STATUS_APPROVED = 'APPROVED'; const STATUS_PROCESSING = 'processing'; + /** + * @var \Magento\Sales\Model\Service\InvoiceService + */ + protected $_invoiceService; + protected $_invoiceSender; + + /** + * @var \Magento\Framework\DB\Transaction + */ + protected $_transaction; + + /** * @param \Magento\Framework\App\Action\Context $context * @param \Magento\Customer\Model\Session $customerSession @@ -49,6 +61,9 @@ public function __construct( \Razorpay\Magento\Model\Config $config, \Magento\Catalog\Model\Session $catalogSession, \Magento\Sales\Api\Data\OrderInterface $order, + \Magento\Sales\Model\Service\InvoiceService $invoiceService, + \Magento\Framework\DB\Transaction $transaction, + \Magento\Sales\Model\Order\Email\Sender\InvoiceSender $invoiceSender, OrderRepositoryInterface $orderRepository, \Magento\Sales\Model\Order\Email\Sender\OrderSender $orderSender ) @@ -65,12 +80,16 @@ public function __construct( $this->api = new Api($keyId, $keySecret); $this->order = $order; - + $this->config = $config; $this->objectManagement = \Magento\Framework\App\ObjectManager::getInstance(); $this->catalogSession = $catalogSession; $this->orderRepository = $orderRepository; $this->orderSender = $orderSender; + + $this->_invoiceService = $invoiceService; + $this->_invoiceSender = $invoiceSender; + $this->_transaction = $transaction; } /** @@ -102,11 +121,18 @@ public function execute() return; } + $order = $this->checkoutSession->getLastRealOrder(); + + $responseContent = [ + 'success' => false, + 'redirect_url' => 'checkout/#payment', + 'parameters' => [] + ]; + try { $this->validateSignature($post); - $order = $this->checkoutSession->getLastRealOrder(); $orderId = $order->getIncrementId(); $order->setState(static::STATUS_PROCESSING)->setStatus(static::STATUS_PROCESSING); @@ -120,14 +146,48 @@ public function execute() ->setIsTransactionClosed(true) ->setShouldCloseParentTransaction(true); + $payment->setParentTransactionId($payment->getTransactionId()); + $payment->addTransactionCommentsToOrder( $paymentId, "" ); + + $transaction = $payment->addTransaction(\Magento\Sales\Model\Order\Payment\Transaction::TYPE_AUTH, null, true, ""); + $transaction->setIsClosed(true); + $order->save(); $this->orderRepository->save($order); + //update/disable the quote + $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); + $quote = $objectManager->get('Magento\Quote\Model\Quote')->load($order->getQuoteId()); + $quote->setIsActive(false)->save(); + + if($order->canInvoice() and + ($this->config->getPaymentAction() === \Razorpay\Magento\Model\PaymentMethod::ACTION_AUTHORIZE_CAPTURE) and + $this->config->canAutoGenerateInvoice()) + { + $invoice = $this->_invoiceService->prepareInvoice($order); + $invoice->setRequestedCaptureCase(\Magento\Sales\Model\Order\Invoice::CAPTURE_ONLINE); + $invoice->setTransactionId($paymentId); + $invoice->register(); + $invoice->save(); + $transactionSave = $this->_transaction->addObject($invoice) + ->addObject($invoice->getOrder()); + $transactionSave->save(); + + $this->_invoiceSender->send($invoice); + //send notification code + $order->setState(static::STATUS_PROCESSING)->setStatus(static::STATUS_PROCESSING); + $order->addStatusHistoryComment( + __('Notified customer about invoice #%1.', $invoice->getId()) + ) + ->setIsCustomerNotified(true) + ->save(); + } + //send Order email, after successfull payment $this->checkoutSession->setRazorpayMailSentOnSuccess(true); $this->orderSender->send($order, true); @@ -135,30 +195,36 @@ public function execute() $responseContent = [ 'success' => true, - 'redirect_url' => 'onepage/success/', + 'redirect_url' => 'checkout/onepage/success/', 'order_id' => $orderId, ]; $code = 200; + $response = $this->resultFactory->create(ResultFactory::TYPE_JSON); + $response->setData($responseContent); + $response->setHttpResponseCode($code); + return $response; + } catch(\Razorpay\Api\Errors\Error $e) { - $responseContent = [ - 'message' => $e->getMessage(), - 'parameters' => [] - ]; + $responseContent['message'] = $e->getMessage(); + $code = $e->getCode(); } catch(\Exception $e) { - $responseContent = [ - 'message' => $e->getMessage(), - 'parameters' => [] - ]; + $responseContent['message'] = $e->getMessage(); + $code = $e->getCode(); } + //update/disable the quote + $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); + $quote = $objectManager->get('Magento\Quote\Model\Quote')->load($order->getQuoteId()); + $quote->setIsActive(true)->save(); + $this->checkoutSession->setFirstTimeChk('0'); $response = $this->resultFactory->create(ResultFactory::TYPE_JSON); $response->setData($responseContent); @@ -169,6 +235,12 @@ public function execute() protected function validateSignature($request) { + if(empty($request['error']) === false) + { + $this->messageManager->addError(__('Payment Failed')); + throw new \Exception("Payment Failed or error from gateway"); + } + $attributes = array( 'razorpay_payment_id' => $request['razorpay_payment_id'], 'razorpay_order_id' => $this->catalogSession->getRazorpayOrderID(), diff --git a/Model/Config.php b/Model/Config.php index 2f809326..9ba64177 100644 --- a/Model/Config.php +++ b/Model/Config.php @@ -12,7 +12,8 @@ class Config const KEY_PUBLIC_KEY = 'key_id'; const KEY_PRIVATE_KEY = 'key_secret'; const KEY_MERCHANT_NAME_OVERRIDE = 'merchant_name_override'; - const KEY_PAYMENT_ACTION = 'payment_action'; + const KEY_PAYMENT_ACTION = 'rzp_payment_action'; + const KEY_AUTO_INVOICE = 'auto_invoice'; /** * @var string @@ -94,6 +95,14 @@ public function isActive() return (bool) (int) $this->getConfigData(self::KEY_ACTIVE, $this->storeId); } + /** + * @return bool + */ + public function canAutoGenerateInvoice() + { + return (bool) (int) $this->getConfigData(self::KEY_AUTO_INVOICE, $this->storeId); + } + /** * To check billing country is allowed for the payment method * diff --git a/Model/PaymentMethod.php b/Model/PaymentMethod.php index 204b1e32..fa7e51fd 100644 --- a/Model/PaymentMethod.php +++ b/Model/PaymentMethod.php @@ -48,7 +48,7 @@ class PaymentMethod extends \Magento\Payment\Model\Method\AbstractMethod /** * @var bool */ - protected $_canUseInternal = false; //Disable module for Magento Admin Order + protected $_canUseInternal = true; //Disable module for Magento Admin Order /** * @var bool @@ -95,6 +95,8 @@ class PaymentMethod extends \Magento\Payment\Model\Method\AbstractMethod */ protected $orderRepository; + //protected $_isOffline = true; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -204,6 +206,11 @@ public function refund(InfoInterface $payment, $amount) return $this; } + public function capture(InfoInterface $payment, $amount) + { + return $this; + } + /** * Format param "channel" for transaction * diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index a349ea24..cd2156ca 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -11,10 +11,10 @@ Magento\Config\Model\Config\Source\Yesno payment/razorpay/active - + Razorpay\Magento\Model\PaymentAction - payment/razorpay/payment_action + payment/razorpay/rzp_payment_action @@ -36,9 +36,14 @@ - Magento\Sales\Model\Config\Source\Order\Status\Processing + Magento\Sales\Model\Config\Source\Order\Status\NewStatus payment/razorpay/order_status + + + Magento\Config\Model\Config\Source\Yesno + payment/razorpay/auto_invoice + Magento\Payment\Model\Config\Source\Allspecificcountries diff --git a/etc/csp_whitelist.xml b/etc/csp_whitelist.xml new file mode 100755 index 00000000..74241474 --- /dev/null +++ b/etc/csp_whitelist.xml @@ -0,0 +1,21 @@ + + + + + + cdn.razorpay.com + + + + + checkout.razorpay.com + + + + + api.razorpay.com + + + + diff --git a/view/frontend/web/js/view/payment/method-renderer/razorpay-method.js b/view/frontend/web/js/view/payment/method-renderer/razorpay-method.js index f9a6155f..849ac07c 100644 --- a/view/frontend/web/js/view/payment/method-renderer/razorpay-method.js +++ b/view/frontend/web/js/view/payment/method-renderer/razorpay-method.js @@ -170,7 +170,6 @@ define( success: function (response) { fullScreenLoader.stopLoader(); if (response.success) { - //self.placeOrder(this.event, response); self.doCheckoutPayment(response); } else { self.isPaymentProcessing.reject(response.message); @@ -203,7 +202,9 @@ define( }, order_id: data.rzp_order, modal: { - ondismiss: function() { //alert('asdsadsa'); + ondismiss: function(data) { + //reset the cart + self.resetCart(data); fullScreenLoader.stopLoader(); self.isPaymentProcessing.reject("Payment Closed"); self.isPlaceOrderActionAllowed(true); @@ -253,11 +254,55 @@ define( */ success: function (response) { fullScreenLoader.stopLoader(); - if (response.success) { - window.location.replace(response.redirect_url); - } else { + + require('Magento_Customer/js/customer-data').reload(['cart']); + + if (!response.success) { alert('asdsa'); + fullScreenLoader.stopLoader(); self.isPaymentProcessing.reject(response.message); self.handleError(response); + self.isPlaceOrderActionAllowed(true); + } + + window.location.replace(url.build(response.redirect_url)); + }, + + /** + * Error callback + * @param {*} response + */ + error: function (response) { + fullScreenLoader.stopLoader(); + self.isPaymentProcessing.reject(response.message); + self.handleError(response); + } + }); + + }, + + resetCart: function(data){ + + var self = this; + fullScreenLoader.startLoader(); + + $.ajax({ + type: 'POST', + url: url.build('razorpay/payment/resetCart'), + data: JSON.stringify(data), + dataType: 'json', + contentType: 'application/json', + + /** + * Success callback + * @param {Object} response + */ + success: function (response) { + fullScreenLoader.stopLoader(); + self.isPaymentProcessing.reject('order_failed'); + require('Magento_Customer/js/customer-data').reload(['cart']); + + if (response.success) { + window.location.replace(url.build(response.redirect_url)); } },