Reputation: 6305
My function to capture the transaction on auth.net is
public function capture(Varien_Object $payment, $amount){
if(!$this->isEnabled()){
return parent::capture($payment, $amount);
}else{
$captureCase = $_POST['invoice']['capture_case'];
if(isset($captureCase) && $captureCase == "online"){
if($capOrderid = $payment->getOrder()->getIncrementId()){
$capOrder = $payment->getOrder();
$capPayment = $payment;
$capAmount = $amount;
$capTransID = $capPayment->getLastTransId();
$ccProfile = $this->getProfileForOrder($capOrderid);
if(isset($ccProfile['used_this_profile']) && $ccProfile['used_this_profile'] == 1){
$pID = $ccProfile['cust_profile_id'];
$ppID = $ccProfile['cust_paymentprofile_id'];
$nick = $ccProfile['nickname'];
$lastOrderId = $capOrder->getIncrementId();
$cvv = $payment->getCcCid();
$directResponseFields = $this->createTransaction($pID,$ppID,$capAmount,$lastOrderId,"profileTransPriorAuthCapture",$cvv,$capTransID);
$responseCode = $directResponseFields[0]; // 1 = Approved 2 = Declined 3 = Error
$responseReasonCode = $directResponseFields[2]; // See http://www.authorize.net/support/AIM_guide.pdf
$responseReasonText = $directResponseFields[3];
$approvalCode = $directResponseFields[4]; // Authorization code
$transId = $directResponseFields[6];
switch ($responseCode) {
case "1":
$capPayment->setStatus(self::STATUS_APPROVED);
$capPayment->setCcTransId($transId);
$capPayment->setLastTransId($transId);
if (!$capPayment->getParentTransactionId() || $transId != $capPayment->getParentTransactionId()) {
$capPayment->setTransactionId($transId);
}
return true;
break;
case "2":
Mage::throwException(__('Payment authorization transaction has been declined.'));
break;
default:
Mage::throwException(__('Payment authorization error.'));
break;
}
}
}
}elseif(!isset($captureCase)){
$oldorderid = Mage::getModel('adminhtml/sales_order_create')->getSession()->getOrder()->getIncrementId();
if(isset($oldorderid) && ($oldorderid != $payment->getOrder()->getIncrementId())){ // if order is created from admin and has an order to refund first.
$oldOrder = Mage::getModel('sales/order')->loadByIncrementId($oldorderid);
$oldPayment = $oldOrder->getPayment();
$oldAmount = $oldPayment->getAmountOrdered();
$transID = $oldPayment->getLastTransId();
$ccProfile = $this->getProfileForOrder($oldorderid);
if(isset($ccProfile['used_this_profile']) && $ccProfile['used_this_profile'] == 1){
$pID = $ccProfile['cust_profile_id'];
$ppID = $ccProfile['cust_paymentprofile_id'];
if($directResponseFields = $this->refundCIM($pID,$ppID,$transID,$oldorderid,$oldAmount)){
$responseCode = $directResponseFields[0]; // 1 = Approved 2 = Declined 3 = Error
$responseReasonCode = $directResponseFields[2]; // See http://www.authorize.net/support/AIM_guide.pdf
$responseReasonText = $directResponseFields[3];
$approvalCode = $directResponseFields[4]; // Authorization code
$transId = $directResponseFields[6];
switch ($responseCode) {
case "1":
//$oldPayment->setStatus(self::STATUS_SUCCESS);
$oldOrder->cancel()->save();
//$oldPayment->setIsTransactionClosed(1);
$oldOrder->setState(Mage_Sales_Model_Order::STATE_CANCELED, true)->save();
//$oldOrder->setState(Mage_Sales_Model_Order::STATE_CLOSED, true)->save();
//Mage::throwException(__("a".$responseCode));
//return $this;
break;
case "4":
Mage::throwException(__('Error Code 4. You cannot refund an unsettled transaction.'));
break;
default:
if(isset($responseReasonText) && !empty($responseReasonText)){
Mage::throwException(__("Code: ".$responseReasonCode." - ".$responseReasonText));
}else{
Mage::throwException(__('Error in refunding the payment. This can happen if the customer has deleted their profile from CIM.'));
}
break;
}
}
}else if(isset($transID) && $oldAmount > 0) {
$oldPayment->setAnetTransType(self::REQUEST_TYPE_CREDIT);
$oldRequest = $this->_buildRequest($oldPayment);
$oldRequest->setXTransId($transID);
$oldPayment->setXAmount($oldAmount,2);
$oldRequest->setXCurrencyCode($oldOrder->getBaseCurrencyCode());
$oldRequest->setXCardNum($oldPayment->getCcLast4());
$oldResult = $this->_postRequest($oldRequest);
if ($oldResult->getResponseCode()==self::RESPONSE_CODE_APPROVED) {
$oldPayment->setStatus(self::STATUS_SUCCESS);
$oldOrder->cancel()->save();
}else{
Mage::throwException($this->_wrapGatewayError($oldResult->getResponseReasonText())); //////////error here/////////
}
}else{
Mage::throwException(Mage::helper('authnet')->__('Error in refunding the payment.'));
}
}
}
$quote = Mage::getSingleton('customer/session');
$nickname = $quote->getAuthorizenetNickname();
$profile = $quote->getProfile();
$postedNickname = $quote->getNickname();
if(!isset($nickname) || $nickname == "" || $nickname == "nnnew"){
if ($amount <= 0) {
Mage::throwException(Mage::helper('authnet')->__('Invalid amount for authorization.'));
}
if ($payment->getCcTransId()) {
$payment->setAnetTransType(self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE);
} else {
$payment->setAnetTransType(self::REQUEST_TYPE_AUTH_CAPTURE);
}
$payment->setAmount($amount);
$request= $this->_buildRequest($payment);
$result = $this->_postRequest($request);
if ($result->getResponseCode() == self::RESPONSE_CODE_APPROVED) {
$payment->setStatus(self::STATUS_APPROVED);
$payment->setCcTransId($result->getTransactionId());
$payment->setLastTransId($result->getTransactionId());
if (!$payment->getParentTransactionId() || $result->getTransactionId() != $payment->getParentTransactionId()) {
$payment->setTransactionId($result->getTransactionId());
}
if(isset($profile) && $profile == "save"){
$order = $payment->getOrder();
$billing = $order->getBillingAddress();
$ccno = $payment->getCcNumber();
$exp = sprintf('%04d-%02d', $payment->getCcExpYear(), $payment->getCcExpMonth());
$cvv = $payment->getCcCid();
$email = $order->getCustomerEmail();
$orderId = $order->getIncrementId();
if($profiles = $this->getCustId($email)){
foreach ($profiles as $_nickname => $cust_profile_id){
if($_nickname == $postedNickname){
Mage::throwException(__('Nickname already in use.'));
}
}
$profileId = $cust_profile_id;
}else{
$profileId = $this->createProfile($payment,true);
}
if($profileId && $profileId != 1){
$ppId = $this->createPaymentProfile($billing,$profileId,$ccno,$exp,$postedNickname,$email,$cvv,true);
$this->assignNicknameToOrder($orderId,$profileId,$ppId,$postedNickname,0);
}
}
return $this;
}
if ($result->getResponseReasonText()) {
Mage::throwException($this->_wrapGatewayError($result->getResponseReasonText()));
}
Mage::throwException(Mage::helper('paygate')->__('Error in capturing the payment.'));
}else if($nickname != "" && $nickname != "nnnew"){
$selectedNickname = $nickname;
$conn_selected = $this->conn();
$results_selected = $conn_selected->query("SELECT * FROM ".$this->getTable()." WHERE cust_paymentprofile_id = '".$selectedNickname."'");
while ($row = $results_selected->fetch() ) {
$pID = $row['cust_profile_id'];
$nick = $row['nickname'];
}
$ppID = $selectedNickname;
$order = $payment->getOrder();
$lastOrderId = $order->getIncrementId();
$cvv = $payment->getCcCid();
$directResponseFields = $this->createTransaction($pID,$ppID,$amount,$lastOrderId,"profileTransAuthCapture",$cvv);
$responseCode = $directResponseFields[0]; // 1 = Approved 2 = Declined 3 = Error
$responseReasonCode = $directResponseFields[2]; // See http://www.authorize.net/support/AIM_guide.pdf
$responseReasonText = $directResponseFields[3];
$approvalCode = $directResponseFields[4]; // Authorization code
$transId = $directResponseFields[6];
switch ($responseCode) {
case "1":
$payment->setStatus(self::STATUS_APPROVED);
//$payment->setCcTransId($result->getTransactionId());
$payment->setLastTransId($transId);
if (!$payment->getParentTransactionId() || $transId != $payment->getParentTransactionId()) {
$payment->setTransactionId($transId);
}
$this->assignNicknameToOrder($lastOrderId,$pID,$ppID,$nick,1);
return true;
break;
case "2":
Mage::throwException(__('Payment authorization transaction has been declined.'));
break;
default:
Mage::throwException(__('Payment authorization error.'));
break;
}
}
Mage::throwException(Mage::helper('paygate')->__('Error in capturing the payment.'));
}
}
the issue comes randomly when I try to Caputre an already authorized amount..Dump of my transaction request is
[request] => Array
(
[x_version] => 3.1
[x_delim_data] => True
[x_relay_response] => False
[x_test_request] => FALSE
[x_login] => ****
[x_tran_key] => ****
[x_type] => PRIOR_AUTH_CAPTURE
[x_method] => CC
[x_invoice_num] => dummy
[x_amount] => 127.48
[x_currency_code] => USD
[x_trans_id] =>
[x_first_name] => dummy
[x_last_name] => dummyl
[x_company] =>
[x_address] => dummy Apt 67
[x_city] => dummy
[x_state] => California
[x_zip] => dummy
[x_country] => US
[x_phone] => dummy
[x_fax] =>
[x_cust_id] =>
[x_customer_ip] => 68.183xxxxx8
[x_customer_tax_id] =>
[x_email] => [email protected]
[x_email_customer] => 0
[x_merchant_email] =>
[x_ship_to_first_name] =>dummy
[x_ship_to_last_name] => dummy
[x_ship_to_company] =>
[x_ship_to_address] => dummy Blvd.
[x_ship_to_city] => dummy
[x_ship_to_state] => dummy
[x_ship_to_zip] => dummy
[x_ship_to_country] => US
[x_po_num] =>
[x_tax] => 0.0000
[x_freight] => 0.0000
)
and the response is
[result] => Array
(
[response_code] => 3
[response_subcode] => 2
[response_reason_code] => 33
[response_reason_text] => A valid referenced transaction ID is required.
[approval_code] =>
[avs_result_code] => P
[transaction_id] => 0
[invoice_number] => 100dddd38
[description] =>
[amount] => 127.48
[method] => CC
[transaction_type] => prior_auth_capture
[customer_id] =>
[md5_hash] => dummy
[card_code_response_code] =>
[c_av_vresponse_code] =>
[split_tender_id] =>
[acc_number] =>
[card_type] =>
[requested_amount] =>
[balance_on_card] =>
)
I noted that Transaction ID
is missing In my Request, the Auth.net developer site says the same ..Some times the orders get captured, but most of time, they dont..I also noted that both successful captures and unsuccessfull captures,transaction ID exists in Magento ( I can view it in in admin panel, see this
When I try to create invoice and capture transaction via mag admin, I get the error
Gateway error: A valid referenced transaction ID is required.
I am wondering why this Happening..Can somebody help me>? any idea?
My plate form is Magento Enterpise (1.12.x) and the extension I am trying to get working is Elayers ( I did not purchased it, working for someone)
Upvotes: 29
Views: 2981
Reputation: 283
TransctionID is being hidden when you're loading the model in the version of Magento that you are using. Try using the ->addFieldToSelect('transaction_id') on loading the model. The reason for this is because it is a protected data attribute and should never be dealt with directly the way you have attempted here.
Alternatively you really should be using Magento's ability to create invoice from the sales order model.
$order = Mage::getModel('sales/order');
$service = Mage::getModel('sales/service_order' , $order);
$service->prepareInvoice();
prepareInvoice takes an optional array of ( 'sku' => 'qty' )
Which makes it easy to manage the potential for multiple invoices per order.
Upvotes: 1