Tuesday, March 27, 2012

Magento Order status does not convert to Processing

Tinkering around to make a payment gateway integration for iPay88 took me some really significant time.
I've been using some method from paypal module to redirect the form to ipay88,
and does a re-query to ipay88 server to determine the approve of transaction from ipay88.
On done, created an invoice and saved the transaction for the invoice.
Payment paid appears correctly, but some how order status still remain "pending".
I realized that i did not set the cctransid to the payment in my controller, 
so one way to do it is to pass the TransId from controller to payment method model.
To do this, create a model class to accommodate values from request form passed in from ipay88,
then in payment method model capture function, retrieve the ipay88 returned model and setCcTransId(...).
When done, the order will now be shown as "processing", depending on the setting in the admin configuration for the payment status on payment.

Sample below:
//getting config saved in admin:
$aConfig = Mage::getStoreConfig("payment/Ipay88");
$merchantcode = $aConfig["merchantcode"];
$oResponse = Mage::getSingleton("Ipay88/Api_Response");
//convert data from postback of ipay88 into oResponse as object data
Varien_Object_Mapper::accumulateByMap($_REQUEST, $oResponse, array(
  "MerchantCode", "PaymentId", "RefNo", "Amount", "Currency", "TransId", "AuthCode", "Status",
  "ErrDesc", "Signature", "Remark")
);

//codes to requery ipay88 for actual transaction
//...
if ($iPayResult == "00") {
  //success
  //update order status and payment status
 if ($oOrder->canInvoice()) {
  $invoice = Mage::getModel('sales/service_order', $oOrder)->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->setTransactionId($cctransid);
  //below this will trigger capture in method model
  $invoice->register();
  $transactionSave = Mage::getModel('core/resource_transaction')
  ->addObject($invoice)
  ->addObject($invoice->getOrder());
  
  $transactionSave->save();
 }
}
Next, in the payment method model capture:
public function capture(Varien_Object $payment, $amount)
{
 if (!$this->canCapture()) {
  Mage::throwException($this->_getHelper()->__('Capture action is not available.'));
 }
 
 $oResponse = Mage::getSingleton("Ipay88/Api_Response");
 $payment->setCcTransId($oResponse["TransId"]);
 return $this;
}
Sample of iPay88 Model to hold request data
class MercStudio_Ipay88_Model_Api_Response extends Varien_Object {
  
}
Yes, its an empty class which extends Varien_Object :) The Magic of Varien object is that it accept any data set to it (setVariablename(value) or setData("variablename", value)), and you may retrieve the data by calling getData("variablename")

No comments: