00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 class Mage_Paygate_Model_Authorizenet extends Mage_Payment_Model_Method_Cc
00029 {
00030 const CGI_URL = 'https://secure.authorize.net/gateway/transact.dll';
00031
00032 const REQUEST_METHOD_CC = 'CC';
00033 const REQUEST_METHOD_ECHECK = 'ECHECK';
00034
00035 const REQUEST_TYPE_AUTH_CAPTURE = 'AUTH_CAPTURE';
00036 const REQUEST_TYPE_AUTH_ONLY = 'AUTH_ONLY';
00037 const REQUEST_TYPE_CAPTURE_ONLY = 'CAPTURE_ONLY';
00038 const REQUEST_TYPE_CREDIT = 'CREDIT';
00039 const REQUEST_TYPE_VOID = 'VOID';
00040 const REQUEST_TYPE_PRIOR_AUTH_CAPTURE = 'PRIOR_AUTH_CAPTURE';
00041
00042 const ECHECK_ACCT_TYPE_CHECKING = 'CHECKING';
00043 const ECHECK_ACCT_TYPE_BUSINESS = 'BUSINESSCHECKING';
00044 const ECHECK_ACCT_TYPE_SAVINGS = 'SAVINGS';
00045
00046 const ECHECK_TRANS_TYPE_CCD = 'CCD';
00047 const ECHECK_TRANS_TYPE_PPD = 'PPD';
00048 const ECHECK_TRANS_TYPE_TEL = 'TEL';
00049 const ECHECK_TRANS_TYPE_WEB = 'WEB';
00050
00051 const RESPONSE_DELIM_CHAR = ',';
00052
00053 const RESPONSE_CODE_APPROVED = 1;
00054 const RESPONSE_CODE_DECLINED = 2;
00055 const RESPONSE_CODE_ERROR = 3;
00056 const RESPONSE_CODE_HELD = 4;
00057
00058 protected $_code = 'authorizenet';
00059
00060
00061
00062
00063 protected $_isGateway = true;
00064 protected $_canAuthorize = true;
00065 protected $_canCapture = true;
00066 protected $_canCapturePartial = false;
00067 protected $_canRefund = false;
00068 protected $_canVoid = true;
00069 protected $_canUseInternal = true;
00070 protected $_canUseCheckout = true;
00071 protected $_canUseForMultishipping = true;
00072 protected $_canSaveCc = false;
00073
00074 protected $_allowCurrencyCode = array('USD');
00075
00076
00077
00078
00079
00080
00081 protected $_debugReplacePrivateDataKeys = array('x_login', 'x_tran_key',
00082 'x_card_num', 'x_exp_date',
00083 'x_card_code', 'x_bank_aba_code',
00084 'x_bank_name', 'x_bank_acct_num',
00085 'x_bank_acct_type','x_bank_acct_name',
00086 'x_echeck_type');
00087
00088
00089
00090
00091
00092
00093
00094 public function canUseForCurrency($currencyCode)
00095 {
00096 if (!in_array($currencyCode, $this->_allowCurrencyCode)) {
00097 return false;
00098 }
00099 return true;
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109 public function authorize(Varien_Object $payment, $amount)
00110 {
00111 $error = false;
00112
00113 if($amount>0){
00114 $payment->setAnetTransType(self::REQUEST_TYPE_AUTH_ONLY);
00115 $payment->setAmount($amount);
00116
00117 $request= $this->_buildRequest($payment);
00118 $result = $this->_postRequest($request);
00119
00120 $payment->setCcApproval($result->getApprovalCode())
00121 ->setLastTransId($result->getTransactionId())
00122 ->setCcTransId($result->getTransactionId())
00123 ->setCcAvsStatus($result->getAvsResultCode())
00124 ->setCcCidStatus($result->getCardCodeResponseCode());
00125
00126 switch ($result->getResponseCode()) {
00127 case self::RESPONSE_CODE_APPROVED:
00128 $payment->setStatus(self::STATUS_APPROVED);
00129 break;
00130 case self::RESPONSE_CODE_DECLINED:
00131 $error = Mage::helper('paygate')->__('Payment authorization transaction has been declined.');
00132 break;
00133 default:
00134 $error = Mage::helper('paygate')->__('Payment authorization error.');
00135 break;
00136 }
00137 }else{
00138 $error = Mage::helper('paygate')->__('Invalid amount for authorization.');
00139 }
00140
00141 if ($error !== false) {
00142 Mage::throwException($error);
00143 }
00144 return $this;
00145 }
00146
00147
00148 public function capture(Varien_Object $payment, $amount)
00149 {
00150 $error = false;
00151
00152 if ($payment->getCcTransId()) {
00153 $payment->setAnetTransType(self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE);
00154 } else {
00155 $payment->setAnetTransType(self::REQUEST_TYPE_AUTH_CAPTURE);
00156 }
00157
00158 $payment->setAmount($amount);
00159
00160 $request= $this->_buildRequest($payment);
00161 $result = $this->_postRequest($request);
00162
00163 if ($result->getResponseCode() == self::RESPONSE_CODE_APPROVED) {
00164 $payment->setStatus(self::STATUS_APPROVED);
00165
00166 $payment->setLastTransId($result->getTransactionId());
00167 }
00168 else {
00169 if ($result->getResponseReasonText()) {
00170 $error = $result->getResponseReasonText();
00171 }
00172 else {
00173 $error = Mage::helper('paygate')->__('Error in capturing the payment');
00174 }
00175 }
00176
00177 if ($error !== false) {
00178 Mage::throwException($error);
00179 }
00180
00181 return $this;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 public function void(Varien_Object $payment)
00194 {
00195 $error = false;
00196 if($payment->getVoidTransactionId()){
00197 $payment->setAnetTransType(self::REQUEST_TYPE_VOID);
00198 $request = $this->_buildRequest($payment);
00199 $request->setXTransId($payment->getVoidTransactionId());
00200 $result = $this->_postRequest($request);
00201 if($result->getResponseCode()==self::RESPONSE_CODE_APPROVED){
00202 $payment->setStatus(self::STATUS_SUCCESS );
00203 }
00204 else{
00205 $payment->setStatus(self::STATUS_ERROR);
00206 $error = $result->getResponseReasonText();
00207 }
00208 }else{
00209 $payment->setStatus(self::STATUS_ERROR);
00210 $error = Mage::helper('paygate')->__('Invalid transaction id');
00211 }
00212 if ($error !== false) {
00213 Mage::throwException($error);
00214 }
00215 return $this;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225 public function refund(Varien_Object $payment, $amount)
00226 {
00227 $error = false;
00228 if ($payment->getRefundTransactionId() && $amount>0) {
00229 $payment->setAnetTransType(self::REQUEST_TYPE_CREDIT);
00230 $request = $this->_buildRequest($payment);
00231 $request->setXTransId($payment->getRefundTransactionId());
00232 $result = $this->_postRequest($request);
00233
00234 if ($result->getResponseCode()==self::RESPONSE_CODE_APPROVED) {
00235 $payment->setStatus(self::STATUS_SUCCESS);
00236 } else {
00237 $error = $result->getResponseReasonText();
00238 }
00239
00240 } else {
00241 $error = Mage::helper('paygate')->__('Error in refunding the payment');
00242 }
00243
00244 if ($error !== false) {
00245 Mage::throwException($error);
00246 }
00247 return $this;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257 protected function _buildRequest(Varien_Object $payment)
00258 {
00259 $order = $payment->getOrder();
00260
00261 $this->setStore($order->getStoreId());
00262
00263 if (!$payment->getAnetTransMethod()) {
00264 $payment->setAnetTransMethod(self::REQUEST_METHOD_CC);
00265 }
00266
00267 $request = Mage::getModel('paygate/authorizenet_request')
00268 ->setXVersion(3.1)
00269 ->setXDelimData('True')
00270 ->setXDelimChar(self::RESPONSE_DELIM_CHAR)
00271 ->setXRelayResponse('False');
00272
00273 if ($order && $order->getIncrementId()) {
00274 $request->setXInvoiceNum($order->getIncrementId());
00275 }
00276
00277 $request->setXTestRequest($this->getConfigData('test') ? 'TRUE' : 'FALSE');
00278
00279 $request->setXLogin($this->getConfigData('login'))
00280 ->setXTranKey($this->getConfigData('trans_key'))
00281 ->setXType($payment->getAnetTransType())
00282 ->setXMethod($payment->getAnetTransMethod());
00283
00284 if($payment->getAmount()){
00285 $request->setXAmount($payment->getAmount(),2);
00286 $request->setXCurrencyCode($order->getBaseCurrencyCode());
00287 }
00288 switch ($payment->getAnetTransType()) {
00289 case self::REQUEST_TYPE_CREDIT:
00290 case self::REQUEST_TYPE_VOID:
00291 case self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE:
00292 $request->setXTransId($payment->getCcTransId());
00293 break;
00294
00295 case self::REQUEST_TYPE_CAPTURE_ONLY:
00296 $request->setXAuthCode($payment->getCcAuthCode());
00297 break;
00298 }
00299
00300 if (!empty($order)) {
00301 $billing = $order->getBillingAddress();
00302 if (!empty($billing)) {
00303 $request->setXFirstName($billing->getFirstname())
00304 ->setXLastName($billing->getLastname())
00305 ->setXCompany($billing->getCompany())
00306 ->setXAddress($billing->getStreet(1))
00307 ->setXCity($billing->getCity())
00308 ->setXState($billing->getRegion())
00309 ->setXZip($billing->getPostcode())
00310 ->setXCountry($billing->getCountry())
00311 ->setXPhone($billing->getTelephone())
00312 ->setXFax($billing->getFax())
00313 ->setXCustId($billing->getCustomerId())
00314 ->setXCustomerIp($order->getRemoteIp())
00315 ->setXCustomerTaxId($billing->getTaxId())
00316 ->setXEmail($order->getCustomerEmail())
00317 ->setXEmailCustomer($this->getConfigData('email_customer'))
00318 ->setXMerchantEmail($this->getConfigData('merchant_email'));
00319 }
00320
00321 $shipping = $order->getShippingAddress();
00322 if (!empty($shipping)) {
00323 $request->setXShipToFirstName($shipping->getFirstname())
00324 ->setXShipToLastName($shipping->getLastname())
00325 ->setXShipToCompany($shipping->getCompany())
00326 ->setXShipToAddress($shipping->getStreet(1))
00327 ->setXShipToCity($shipping->getCity())
00328 ->setXShipToState($shipping->getRegion())
00329 ->setXShipToZip($shipping->getPostcode())
00330 ->setXShipToCountry($shipping->getCountry());
00331 }
00332
00333 $request->setXPoNum($payment->getPoNumber())
00334 ->setXTax($order->getTaxAmount())
00335 ->setXFreight($order->getShippingAmount());
00336 }
00337
00338 switch ($payment->getAnetTransMethod()) {
00339 case self::REQUEST_METHOD_CC:
00340 if($payment->getCcNumber()){
00341 $request->setXCardNum($payment->getCcNumber())
00342 ->setXExpDate(sprintf('%02d-%04d', $payment->getCcExpMonth(), $payment->getCcExpYear()))
00343 ->setXCardCode($payment->getCcCid());
00344 }
00345 break;
00346
00347 case self::REQUEST_METHOD_ECHECK:
00348 $request->setXBankAbaCode($payment->getEcheckRoutingNumber())
00349 ->setXBankName($payment->getEcheckBankName())
00350 ->setXBankAcctNum($payment->getEcheckAccountNumber())
00351 ->setXBankAcctType($payment->getEcheckAccountType())
00352 ->setXBankAcctName($payment->getEcheckAccountName())
00353 ->setXEcheckType($payment->getEcheckType());
00354 break;
00355 }
00356
00357 return $request;
00358 }
00359
00360 protected function _postRequest(Varien_Object $request)
00361 {
00362 $result = Mage::getModel('paygate/authorizenet_result');
00363
00364 $client = new Varien_Http_Client();
00365
00366 $uri = $this->getConfigData('cgi_url');
00367 $client->setUri($uri ? $uri : self::CGI_URL);
00368 $client->setConfig(array(
00369 'maxredirects'=>0,
00370 'timeout'=>30,
00371
00372 ));
00373 $client->setParameterPost($request->getData());
00374 $client->setMethod(Zend_Http_Client::POST);
00375
00376 if ($this->getConfigData('debug')) {
00377 $requestDebug = clone $request;
00378
00379 foreach ($this->_debugReplacePrivateDataKeys as $key) {
00380 if ($requestDebug->hasData($key)) {
00381 $requestDebug->setData($key, '***');
00382 }
00383 }
00384
00385 foreach( $requestDebug->getData() as $key => $value ) {
00386 $requestData[] = strtoupper($key) . '=' . $value;
00387 }
00388
00389 $requestData = join('&', $requestData);
00390
00391 $debug = Mage::getModel('paygate/authorizenet_debug')
00392 ->setRequestBody($requestData)
00393 ->setRequestSerialized(serialize($requestDebug->getData()))
00394 ->setRequestDump(print_r($requestDebug->getData(),1))
00395 ->save();
00396 }
00397
00398 try {
00399 $response = $client->request();
00400 } catch (Exception $e) {
00401 $result->setResponseCode(-1)
00402 ->setResponseReasonCode($e->getCode())
00403 ->setResponseReasonText($e->getMessage());
00404
00405 if (!empty($debug)) {
00406 $debug
00407 ->setResultSerialized(serialize($result->getData()))
00408 ->setResultDump(print_r($result->getData(),1))
00409 ->save();
00410 }
00411 Mage::throwException(
00412 Mage::helper('paygate')->__('Gateway request error: %s', $e->getMessage())
00413 );
00414 }
00415
00416 $responseBody = $response->getBody();
00417
00418 $r = explode(self::RESPONSE_DELIM_CHAR, $responseBody);
00419
00420 if ($r) {
00421 $result->setResponseCode((int)str_replace('"','',$r[0]))
00422 ->setResponseSubcode((int)str_replace('"','',$r[1]))
00423 ->setResponseReasonCode((int)str_replace('"','',$r[2]))
00424 ->setResponseReasonText($r[3])
00425 ->setApprovalCode($r[4])
00426 ->setAvsResultCode($r[5])
00427 ->setTransactionId($r[6])
00428 ->setInvoiceNumber($r[7])
00429 ->setDescription($r[8])
00430 ->setAmount($r[9])
00431 ->setMethod($r[10])
00432 ->setTransactionType($r[11])
00433 ->setCustomerId($r[12])
00434 ->setMd5Hash($r[37])
00435 ->setCardCodeResponseCode($r[39]);
00436 } else {
00437 Mage::throwException(
00438 Mage::helper('paygate')->__('Error in payment gateway')
00439 );
00440 }
00441
00442 if (!empty($debug)) {
00443 $debug
00444 ->setResponseBody($responseBody)
00445 ->setResultSerialized(serialize($result->getData()))
00446 ->setResultDump(print_r($result->getData(),1))
00447 ->save();
00448 }
00449
00450 return $result;
00451 }
00452 }