public function onSalesModelOrderPaymentVoid($observer) { if ($observer->getPayment()->getOrder()->getInstallmentTypeId()) { $orderId = $observer->getPayment()->getOrder()->getRealOrderId(); if (NGC_Installment_Model_Master::suspendInstallmentPayment($orderId, 1, 'Order was void')) { return Mage::throwException('Unable to suspend future installment payments'); } if (NGC_Installment_Model_Master::refundInstallmentPayment($orderId)) { return mage::throwException('Unable to refund installment payments'); } } }
/** * This function will get ran daily and will authorize and capture installment payments that are due today * @static * */ static function dailyCaptureInstallmentPayment() { $date = date("Y-m-d", Mage::getModel('core/date')->timestamp(time())) . ' 23:59:59'; $collection = Mage::getModel('installment/master')->getCollection(); $collection->addFieldToFilter('installment_master_amount_due_date', array('lt' => $date))->addFieldToFilter('installment_master_installment_paid', 0)->addFieldToFilter('installment_master_suspend_installment', 0)->addFieldToFilter('order_id', array('like' => '100%')); $collection->getSelect()->join(array('order' => $collection->getTable('sales/order')), 'order.increment_id = main_table.order_id', array('order.increment_id'))->where('order.status IN ("shipped", "ready_to_collect", "installment_plan_running", "installment_capture_failed", "capture_failed")'); $currentDate = Mage::getModel('core/date')->gmtDate(); foreach ($collection as $transaction) { $order = Mage::getModel('sales/order')->loadByIncrementId($transaction->getOrderId()); $orderId = $order->getRealOrderId(); if ($order->getRealOrderId()) { $payment = $order->getPayment(); $amount = $transaction->getInstallmentMasterAmountDue(); $maxAttempt = Mage::getStoreConfig('installment/grace_period_options/grace_period_attempts', $order->getStoreId()); $attempt = $transaction->getInstallmentMasterAttemptToAuthorize() + 1; if ($attempt <= $maxAttempt) { if ($transaction->getInstallmentMasterInstallmentAuthorized()) { $payment->getMethodInstance()->setStore($order->getStoreId())->capture($payment, $amount); } else { $payment->getMethodInstance()->setStore($order->getStoreId())->authorize($payment, $amount); $payment->getMethodInstance()->setStore($order->getStoreId())->capture($payment, $amount); } $payment->setIsTransactionClosed(1); $payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE, null, false, sprintf('Captured amount of %s for installment payment #%s', $amount, $transaction->getInstallmentMasterSequenceNumber()))->save(); // insert transaction record into installment_transaction list($customerProfileId, $paymentProfileId, $authorizeCode) = explode('-', $payment->getPoNumber()); $currencyCode = Mage::app()->getStore($order->getStoreId())->getCurrentCurrencyCode(); if ($payment->getCcAvsStatus() == 'Ok') { $transaction->setInstallmentMasterInstallmentAuthorized(true)->setInstallmentMasterInstallmentPaid(true)->setInstallmentMasterAttemptToAuthorize($attempt)->save(); $installmentTrans = Mage::getModel('installment/transaction'); $installmentTrans->setOrderId($orderId)->setInstallmentTransactionTransactionSequenceNumber($attempt)->setInstallmentTransactionPaymentToken($payment->getCcTransId() . '-' . $payment->getPoNumber())->setInstallmentTransactionSequenceNumber($transaction->getInstallmentMasterSequenceNumber())->setInstallmentTransactionAuthorizeAmount($amount)->setInstallmentTransactionAuthorizeAttemptDate($currentDate)->setInstallmentTransactionAuthorizationCode($authorizeCode)->setInstallmentTransactionCurrencyCode($currencyCode)->save(); // if last payment update state and status to complete $installment = Mage::getModel('installment/master')->getCollection(); $installment->getSelect()->reset(Zend_Db_Select::COLUMNS)->columns('MAX(installment_master_sequence_number) as max_sequence_number')->where("order_id = '" . $transaction->getOrderId() . "'")->group(array('order_id')); $result = $installment->getData(); if (!empty($result) && is_array($result) && array_key_exists('max_sequence_number', $result[0]) && $result[0]['max_sequence_number'] == $transaction->getInstallmentMasterSequenceNumber()) { foreach ($order->getInvoiceCollection() as $invoice) { $invoice->setState(Mage_Sales_Model_Order_Invoice::STATE_PAID)->save(); } } $order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, 'installment_plan_running')->save(); } else { // Increase auth attempt for installment master record and update date $date = NGC_Installment_Model_Master::calculateAmountDueDate(Mage::getStoreConfig('installment/grace_period_options/grace_period_days', $order->getStoreId())); $transaction->setInstallmentMasterAttemptToAuthorize($attempt)->setInstallmentMasterAmountDueDate($date)->save(); // Insert installment transaction record with failed auth details $installmentTrans = Mage::getModel('installment/transaction'); $installmentTrans->setOrderId($orderId)->setInstallmentTransactionTransactionSequenceNumber($attempt)->setInstallmentTransactionPaymentToken($payment->getCcTransId() . '-' . $payment->getPoNumber())->setInstallmentTransactionSequenceNumber($transaction->getInstallmentMasterSequenceNumber())->setInstallmentTransactionAuthorizeAmount($amount)->setInstallmentTransactionAuthorizeAttemptDate($currentDate)->setInstallmentTransactionDeclineCode($authorizeCode)->setInstallmentTransactionDeclineTransationMessage($payment->getDeclineCode())->setInstallmentTransactionCurrencyCode($currencyCode)->save(); $fmtAmount = $payment->getOrder()->getBaseCurrency()->formatTxt($amount); $message = Mage::helper('sales')->__('Failed to authorized & captured amount of %s for installment payment #%s', $fmtAmount, $transaction->getInstallmentMasterSequenceNumber()); $order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, 'installment_capture_failed', $message)->save(); if ($transaction->getInstallmentMasterAutoAdjust()) { NGC_Installment_Model_Master::autoAdjustInstallmentPayment($order, $transaction->getInstallmentMasterSequenceNumber()); } } } else { // Max auth attempts have been reached, suspend current & future installment payments and update as hard decline NGC_Installment_Model_Master::suspendInstallmentPayment($orderId, $transaction->getInstallmentMasterSequenceNumber()); } } else { // TODO: throw exception about being unable to load an order } } }
protected static function _refundPartialOrder($observer) { $creditMemo = $observer->getCreditmemo(); $order = $creditMemo->getOrder(); $payment = $order->getPayment(); $orderId = $order->getRealOrderId(); $newGrandTotal = $order->getGrandTotal(); $refunded = 0; $totalRefund = $creditMemo->getGrandTotal(); $totalPaid = self::getTotalPaid($orderId); $master = Mage::getModel('installment/master')->getCollection(); $master->addFieldToFilter('order_id', $orderId); if (self::isPlanComplete($orderId)) { $payment->getMethodInstance()->setStore($order->getStoreId())->refund($order->getPayment(), $totalRefund); $payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_REFUND, $payment, false, sprintf('Refunded amount of %s', $totalRefund))->save(); } else { // Customer has paid equal to the new grand total. Suspend future installment payments and close invoice if ($totalPaid == $newGrandTotal) { // Suspend all future installments if (!NGC_Installment_Model_Master::suspendInstallmentPayment($orderId, 1, 'Order was refunded')) { return Mage::throwException('Unable to suspend future installment payments'); } // Close invoice foreach ($order->getInvoiceCollection() as $invoice) { $invoice->setState(Mage_Sales_Model_Order_Invoice::STATE_PAID)->save(); } // Customer has paid less than the new grand total. Update future installments to take into // account the new order grand total } elseif ($totalPaid <= $newGrandTotal) { // Iterate installment payments and calculate the remaining amount due. $planTotal = $totalPaid; foreach ($master as $installment) { if (!$installment->getInstallmentMasterInstallmentPaid()) { $newTotal = $planTotal + $installment->getInstallmentMasterAmountDue(); // If the $newTotal plan total is less than the new grand total refund continue to next transaction if ($newTotal < $newGrandTotal) { $planTotal = $newTotal; continue; // If the $newTotal plan total is equal to the new grand total then suspend all future installments } elseif ($newTotal == $newGrandTotal) { $nextSeqNum = $installment->getInstallmentMasterSequenceNumber() + 1; if (!NGC_Installment_Model_Master::suspendInstallmentPayment($orderId, $nextSeqNum, 'Order was refunded')) { return Mage::throwException('Unable to suspend future installment payments'); } // The $newTotal plan total is greater than the new grand total. Calculate the difference, // decrease the installment payment by the difference, and suspend future payments } else { $totalDiff = $newTotal - $newGrandTotal; $newInstallmentTotal = $installment->getInstallmentMasterAmountDue() - $totalDiff; $installment->setInstallmentMasterAmountDue($newInstallmentTotal)->save(); $nextSeqNum = $installment->getInstallmentMasterSequenceNumber() + 1; if (!NGC_Installment_Model_Master::suspendInstallmentPayment($orderId, $nextSeqNum, 'Order was refunded')) { return Mage::throwException('Unable to suspend future installment payments'); } } } } // Customer has paid more than the new order grand total. Refund the difference and suspend any future // installment payments, close invoice, and mark order as complete } elseif ($totalPaid > $newGrandTotal) { $totalDiff = $totalPaid - $newGrandTotal; $payment->getMethodInstance()->setStore($order->getStoreId())->refund($order->getPayment(), $totalDiff); $payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_REFUND, $payment, false, sprintf('Refunded amount of %s', $totalRefund))->save(); $master = Mage::getModel('installment/master')->getCollection(); $master->addFieldToFilter('installment_master_installment_paided', 0)->addFieldToFilter('installment_master_installment_authorized', 0); foreach ($master as $installment) { $nextSeqNum = $installment->getInstallmentMasterSequenceNumber(); break; } // Suspend all future installments if (!NGC_Installment_Model_Master::suspendInstallmentPayment($orderId, $nextSeqNum, 'Order was refunded')) { return Mage::throwException('Unable to suspend future installment payments'); } // Close invoice foreach ($order->getInvoiceCollection() as $invoice) { $invoice->setState(Mage_Sales_Model_Order_Invoice::STATE_PAID)->save(); } } } }