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
{
protected $_code = 'yourPaymentCode';
protected $_isGateway = true;
protected $_canCapture = false;
protected $_canAuthorize = false;
protected $_canOrder = true;
public function order(Varien_Object $payment, $amount)
{
$gateway->init( $amount,
$payment->getOrder()->getId(),
$returnUrl,
...);
if($gateway->isSuccess()) {
$payment->setTransactionId($gateway->getTransactionId());
} else {
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()
{
$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() );
$quote = Mage::getModel('sales/quote')->load( $order->getQuoteId() );
$quote->setIsActive( true )->save();
$order->cancel()->save();
$this->_redirect('checkout/onepage');
}
}