3

My payment module is required to sent notifications to the payment service if an order is canceled or refunded. I assume that the "Cancel" button on the order page (in the administration backend) will cancel the order, and that the "Credit memo" button (after an invoice has been created) will refund the order.

How do I run my code on these events? I tried using the cancel() method in my payment method model, but the code did not run.

hakre
  • 193,403
  • 52
  • 435
  • 836
  • I could be way off here but would you run the charge again but with the amount being negative? Original Charge: $5.00, Cancelled/Refund Charge -$5.00 Just a thought – Phill Pafford Jan 25 '11 at 18:46

3 Answers3

2

No observable events are fired during the Payment processing stage of Magento. Instead, you define a class for whatever gateway you're implementing, and then define methods that Magento will automatically call as an order makes it's way through the various payment methods.

Poke around the base abstract payment class to see the various methods that will be called during payment processing. Define the same methods in your class to hook into the payment process at whatever point you'd like.

File: app/code/core/Mage/Payment/Model/Method/Abstract.php

class abstract class Mage_Payment_Model_Method_Abstract
{

    /**
     * Authorize
     *
     * @param   Varien_Object $orderPayment
     * @return  Mage_Payment_Model_Abstract
     */
    public function authorize(Varien_Object $payment, $amount)
    ...     
    /**
     * Capture payment
     *
     * @param   Varien_Object $orderPayment
     * @return  Mage_Payment_Model_Abstract
     */
    public function capture(Varien_Object $payment, $amount)    
    ... 

    /**
     * Void payment
     *
     * @param   Varien_Object $invoicePayment
     * @return  Mage_Payment_Model_Abstract
     */
    public function void(Varien_Object $payment)
    ...    

    /**
     * Refund money
     *
     * @param   Varien_Object $invoicePayment
     * @return  Mage_Payment_Model_Abstract
     */
    //public function refund(Varien_Object $payment, $amount)
    public function refund(Varien_Object $payment, $amount)
    ...


    /**
     * Cancel payment (GoogleCheckout)
     *
     * @param   Varien_Object $invoicePayment
     * @return  Mage_Payment_Model_Abstract
     */
    public function cancel(Varien_Object $payment)
    ...

I don't do a lot of Payment Gateway implementations, but I'm guessing that refund is the method you want for credit memos, and capture is the one for invoices. It looks like the cancel method is something specific to Google Checkout. Define all five in your class with some logging functions and walk though some fake orders on your development system if you want to know for sure.

Alana Storm
  • 164,128
  • 91
  • 395
  • 599
2

Seems like your payment method is not using transactions or does not create authorization transaction id. It is common beginner mistake in Payment gateways development.

To enable your payment gateway with online actions you need to implement something like this in your payment method:

class MyBest_Payment_Model_Method extends Mage_Payment_Model_Method_Abstract
{
    protected $_canAuthorize            = true; // Set true, if you have authorization step.
    protected $_canCapture              = true; // Set true, if you payment method allows to perform capture transaction (usally only credit cards methods)
    protected $_canRefund               = true; // Set true, if online refunds are available
    protected $_canVoid                 = true; // Set true, if you can cancel authorization via API online

    public function authorize(Varien_Object $payment, $amount)
    { 

        // ... You payment method authorization goes here ...
        // Here goes retrieving or generation non-zero, 
        // non-null value as transaction ID. 
        $transactionId = $api->someCall(); 
        // Setting tranasaction id to payment object
        // It is improtant, if you want perform online actions 
        // in future with this order!
        $payment->setTransactionId($transactionId); 

        // ... some other your actions ... 
        return $this;
    }

    public function void(Varien_Object $payment)
    {
        // ... some actions for sending cancel notification to your payment gateway
    }

    public function refund(Varien_Object $payment, $amount)
    {
        // ... some actions for performing an online refund ...
    }
}
Ivan Chepurnyi
  • 9,233
  • 1
  • 43
  • 43
  • I've tried this and it does not quite work. The refund() method seem to only work for online refunds done through the invoice page (not the Credit Memo button on the order page). The void() method is not called at all, neither is authorize() - no transaction is created – Troubled Magento user Jan 26 '11 at 12:34
  • @Troubled Magento user, You should use it on order with transaction that is set propertly. Old orders will not work, because such data wasn't stored at that time. By the way, creadit memo button on the order page creates offline refund (i.e. refund without sending notification). In authorize method you should create a transaction, not Magento, because transaction depends on your gateway. – Ivan Chepurnyi Jan 26 '11 at 12:36
  • @Troubled Magento user, void method is called only if you have opened authorization transaction, i.e., if the payment was not captured (without invoice) or if it has ability to perform a partial capture (the invoice not covers all the order items). Seems like Magento payment system needs good explanation, unfortunatelly don't have enough time for article now... – Ivan Chepurnyi Jan 26 '11 at 12:43
  • Hi, you note that 'setTransactionId' is required for the refund and void functions to work properly, however in the latest versions of Magento (1.6 / 1.7) I can only find the last_trans_id in the payments table in the database, has this changed or am I missing something? – sg3s Jan 31 '13 at 09:29
  • @sg3s `setTransactionId()` starts creation of new record in transactions table, it is not stored anymore in order_payment table, last trans id is reference to transaction that is available in transactions table. – Ivan Chepurnyi Jan 31 '13 at 16:14
1

Magento has event hooks that might be helpful. A list of events (a bit outdated, I think) can be found here. And there is a useful article about how Magneto's events work here.

Also, looking at existing payment extensions could be useful. I would not be surprised if similar events are dispatched by Google Checkout for order cancellations. The Extension repository will have lots of payment methods to look at.

Good luck!

thaddeusmt
  • 15,410
  • 9
  • 67
  • 67