Example #1
0
 /**
  * Process payment refund notification
  * Updates transactions hierarchy, if required
  * Prevents transaction double processing
  * Updates payment totals, updates order status and adds proper comments
  * TODO: potentially a full capture can be refunded. In this case if there was only one invoice for that transaction
  *       then we should create a creditmemo from invoice and also refund it offline
  * TODO: implement logic of chargebacks reimbursements (via negative amount)
  *
  * @param float $amount
  * @return Mage_Sales_Model_Order_Payment
  */
 public function registerRefundNotification($amount)
 {
     $notificationAmount = $amount;
     $this->_generateTransactionId(Mage_Sales_Model_Order_Payment_Transaction::TYPE_REFUND, $this->_lookupTransaction($this->getParentTransactionId()));
     if ($this->_isTransactionExists()) {
         return $this;
     }
     $order = $this->getOrder();
     $invoice = $this->_getInvoiceForTransactionId($this->getParentTransactionId());
     if ($invoice) {
         $baseGrandTotal = $invoice->getBaseGrandTotal();
         $amountRefundLeft = $baseGrandTotal - $invoice->getBaseTotalRefunded();
     } else {
         $baseGrandTotal = $order->getBaseGrandTotal();
         $amountRefundLeft = $baseGrandTotal - $order->getBaseTotalRefunded();
     }
     if ($amountRefundLeft < $amount) {
         $amount = $amountRefundLeft;
     }
     if ($amount != $baseGrandTotal) {
         $transaction = new Varien_Object(array('txn_id' => $this->getTransactionId()));
         Mage::dispatchEvent('sales_html_txn_id', array('transaction' => $transaction, 'payment' => $this));
         $transactionId = $transaction->getHtmlTxnId() ? $transaction->getHtmlTxnId() : $transaction->getTxnId();
         $order->addStatusHistoryComment(Mage::helper('sales')->__('IPN "Refunded". Refund issued by merchant. Registered notification about refunded amount of %s. Transaction ID: "%s". Credit Memo has not been created. Please create offline Credit Memo.', $this->_formatPrice($notificationAmount), $transactionId), false);
         return $this;
     }
     $serviceModel = Mage::getModel('sales/service_order', $order);
     if ($invoice) {
         if ($invoice->getBaseTotalRefunded() > 0) {
             $adjustment = array('adjustment_positive' => $amount);
         } else {
             $adjustment = array('adjustment_negative' => $baseGrandTotal - $amount);
         }
         $creditmemo = $serviceModel->prepareInvoiceCreditmemo($invoice, $adjustment);
         if ($creditmemo) {
             $totalRefunded = $invoice->getBaseTotalRefunded() + $creditmemo->getBaseGrandTotal();
             $this->setShouldCloseParentTransaction($invoice->getBaseGrandTotal() <= $totalRefunded);
         }
     } else {
         if ($order->getBaseTotalRefunded() > 0) {
             $adjustment = array('adjustment_positive' => $amount);
         } else {
             $adjustment = array('adjustment_negative' => $baseGrandTotal - $amount);
         }
         $creditmemo = $serviceModel->prepareCreditmemo($adjustment);
         if ($creditmemo) {
             $totalRefunded = $order->getBaseTotalRefunded() + $creditmemo->getBaseGrandTotal();
             $this->setShouldCloseParentTransaction($order->getBaseGrandTotal() <= $totalRefunded);
         }
     }
     $creditmemo->setPaymentRefundDisallowed(true)->setAutomaticallyCreated(true)->register()->addComment(Mage::helper('sales')->__('Credit memo has been created automatically'))->save();
     $this->_updateTotals(array('amount_refunded' => $creditmemo->getGrandTotal(), 'base_amount_refunded_online' => $amount));
     $this->setCreatedCreditmemo($creditmemo);
     // update transactions and order state
     $transaction = $this->_addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_REFUND, $creditmemo);
     $message = $this->_prependMessage(Mage::helper('sales')->__('Registered notification about refunded amount of %s.', $this->_formatPrice($amount)));
     $message = $this->_appendTransactionToMessage($transaction, $message);
     $order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true, $message);
     return $this;
 }