Magento Payment Review / подозрение в мошенничестве - PullRequest
3 голосов
/ 23 марта 2011

Я работаю в магазине Magento, где клиент запросил несколько пользовательских фильтров для заказов, чтобы их можно было просмотреть вручную перед отправкой на выполнение.Когда возникают эти случаи, заказы помечаются встроенным Проверка платежа / Подозрение на мошенничество состояние / статус.

Моя проблема в том, что в интерфейсе администратораПохоже, вы не можете сделать много с заказом в состоянии Payment Review .Я добавил пользовательскую кнопку типа «Одобрить» для ручного одобрения заказа, но если он будет рассмотрен и подтвержден как мошенничество, какое ожидаемое действие необходимо предпринять?Я бы подумал отменить или вернуть заказ, но это не разрешено.Проверка canCancel или canCreditmemo в заказе возвращает false.Было бы лучше использовать Hold state или что-то сверх Payment Payment для сценария, подобного этому?

Ответы [ 4 ]

8 голосов
/ 10 октября 2012

Вместо того, чтобы переопределять объект Mage_Sales_Model_Order (не совсем идеальный), я обнаружил некоторые существующие ловушки в наборе инструментов Magento, которые могут разрешать действия администратора после того, как ордер помечен с использованием статуса «Подозреваемое мошенничество». Чтобы включить их, необходимо выполнить следующие шаги:

В способе оплаты (унаследованный от Mage_Payment_Model_Method_Abstract) добавьте следующее:

    protected $_canReviewPayment  = true;

    public function acceptPayment(Mage_Payment_Model_Info $payment) {
        parent::acceptPayment($payment);
        //perform gateway actions to remove Fraud flags. Capture should not occur here
        return true;
        //returning true will trigger a capture on any existing invoices, otherwise the admin can manually Invoice the order
    }

    public function denyPayment(Mage_Payment_Model_Info $payment) {
        parent::denyPayment($payment);
        //if your payment gateway supports it, you should probably void any pre-auth
        return true;  
    }

Блок просмотра заказов Magento проверит $order->canReviewPayment(), который будет проверять переменную _canReviewPayment в способе оплаты, и, если он истинен, отобразит две кнопки в представлении заказа: «Принять платеж» и «Запретить платеж». При нажатии будут добавлены две новые функции «Способ оплаты», которые мы только что добавили выше.

Если у вас уже есть Счет, связанный с Заказом, это будет pay 'd или cancel' d. Посмотрите на Mage_Sales_Model_Order_Payment::registerPaymentReviewAction для более подробной информации.

3 голосов
/ 12 июня 2014

У нас есть клиенты с проблемой paygate, касающейся этого подозреваемого мошенничества или флага «мошенничества» для оплаты счета, когда paygate не уведомил Magento после того, как платеж был одобрен вручную.Похоже, это проблема с authorize.net и некоторыми конфигурациями авторизации и ответа PayPal.

Вот решение, состоящее из трех частей, которое я разработал, чтобы манипулировать заказом, по крайней мере, достаточно далеко, чтобы можно было создать кредитовое авизо, иочистить статус мошенничества.Этот процесс также создает доставку заказа и переводит заказ на «Обработка», а затем «Завершено».

Я сделал эти три изменения в локальной копии файла основного кода / public_html / app / code / local/Mage/Adminhtml/Block/Sales/Order/View.php

(1) Закомментированная строка кода и заменена строкой, которая позволяет кнопке кредитового авизо появляться, когда заказ находится в статусе Обработка или Завершено, даже если$ order-> canCreditmemo () не был правильно установлен равным true.

// if ($this->_isAllowedAction('creditmemo') && $order->canCreditmemo()) {
if ($this->_isAllowedAction('creditmemo') && ($order->getState() == 'complete' || $order->getState() == 'processing')) {

(2) Создана кнопка для очистки статуса мошенничества, которая вызывает функцию, указанную в # 3

// 06/10/2014 Rand created button on Admin panel to clear fraud AFTER payment is authorized manually.
if ($order->getStatus() === 'fraud') {
$message = Mage::helper('sales')->__('*** CAUTION *** Payment must FIRST be authorized manually. Are you sure you want to clear this fraud status?');
$this->addButton('clear_fraud', array(
    'label'     => Mage::helper('sales')->__('Clear Fraud'),
    'onclick'   => 'setLocation(\'' . $this->clearFraud($order) . '\')',
));
}

(3) Создана открытая функция clearFraud ($ order) для выполнения очистки счета к оплате, создания отправки (при необходимости) и очистки состояния $ order от 'мошенничества' до завершения.

public function clearFraud($order)
{
// THIS FUNCTION IS CREATED BY RAND TO HANDLE CLEARING INCOMPLETED RECORDS
// CREATED BY AUTHORIZE.NET FRAUD PROTECTION PROCESS

// setState of order invoice(s) to one that will accept order completion, and save it.
if ($order->hasInvoices()) {
    foreach ($order->getInvoiceCollection() as $invoice) {
        $invoice->setState('2');
        $invoice->save();
    }
}

// Handle Shipment: Create it (if needed) and save the transaction.
if (!$order->hasShipments()) {
    $shipment = $order->prepareShipment();
    $shipment->register();
    $order->setIsInProcess(true);
    $transactionSave = Mage::getModel('core/resource_transaction')
        ->addObject($shipment)
        ->addObject($shipment->getOrder())
        ->save();
    $order->save();
}

// Set order to complete, and save the order
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true);
$order->save();
$order->setState(Mage_Sales_Model_Order::STATE_COMPLETE, true);
$order->save();

return $this->getUrl('*/sales_order');
}

Это должно помочь вам решить, как заставить Magento вести себя так, как вы хотите.

2 голосов
/ 24 марта 2011

Я думаю, что семантически важно различать состояние Hold и Payment Payment , поэтому я бы порекомендовал вам сохранить отдельный статус / состояние и заставить его работать в клиентерабочий процесс.

Вы можете переопределить функции canCancel() и canCreditmemo(), чтобы они разрешали эти действия, когда заказ находится в состоянии проверки платежей.В вашем классе, который расширяет Mage_Sales_Model_Order, переопределите эти функции для проверки вашего пользовательского статуса / состояния.

HTH,
JD

0 голосов
/ 25 мая 2017

После поиска решения этой проблемы вариант с B.Sharp - единственное, что я нашел.Я смешал это с этим https://www.hummingbirduk.com/suspected-fraud-transactions-magento/ и добавил $ invoice-> sendEmail ();чтобы получить электронное письмо, отправленное клиенту.

В нашей ситуации статус «подозревается в мошенничестве» происходит случайным образом, тот же клиент с той же корзиной и той же учетной записью PayPal может получить его или нет.Ничего общего с округлением, налогом или валютой.

class Mage_Adminhtml_Block_Sales_Order_View extends Mage_Adminhtml_Block_Widget_Form_Container

{

public function __construct()
{
    $this->_objectId    = 'order_id';
    $this->_controller  = 'sales_order';
    $this->_mode        = 'view';

    parent::__construct();

    $this->_removeButton('delete');
    $this->_removeButton('reset');
    $this->_removeButton('save');
    $this->setId('sales_order_view');
    $order = $this->getOrder();
    $coreHelper = Mage::helper('core');

    if ($this->_isAllowedAction('edit') && $order->canEdit()) {
        $confirmationMessage = $coreHelper->jsQuoteEscape(
            Mage::helper('sales')->__('Are you sure? This order will be canceled and a new one will be created instead')
        );
        $onclickJs = 'deleteConfirm(\'' . $confirmationMessage . '\', \'' . $this->getEditUrl() . '\');';
        $this->_addButton('order_edit', array(
            'label'    => Mage::helper('sales')->__('Edit'),
            'onclick'  => $onclickJs,
        ));
        // see if order has non-editable products as items
        $nonEditableTypes = array_keys($this->getOrder()->getResource()->aggregateProductsByTypes(
            $order->getId(),
            array_keys(Mage::getConfig()
                ->getNode('adminhtml/sales/order/create/available_product_types')
                ->asArray()
            ),
            false
        ));
        if ($nonEditableTypes) {
            $confirmationMessage = $coreHelper->jsQuoteEscape(
                Mage::helper('sales')
                    ->__('This order contains (%s) items and therefore cannot be edited through the admin interface at this time, if you wish to continue editing the (%s) items will be removed, the order will be canceled and a new order will be placed.',
                    implode(', ', $nonEditableTypes), implode(', ', $nonEditableTypes))
            );
            $this->_updateButton('order_edit', 'onclick',
                'if (!confirm(\'' . $confirmationMessage . '\')) return false;' . $onclickJs
            );
        }
    }

    if ($this->_isAllowedAction('cancel') && $order->canCancel()) {
        $confirmationMessage = $coreHelper->jsQuoteEscape(
            Mage::helper('sales')->__('Are you sure you want to cancel this order?')
        );
        $this->_addButton('order_cancel', array(
            'label'     => Mage::helper('sales')->__('Cancel'),
            'onclick'   => 'deleteConfirm(\'' . $confirmationMessage . '\', \'' . $this->getCancelUrl() . '\')',
        ));
    }

    if ($this->_isAllowedAction('emails') && !$order->isCanceled()) {
        $confirmationMessage = $coreHelper->jsQuoteEscape(
            Mage::helper('sales')->__('Are you sure you want to send order email to customer?')
        );
        $this->addButton('send_notification', array(
            'label'     => Mage::helper('sales')->__('Send Email'),
            'onclick'   => "confirmSetLocation('{$confirmationMessage}', '{$this->getEmailUrl()}')",
        ));
    }

    //if ($this->_isAllowedAction('creditmemo') && $order->canCreditmemo()) {
    if ($this->_isAllowedAction('creditmemo') && ($order->getState() == 'complete' || $order->getState() == 'processing')) {
        $confirmationMessage = $coreHelper->jsQuoteEscape(
            Mage::helper('sales')->__('This will create an offline refund. To create an online refund, open an invoice and create credit memo for it. Do you wish to proceed?')
        );
        $onClick = "setLocation('{$this->getCreditmemoUrl()}')";
        if ($order->getPayment()->getMethodInstance()->isGateway()) {
            $onClick = "confirmSetLocation('{$confirmationMessage}', '{$this->getCreditmemoUrl()}')";
        }
        $this->_addButton('order_creditmemo', array(
            'label'     => Mage::helper('sales')->__('Credit Memo'),
            'onclick'   => $onClick,
            'class'     => 'go'
        ));
    }

    // invoice action intentionally
    if ($this->_isAllowedAction('invoice') && $order->canVoidPayment()) {
        $confirmationMessage = $coreHelper->jsQuoteEscape(
            Mage::helper('sales')->__('Are you sure you want to void the payment?')
        );
        $this->addButton('void_payment', array(
            'label'     => Mage::helper('sales')->__('Void'),
            'onclick'   => "confirmSetLocation('{$confirmationMessage}', '{$this->getVoidPaymentUrl()}')",
        ));
    }

    if ($this->_isAllowedAction('hold') && $order->canHold()) {
        $this->_addButton('order_hold', array(
            'label'     => Mage::helper('sales')->__('Hold'),
            'onclick'   => 'setLocation(\'' . $this->getHoldUrl() . '\')',
        ));
    }

    if ($this->_isAllowedAction('unhold') && $order->canUnhold()) {
        $this->_addButton('order_unhold', array(
            'label'     => Mage::helper('sales')->__('Unhold'),
            'onclick'   => 'setLocation(\'' . $this->getUnholdUrl() . '\')',
        ));
    }

    if ($this->_isAllowedAction('review_payment')) {
        if ($order->canReviewPayment()) {
            $confirmationMessage = $coreHelper->jsQuoteEscape(
                Mage::helper('sales')->__('Are you sure you want to accept this payment?')
            );
            $onClick = "confirmSetLocation('{$confirmationMessage}', '{$this->getReviewPaymentUrl('accept')}')";
            $this->_addButton('accept_payment', array(
                'label'     => Mage::helper('sales')->__('Accept Payment'),
                'onclick'   => $onClick,
            ));
            $confirmationMessage = $coreHelper->jsQuoteEscape(
                Mage::helper('sales')->__('Are you sure you want to deny this payment?')
            );
            $onClick = "confirmSetLocation('{$confirmationMessage}', '{$this->getReviewPaymentUrl('deny')}')";
            $this->_addButton('deny_payment', array(
                'label'     => Mage::helper('sales')->__('Deny Payment'),
                'onclick'   => $onClick,
            ));
        }
        if ($order->canFetchPaymentReviewUpdate()) {
            $this->_addButton('get_review_payment_update', array(
                'label'     => Mage::helper('sales')->__('Get Payment Update'),
                'onclick'   => 'setLocation(\'' . $this->getReviewPaymentUrl('update') . '\')',
            ));
        }
    }

    if ($this->_isAllowedAction('invoice') && $order->canInvoice()) {
        $_label = $order->getForcedDoShipmentWithInvoice() ?
            Mage::helper('sales')->__('Invoice and Ship') :
            Mage::helper('sales')->__('Invoice');
        $this->_addButton('order_invoice', array(
            'label'     => $_label,
            'onclick'   => 'setLocation(\'' . $this->getInvoiceUrl() . '\')',
            'class'     => 'go'
        ));
    }

    if ($this->_isAllowedAction('ship') && $order->canShip()
        && !$order->getForcedDoShipmentWithInvoice()) {
        $this->_addButton('order_ship', array(
            'label'     => Mage::helper('sales')->__('Ship'),
            'onclick'   => 'setLocation(\'' . $this->getShipUrl() . '\')',
            'class'     => 'go'
        ));
    }

    if ($this->_isAllowedAction('reorder')
        && $this->helper('sales/reorder')->isAllowed($order->getStore())
        && $order->canReorderIgnoreSalable()
    ) {
        $this->_addButton('order_reorder', array(
            'label'     => Mage::helper('sales')->__('Reorder'),
            'onclick'   => 'setLocation(\'' . $this->getReorderUrl() . '\')',
            'class'     => 'go'
        ));
    }


    // 06/10/2014 Rand created button on Admin panel to clear fraud AFTER payment is authorized manually.
    if ($order->getStatus() === 'fraud') {
            $message = Mage::helper('sales')->__('*** CAUTION *** Payment must FIRST be authorized manually. Are you sure you want to clear this fraud status?');
                $this->addButton('clear_fraud', array(
                    'label'     => Mage::helper('sales')->__('Clear Fraud'),
                    'onclick'   => 'setLocation(\'' . $this->clearFraud($order) . '\')',
                    'class'     => 'go'
                ));
        }



}

/**
 * Retrieve order model object
 *
 * @return Mage_Sales_Model_Order
 */
public function getOrder()
{
    return Mage::registry('sales_order');
}

/**
 * Retrieve Order Identifier
 *
 * @return int
 */
public function getOrderId()
{
    return $this->getOrder()->getId();
}

public function getHeaderText()
{
    if ($_extOrderId = $this->getOrder()->getExtOrderId()) {
        $_extOrderId = '[' . $_extOrderId . '] ';
    } else {
        $_extOrderId = '';
    }
    return Mage::helper('sales')->__('Order # %s %s | %s', $this->getOrder()->getRealOrderId(), $_extOrderId, $this->formatDate($this->getOrder()->getCreatedAtDate(), 'medium', true));
}

public function getUrl($params='', $params2=array())
{
    $params2['order_id'] = $this->getOrderId();
    return parent::getUrl($params, $params2);
}

public function getEditUrl()
{
    return $this->getUrl('*/sales_order_edit/start');
}

public function getEmailUrl()
{
    return $this->getUrl('*/*/email');
}

public function getCancelUrl()
{
    return $this->getUrl('*/*/cancel');
}

public function getInvoiceUrl()
{
    return $this->getUrl('*/sales_order_invoice/start');
}

public function getCreditmemoUrl()
{
    return $this->getUrl('*/sales_order_creditmemo/start');
}

public function getHoldUrl()
{
    return $this->getUrl('*/*/hold');
}

public function getUnholdUrl()
{
    return $this->getUrl('*/*/unhold');
}

public function getShipUrl()
{
    return $this->getUrl('*/sales_order_shipment/start');
}

public function getCommentUrl()
{
    return $this->getUrl('*/*/comment');
}

public function getReorderUrl()
{
    return $this->getUrl('*/sales_order_create/reorder');
}

/**
 * Payment void URL getter
 */
public function getVoidPaymentUrl()
{
    return $this->getUrl('*/*/voidPayment');
}

protected function _isAllowedAction($action)
{
    return Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/' . $action);
}

/**
 * Return back url for view grid
 *
 * @return string
 */
public function getBackUrl()
{
    if ($this->getOrder()->getBackUrl()) {
        return $this->getOrder()->getBackUrl();
    }

    return $this->getUrl('*/*/');
}

public function getReviewPaymentUrl($action)
{
    return $this->getUrl('*/*/reviewPayment', array('action' => $action));
}


public function clearFraud($order)
{


    $order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true);
    $order->setStatus('processing', false);
    $order->save();
    try {
        if(!$order->canInvoice()) {
            Mage::throwException(Mage::helper('core')->__('Cannot create an invoice.'));
        }
        $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
        if (!$invoice->getTotalQty()) {
            Mage::throwException(Mage::helper('core')->__('Cannot create an invoice without products.'));
        }
        $invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE);
        $invoice->register();
        $invoice->sendEmail();
        $transactionSave = Mage::getModel('core/resource_transaction')->addObject($invoice)->addObject($invoice->getOrder());
        $transactionSave->save();
        } catch (Mage_Core_Exception $e) {
    }





    return $this->getUrl('*/sales_order');
}

}

...