Magento create Creditmemo to refund online or offline

<?php
 
        $orderId ='123456789';
        $invoiceId = '1234';
 
        $data = array(
            'items' => array(
                '12345' => array('qty' => '1'),
                '12346' => array('qty' => '2')
            ),
            'comment_text' => null,
            'do_offline' => 1,
            'shipping_amount' => 0,
            'adjustment_positive' => '0',
            'adjustment_negative' => '0',
            'refund_customerbalance_return_enable' => 1,
            'refund_customerbalance_return' => 39.9
        );
 
        // load order and invoice
        $order  = Mage::getModel('sales/order')->load($orderId);
        $invoice = Mage::getModel('sales/order_invoice')
                ->load($invoiceId)
                ->setOrder($order);
 
        // if can credit memo
        if (!$order->getId() && !$order->canCreditmemo()) {
            Mage::throwException(
                $this->__('Cannot create credit memo for the order.')
            );
        }
 
        // Initialize items
        $savedData = $data['items'];
 
        $qtys = array();
        $backToStock = array();
        foreach ($savedData as $orderItemId =>$itemData) {
            if (isset($itemData['qty'])) {
                $qtys[$orderItemId] = $itemData['qty'];
            }
            if (isset($itemData['back_to_stock'])) {
                $backToStock[$orderItemId] = true;
            }
        }
        $data['qtys'] = $qtys;
 
        // Create credit memo if invoice then prepareInvoiceCreditmemo(), otherwise prepareCreditmemo()
        $service = Mage::getModel('sales/service_order', $order);
        if ($invoice) {
            $creditmemo = $service->prepareInvoiceCreditmemo($invoice, $data);
        } else {
            $creditmemo = $service->prepareCreditmemo($data);
        }
 
 
        /**
         * Process back to stock flags
         */
        foreach ($creditmemo->getAllItems() as $creditmemoItem) {
            $orderItem = $creditmemoItem->getOrderItem();
            $parentId = $orderItem->getParentItemId();
            if (isset($backToStock[$orderItem->getId()])) {
                $creditmemoItem->setBackToStock(true);
            } elseif ($orderItem->getParentItem() && isset($backToStock[$parentId]) && $backToStock[$parentId]) {
                $creditmemoItem->setBackToStock(true);
            } elseif (empty($savedData)) {
                $creditmemoItem->setBackToStock(Mage::helper('cataloginventory')->isAutoReturnEnabled());
            } else {
                $creditmemoItem->setBackToStock(false);
            }
        }
 
        // A workaround regarding refund to customer balance
        $param = Mage::app()->getRequest()->getParams();
 
        $param['creditmemo']['refund_customerbalance_return_enable'] = true;
        $param['creditmemo']['refund_customerbalance_return']        = $order->getData('base_total_paid');
 
        Mage::app()->getRequest()->setParams($param);
 
        $args = array('creditmemo' => $creditmemo, 'request' => Mage::app()->getRequest());
        Mage::dispatchEvent('adminhtml_sales_order_creditmemo_register_before', $args);
 
        if ($creditmemo) {
            if (($creditmemo->getGrandTotal() <= 0) && (!$creditmemo->getAllowZeroGrandTotal())) {
                Mage::throwException(
                    $this->__('Credit memo\'s total must be positive.')
                );
            }
 
            // Comment text if exist
            $creditmemo->addComment('our comment',false,false);
 
            // Flag for online refund
            if (isset($data['do_refund'])) {
                $creditmemo->setRefundRequested(true);
            }
 
            // Flag for offline refund
            if (isset($data['do_offline'])) {
                $creditmemo->setOfflineRequested((bool)(int)$data['do_offline']);
            }
 
            // saving creditmemo
            $creditmemo->register();
 
            // Database update
            $transactionSave = Mage::getModel('core/resource_transaction')
                ->addObject($creditmemo)
                ->addObject($creditmemo->getOrder());
            if ($creditmemo->getInvoice()) {
                $transactionSave->addObject($creditmemo->getInvoice());
            }
            $transactionSave->save();
        }

Leave a Reply