0
votes

I am working on API based Payment gateway in magento, When user directly pay from credit card, I am doing my all process by calling api specific function in capture method of payment gateway.

When I will enable 3D secure option for payment gateway I need to redirect user to 3rdparty for verification for that I am using getOrderPlaceRedirectUrl with condition.

With Condition I ma also saving order with pending status but Magento generate the invoice and mark as paid and change status to processing. that I need to do once get successful authentication from 3rdparty.

for updating order status using following code:

$order->setState( Mage_Sales_Model_Order::STATE_NEW, true );
$order->save();

If anyone can help how can I control to not generate invoice in capture method will be very appreciated.

2

2 Answers

1
votes

If you use capture() in your payment method, and your capture() method returns without throwing an exception, then Magento assumes that the capture is done, "the money is in your pocket", so it makes the invoice. This is not good if you use a 3rd party payment gateway.

You can do the following: set your *payment_action* to order in your config.xml

<config>     
    <default>
        <payment>
            <yourPaymentCode>
                <order_status>pending_payment</order_status>
                <payment_action>order</payment_action>
                ...

In your payment method set the attributes and implement the order() method. Snd set getOrderPlaceRedirectUrl, but you already did that.

class Your_Module_Model_PaymentMethod 
    extends Mage_Payment_Model_Method_Abstract
{
    // set these attributes
    protected $_code = 'yourPaymentCode';
    protected $_isGateway = true;
    protected $_canCapture = false;
    protected $_canAuthorize = false;
    protected $_canOrder = true;

    public function order(Varien_Object $payment, $amount)
    {
        // initialize your gateway transaction as needed
        // $gateway is just an imaginary example of course
        $gateway->init( $amount, 
            $payment->getOrder()->getId(), 
            $returnUrl,
            ...);
        if($gateway->isSuccess()) {
            // save transaction id
            $payment->setTransactionId($gateway->getTransactionId());
        } else {
            // this message will be shown to the customer
            Mage::throwException($gateway->getErrorMessage());
        }
        return $this;
    }

And somehow the gateway has to respond. In my case they redirect the customer to $responseUrl given in init(), but they warn that it is possible that the user's browser crashes after payment but before they can be redirected to our store: In that case they call the URL in the background, so handling that URL cannot rely on session data. I made a controller for this:

public function gatewayResponseAction()
{
    // again the imaginary example $gateway
    $order = Mage::getModel('sales/order')->load( $gateway->getOrderId() );
    $payment = $order->getPayment();
    $transaction = $payment->getTransaction( $gateway->getTransactionId() );

    if ($gateway->isSuccess())
    {
        $payment->registerCaptureNotification( $gateway->getAmount() );
        $payment->save();
        $order->save();
        $this->_redirect('checkout/onepage/success');
    }
    else
    {
        Mage::getSingleton('core/session')
            ->addError($gateway->getErrorMessage() );
        // set quote active again, and cancel order 
        // so the user can make a new order
        $quote = Mage::getModel('sales/quote')->load( $order->getQuoteId() );
        $quote->setIsActive( true )->save();
        $order->cancel()->save();
        $this->_redirect('checkout/onepage');
    }
}
0
votes

Try setting the state to pending payment, something like the following;

$order->setState(Mage_Sales_Model_Order::STATE_PENDING_PAYMENT, 
    'pending_payment', 
    '3D Secure Auth Now Taking Place')->save();

P.S. The PayPal module that comes with Magento does exactly what you are trying to do, so take a look at PayPal Standard model and controller for some pointers.