No Transaction ID in Payment Invoice - magento

I've developed a Payment Method extension for Magento. In this extension, I've added:
protected $_canRefund = true;
However, when I click an invoice and select Credit Memo, I can only see 'Refund Offline' and not 'Refund'. All tutorials I followed insist that I only have to change that value to true to activate the button (obviously I still have to implement the refund method and the actual refund procedure) but I can't see a way to do this.
If I, within a block on the order screen, execute this line $order->getPayment()->getMethodInstance()->canRefund(); it does indeed return true, but still no luck with the actual credit memo.
Edit
I've changed the title of the question to reflect my new find.
Basically, the reason it's not appearing is because my invoices aren't created with transaction IDs - I have no idea why, but this is my capture payment method that runs when generating an invoice:
public function capturePayment($order) {
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_ONLINE);
$invoice->register();
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder());
$transactionSave->save();
$order->setState('processing', 'payment_received', "Payment has been received", false);
$order->save();
} catch (Mage_Core_Exception $e) {
Mage::throwException("Error Taking Payment, Please Try Again:\n" . $e);
}
}
Why isn't a transaction ID being assigned to my capture?

check below url
http://www.spinonesolutions.com/2009/10/magento-enable-paygate-refunds/
https://magento.stackexchange.com/questions/7846/capture-void-refund-not-showed-in-magento-admin-area
http://excellencemagentoblog.com/magento-create-custom-payment-method-api-based
hope this help you

Related

Magento OPC Observer redirect

I'm struggling with a special little problem related to the redirect out of some Magento observer.
I wrote an extension and put an observer to the "checkout_submit_all_after" event, which works out just fine. My little extension automatically creates an invoice and sets the order status to processing, once the payment method is "Invoice". Unfortunately the redirect after submitting an order in the one page checkout doesn't work anymore. It always redirects to "checkout/cart" instead of "checkout/onepage/success".
Someone any ideas what I'm doing wrong?
Here's my code:
class Shostra_AutoInvoice_Model_Order_Observer
{
public function __construct()
{
}
public function auto_create_invoice($observer)
{
$order = $observer->getEvent()->getOrder();
if (!$order->hasInvoices()) {
$payment = $order->getPayment()->getMethodInstance()->getTitle();
Mage::log("payment method: " . $payment);
if($payment=="Rechnung"){
Mage::log("autocreating invoice");
$invoice = $order->prepareInvoice();
$invoice->register();
$invoice->pay();
$invoice->save();
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();
Mage::log("invoice created and saved");
}
$this->addComment('Order automatically set to paid.');
} else {
$this->addComment('no invoices found.');
}
$response = $observer->getResponse();
$response->setRedirect(Mage::getUrl('checkout/onepage/success'));
Mage::getSingleton('checkout/session')->setNoCartRedirect(true);
}
}
Thanks a lot!
Why don't you try sales_order_save_after event and try saving it, so no issues with redirection manually as Magento will take its own course,
you can refer to this link for more explanation
http://inchoo.net/magento/magento-orders/automatically-invoice-ship-complete-order-in-magento/

magento update Total Paid after payment

I have my own custom payment gateway which is working ok with one problem. When a transaction is successful the order gets updated and the email sent but the Total paid is still €0.
How do I update the paid status? I cannot find any articles on this.
Magento 1.7
public function responseAction() {
if($this->getRequest()->isPost()) {
if($payment_validated) {
// Payment was successful, so update the order's state, send order email and move to the success page
$order = Mage::getModel('sales/order');
$order->loadByIncrementId($orderId);
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true, 'AIB has authorized the payment.');
$order->sendNewOrderEmail();
$order->setEmailSent(true);
$order->save();
Mage::getSingleton('checkout/session')->unsQuoteId();
Mage_Core_Controller_Varien_Action::_redirect('checkout/onepage/success', array('_secure'=>true));
}
This answer might be little out of date but still someone might find it helpful.
I myself found this question and wanted an answer for this one.
So i found a very helpful article at atwix and specifically I used:
$orderId = 200000025; // you'll get your own Order Id
$model = Mage::getModel('sales/order');
$model->loadByIncrementId($orderId);
$invoice = $model->prepareInvoice();
$invoice->register();
Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder())
->save();
$invoice->sendEmail(true, '');
if($model->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)) {
$model->save();
}
So after this I got payment status to Paid in the backend and also changed the status to processing.
Now next step is to let customer know that he's order has been paid and I would like to do it via email.
Cheers!!

Send account confirmation email to specific customer group in magento

How to send account confirmation email to specific customer group in magento
I want to send confirmation email only a specific customer group. please any one can help in this issue....
I already save the customer group during registration or new account creation by using below link:-
http://phpmagento.blogspot.in/2012/01/how-to-show-customer-group-selecter-in.html
Go to the \app\code\core\Mage\Customer\Model\Customer.php
replace
<pre>
public function isConfirmationRequired()
{
if ($this->canSkipConfirmation()) {
return false;
}
if (self::$_isConfirmationRequired === null) {
$storeId = $this->getStoreId() ? $this->getStoreId() : null;
self::$_isConfirmationRequired = (bool)Mage::getStoreConfig(self::XML_PATH_IS_CONFIRM, $storeId);
}
return self::$_isConfirmationRequired;
}
</pre>
with:
public function isConfirmationRequired()
{
if ($this->canSkipConfirmation()) {
return false;
}
if (self::$_isConfirmationRequired === null) {
$storeId = $this->getStoreId() ? $this->getStoreId() : null;
if($this->getGroupId() == 2) {
self::$_isConfirmationRequired = (bool)Mage::getStoreConfig(self::XML_PATH_IS_CONFIRM, $storeId);
}
}
return self::$_isConfirmationRequired;
}
</pre>
Where 2 is the wholesale group Id.
Account confirmation email is sent when creating customer.
Customer group is added to customer after customer account is created.
So it's not possible to send confirmation email to only a specifik customer groep.
I Don't think you can without do some customization in magento.
Try
Disable All Email Confirmation. see How To Enable/Disable Email confirmation for New Account
Then create an observer for on customer save. see magento customer_save_after model / observer not called, catch customer -> edit -> save function
Check to see if the customer is a new customer and in the correct group (may need to check if the got confirmation email before)
Copy the logic that send Email confirmation from base magento into your observer

Mark order as pending in capture method in custom Payment Method

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.
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');
}
}
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.

Stop Magento from emptying the shopping cart before payment confirmation?

This is one of the most vital problems I have found since I started testing Magento for my web store. It's kind of a no-brainer that it's absolutely unnecessary and harmful to sales to empty cart before payment confirmation, which unfortunately, Magento does.
If the user selects PayPal (website standard) for payment method and for some reason clicks "Back to xxxx" (your business name at PayPal) on the PayPal payment page without paying, PayPal would redirect the user back to http://www.example.com/checkout/cart/, which now is an EMPTY cart.
I think it should be after payment confirmation / PayPal IPN that the cart be empty-ed, instead of any point before that.
Even if the user wants to continue again, he or she'd be annoyed from searching and adding all the products again and would very probably just leave.
Any idea how I can work around this?
This worked for me:
File: ~/app/code/core/Mage/Checkout/controllers/OnepageController.php
Replace this:
$this->getOnepage()->getQuote()->save();
/**
* when there is redirect to third party, we don't want to save order yet.
* we will save the order in return action.
*/
if (isset($redirectUrl)) {
$result['redirect'] = $redirectUrl;
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
With this one:
/**
* when there is redirect to third party, we don't want to save order yet.
* we will save the order in return action.
*/
if (isset($redirectUrl)) {
$result['redirect'] = $redirectUrl;
$this->getOnepage()->getQuote()->setIsActive(1) ;
}
$this->getOnepage()->getQuote()->save();
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
For Paypal I found the cancel action inside the app/code/core/Mage/Paypal/controllers/StandardController.php cancelAction
I changed the code like that for cancel action
public function cancelAction()
{
$session = Mage::getSingleton('checkout/session');
$cart = Mage::getSingleton('checkout/cart');
$session->setQuoteId($session->getPaypalStandardQuoteId(true));
if ($session->getLastRealOrderId()) {
$incrementId = $session->getLastRealOrderId();
if (empty($incrementId)) {
$session->addError($this->__('Your payment failed, Please try again later'));
$this->_redirect('checkout/cart');
return;
}
$order = Mage::getModel('sales/order')->loadByIncrementId($session->getLastRealOrderId());
$session->getQuote()->setIsActive(false)->save();
$session->clear();
try {
$order->setActionFlag(Mage_Sales_Model_Order::ACTION_FLAG_CANCEL, true);
$order->cancel()->save();
} catch (Mage_Core_Exception $e) {
Mage::logException($e);
}
$items = $order->getItemsCollection();
foreach ($items as $item) {
try {
$cart->addOrderItem($item);
} catch (Mage_Core_Exception $e) {
$session->addError($this->__($e->getMessage()));
Mage::logException($e);
continue;
}
}
$cart->save();
$session->addError($this->__('Your payment failed. Please try again later'));
}
$this->_redirect('checkout/cart');
}
It worked pretty good for me and there is no need to change any other place for that.
It marks the current order as Cancelled and restores the cart with using that order and redirects the user to cart again.
/app/code/core/Mage/Checkout/controllers/OnepageController.php this file is the actual controller file, but depends up on the payment method extensions it will change with Namespace/Modulename/Checkout/controllers/OnepageController.php
Find function saveOrderAction()
find these lines
$this->getOnepage()->getQuote()->save();
/**
* when there is redirect to third party, we don't want to save order yet.
* we will save the order in return action.
*/
if (isset($redirectUrl)) {
$result['redirect'] = $redirectUrl;
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
comment this line //$this->getOnepage()->getQuote()->save();
and add below codes inside the if condition so the condition will look like ..
//$this->getOnepage()->getQuote()->save();
if (isset($redirectUrl)) {
$result['redirect'] = $redirectUrl;
$this->getOnepage()->getQuote()->setIsActive(1) ;
}
$this->getOnepage()->getQuote()->save();
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
This is i have done with the third party Payment extension.
Since Magento version 1.6.0.0 (juli 2011) you can enable "Persistent Shopping Cart"
under
System > Configuration > Customers > Persistent Shopping Cart
This should solve this problem.
Use these settings to make it work
Enable Persistence = Yes
Persistence Lifetime (seconds) = 31536000
Enable "Remember Me" = Yes
"Remember Me" Default Value = Yes
Clear Persistence on Log Out = No
Persist Shopping Cart = Yes
Good luck :)
Your issue is with the way Mage_Checkout_OnepageController::saveOrderAction() behaves.
More specific: open app/code/core/Mage/Checkout/controllers/OnepageController.php
$this->getOnepage()->getQuote()->save();//this makes the cart empty (sets the quote as converted to order)
if (isset($redirectUrl)) {
$result['redirect'] = $redirectUrl;
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
}
You can replace the last part:
$this->getOnepage()->getQuote()->save();//....
with:
if (isset($redirectUrl)) {
$result['redirect'] = $redirectUrl;
$this->getOnepage()->getQuote()->setIsActive(1) ;
}
$this->getOnepage()->getQuote()->save();
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));

Resources