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
00029
00030
00031
00032
00033
00034
00035 class Mage_Paygate_Model_Payflow_Pro extends Mage_Payment_Model_Method_Cc
00036 {
00037 const TRXTYPE_AUTH_ONLY = 'A';
00038 const TRXTYPE_SALE = 'S';
00039 const TRXTYPE_CREDIT = 'C';
00040 const TRXTYPE_DELAYED_CAPTURE = 'D';
00041 const TRXTYPE_DELAYED_VOID = 'V';
00042 const TRXTYPE_DELAYED_VOICE = 'F';
00043 const TRXTYPE_DELAYED_INQUIRY = 'I';
00044
00045 const TENDER_AUTOMATED = 'A';
00046 const TENDER_CC = 'C';
00047 const TENDER_PINLESS_DEBIT = 'D';
00048 const TENDER_ECHEK = 'E';
00049 const TENDER_TELECHECK = 'K';
00050 const TENDER_PAYPAL = 'P';
00051
00052 const RESPONSE_DELIM_CHAR = ',';
00053
00054 protected $_clientTimeout = 45;
00055
00056 const RESPONSE_CODE_APPROVED = 0;
00057 const RESPONSE_CODE_FRAUDSERVICE_FILTER = 126;
00058 const RESPONSE_CODE_DECLINED = 12;
00059 const RESPONSE_CODE_CAPTURE_ERROR = 111;
00060
00061 protected $_code = 'verisign';
00062
00063
00064
00065
00066 protected $_isGateway = true;
00067 protected $_canAuthorize = true;
00068 protected $_canCapture = true;
00069 protected $_canCapturePartial = false;
00070 protected $_canRefund = false;
00071 protected $_canVoid = true;
00072 protected $_canUseInternal = true;
00073 protected $_canUseCheckout = true;
00074 protected $_canUseForMultishipping = true;
00075 protected $_canSaveCc = false;
00076 protected $_isProxy = false;
00077
00078
00079
00080
00081
00082
00083 protected $_debugReplacePrivateDataKeys = array('user', 'pwd', 'acct',
00084 'expdate', 'cvv2');
00085
00086
00087
00088
00089
00090
00091 protected $_validVoidTransState = array(3,6,9);
00092
00093 public function authorize(Varien_Object $payment, $amount)
00094 {
00095 $error = false;
00096 if($amount>0){
00097 $payment->setTrxtype(self::TRXTYPE_AUTH_ONLY);
00098 $payment->setAmount($amount);
00099
00100 $request = $this->_buildRequest($payment);
00101 $result = $this->_postRequest($request);
00102 $payment->setCcTransId($result->getPnref());
00103
00104 switch ($result->getResultCode()){
00105 case self::RESPONSE_CODE_APPROVED:
00106 $payment->setStatus(self::STATUS_APPROVED);
00107 break;
00108
00109 case self::RESPONSE_CODE_FRAUDSERVICE_FILTER:
00110 $payment->setFraudFlag(true);
00111 break;
00112
00113 default:
00114 if ($result->getRespmsg()) {
00115 $error = $result->getRespmsg();
00116 }
00117 else {
00118 $error = Mage::helper('paygate')->__('Error in authorizing the payment');
00119 }
00120 break;
00121 }
00122 }else{
00123 $error = Mage::helper('paygate')->__('Invalid amount for authorization');
00124 }
00125
00126 if ($error !== false) {
00127 Mage::throwException($error);
00128 }
00129 return $this;
00130 }
00131
00132 public function capture(Varien_Object $payment, $amount)
00133 {
00134 $error = false;
00135 if ($payment->getCcTransId()) {
00136
00137
00138
00139 if ($payment->getOrder()->getTotalPaid()>0) {
00140 $payment->setTrxtype(self::TRXTYPE_SALE);
00141 } else {
00142 $payment->setTrxtype(self::TRXTYPE_DELAYED_CAPTURE);
00143 }
00144 $payment->setTransactionId($payment->getCcTransId());
00145 $request = $this->_buildBasicRequest($payment);
00146 } else {
00147 $payment->setTrxtype(self::TRXTYPE_SALE);
00148 $payment->setAmount($amount);
00149 $request = $this->_buildRequest($payment);
00150 }
00151
00152 $result = $this->_postRequest($request);
00153 switch ($result->getResultCode()){
00154 case self::RESPONSE_CODE_APPROVED:
00155 $payment->setStatus(self::STATUS_APPROVED);
00156
00157 $payment->setLastTransId($result->getPnref());
00158 break;
00159
00160 case self::RESPONSE_CODE_FRAUDSERVICE_FILTER:
00161 $payment->setFraudFlag(true);
00162 break;
00163
00164 default:
00165 if ($result->getRespmsg()) {
00166 $error = $result->getRespmsg();
00167 }
00168 else {
00169 $error = Mage::helper('paygate')->__('Error in capturing the payment');
00170 }
00171 break;
00172 }
00173 if ($error !== false) {
00174 Mage::throwException($error);
00175 }
00176 return $this;
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 public function canVoid(Varien_Object $payment)
00188 {
00189 if($payment->getCcTransId()){
00190 $payment->setTrxtype(self::TRXTYPE_DELAYED_INQUIRY);
00191 $payment->setTransactionId($payment->getCcTransId());
00192 $request=$this->_buildBasicRequest($payment);
00193 $result = $this->_postRequest($request);
00194
00195 if($result->getResultCode()==self::RESPONSE_CODE_APPROVED){
00196 if($result->getTransstate()>1000){
00197 $payment->setStatus(self::STATUS_ERROR);
00198 $payment->setStatusDescription(Mage::helper('paygate')->__('Voided transaction'));
00199 }elseif(in_array($result->getTransstate(),$this->_validVoidTransState)){
00200 $payment->setStatus(self::STATUS_VOID);
00201 }
00202 }else{
00203 $payment->setStatus(self::STATUS_ERROR);
00204 $payment->setStatusDescription($result->getRespmsg()?
00205 $result->getRespmsg():
00206 Mage::helper('paygate')->__('Error in retrieving the transaction'));
00207 }
00208 }else{
00209 $payment->setStatus(self::STATUS_ERROR);
00210 $payment->setStatusDescription(Mage::helper('paygate')->__('Invalid transaction id'));
00211 }
00212
00213 return $this;
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223 public function void(Varien_Object $payment)
00224 {
00225 $error = false;
00226 if($payment->getVoidTransactionId()){
00227 $payment->setTrxtype(self::TRXTYPE_DELAYED_VOID);
00228 $payment->setTransactionId($payment->getVoidTransactionId());
00229 $request=$this->_buildBasicRequest($payment);
00230 $result = $this->_postRequest($request);
00231
00232 if($result->getResultCode()==self::RESPONSE_CODE_APPROVED){
00233 $payment->setStatus(self::STATUS_SUCCESS);
00234 $payment->setCcTransId($result->getPnref());
00235 }else{
00236 $payment->setStatus(self::STATUS_ERROR);
00237 $error = $result->getRespmsg();
00238 }
00239 }else{
00240 $payment->setStatus(self::STATUS_ERROR);
00241 $error = Mage::helper('paygate')->__('Invalid transaction id');
00242 }
00243
00244 if ($error !== false) {
00245 Mage::throwException($error);
00246 }
00247
00248 return $this;
00249
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 public function refund(Varien_Object $payment, $amount)
00261 {
00262 $error = false;
00263 if(($payment->getRefundTransactionId() && $amount>0)){
00264 $payment->setTransactionId($payment->getRefundTransactionId());
00265 $payment->setTrxtype(self::TRXTYPE_CREDIT);
00266
00267 $request=$this->_buildBasicRequest($payment);
00268
00269 $request->setAmt(round($amount,2));
00270 $result = $this->_postRequest($request);
00271
00272 if($result->getResultCode()==self::RESPONSE_CODE_APPROVED){
00273 $payment->setStatus(self::STATUS_SUCCESS);
00274 $payment->setCcTransId($result->getPnref());
00275 }else{
00276 $error = ($result->getRespmsg()?
00277 $result->getRespmsg():
00278 Mage::helper('paygate')->__('Error in refunding the payment.'));
00279
00280 }
00281 }else{
00282 $error = Mage::helper('paygate')->__('Error in refunding the payment');
00283 }
00284
00285 if ($error !== false) {
00286 Mage::throwException($error);
00287 }
00288 return $this;
00289
00290 }
00291
00292 protected function _postRequest(Varien_Object $request)
00293 {
00294 if ($this->getConfigData('debug')) {
00295 $requestDebug = clone $request;
00296
00297
00298 foreach ($this->_debugReplacePrivateDataKeys as $key) {
00299 if ($requestDebug->hasData($key)) {
00300 $requestDebug->setData($key, '***');
00301 }
00302 }
00303
00304 foreach( $requestDebug->getData() as $key => $value ) {
00305 $value = (string)$value;
00306 $requestData[] = strtoupper($key) . '[' . strlen($value) . ']=' . $value;
00307 }
00308
00309 $requestData = join('&', $requestData);
00310
00311 $debug = Mage::getModel('paygate/authorizenet_debug')
00312 ->setRequestBody($requestData)
00313 ->setRequestSerialized(serialize($requestDebug->getData()))
00314 ->setRequestDump(print_r($requestDebug->getData(),1))
00315 ->save();
00316 }
00317
00318 $client = new Varien_Http_Client();
00319
00320 $_config = array(
00321 'maxredirects'=>5,
00322 'timeout'=>30,
00323 );
00324
00325 $_isProxy = $this->getConfigData('use_proxy', false);
00326 if($_isProxy){
00327 $_config['proxy'] = $this->getConfigData('proxy_host') . ':' . $this->getConfigData('proxy_port');
00328 $_config['httpproxytunnel'] = true;
00329 $_config['proxytype'] = CURLPROXY_HTTP;
00330 }
00331
00332 $uri = $this->getConfigData('url');
00333 $client->setUri($uri)
00334 ->setConfig($_config)
00335 ->setMethod(Zend_Http_Client::POST)
00336 ->setParameterPost($request->getData())
00337 ->setHeaders('X-VPS-VIT-CLIENT-CERTIFICATION-ID: 33baf5893fc2123d8b191d2d011b7fdc')
00338 ->setHeaders('X-VPS-Request-ID: ' . $request->getRequestId())
00339 ->setHeaders('X-VPS-CLIENT-TIMEOUT: ' . $this->_clientTimeout)
00340 ;
00341
00342
00343
00344
00345
00346 $response = $client->setUrlEncodeBody(false)
00347 ->request();
00348
00349 $result = Mage::getModel('paygate/payflow_pro_result');
00350
00351 $response = strstr($response->getBody(), 'RESULT');
00352 $valArray = explode('&', $response);
00353
00354 foreach($valArray as $val) {
00355 $valArray2 = explode('=', $val);
00356 $result->setData(strtolower($valArray2[0]), $valArray2[1]);
00357 }
00358
00359 $result->setResultCode($result->getResult())
00360 ->setRespmsg($result->getRespmsg());
00361
00362 if (!empty($debug)) {
00363 $debug
00364 ->setResponseBody($response)
00365 ->setResultSerialized(serialize($result->getData()))
00366 ->setResultDump(print_r($result->getData(),1))
00367 ->save();
00368 }
00369
00370 return $result;
00371 }
00372
00373 protected function _buildRequest(Varien_Object $payment)
00374 {
00375 if( !$payment->getTrxtype() ) {
00376 $payment->setTrxtype(self::TRXTYPE_AUTH_ONLY);
00377 }
00378
00379 if( !$payment->getTender() ) {
00380 $payment->setTender(self::TENDER_CC);
00381 }
00382
00383 $request = Mage::getModel('paygate/payflow_pro_request')
00384 ->setUser($this->getConfigData('user'))
00385 ->setVendor($this->getConfigData('vendor'))
00386 ->setPartner($this->getConfigData('partner'))
00387 ->setPwd($this->getConfigData('pwd'))
00388 ->setTender($payment->getTender())
00389 ->setTrxtype($payment->getTrxtype())
00390 ->setVerbosity($this->getConfigData('verbosity'))
00391 ->setRequestId($this->_generateRequestId())
00392 ;
00393
00394 if($payment->getAmount()){
00395 $request->setAmt(round($payment->getAmount(),2));
00396 $request->setCurrency($payment->getOrder()->getBaseCurrencyCode());
00397 }
00398
00399 switch ($request->getTender()) {
00400 case self::TENDER_CC:
00401 if($payment->getCcNumber()){
00402 $request
00403
00404 ->setAcct($payment->getCcNumber())
00405 ->setExpdate(sprintf('%02d',$payment->getCcExpMonth()).substr($payment->getCcExpYear(),-2,2))
00406 ->setCvv2($payment->getCcCid());
00407 }
00408 break;
00409 }
00410
00411 $order = $payment->getOrder();
00412 if(!empty($order)){
00413 $billing = $order->getBillingAddress();
00414 if (!empty($billing)) {
00415 $request->setFirstname($billing->getFirstname())
00416 ->setLastname($billing->getLastname())
00417 ->setStreet($billing->getStreet(1))
00418 ->setCity($billing->getCity())
00419 ->setState($billing->getRegion())
00420 ->setZip($billing->getPostcode())
00421 ->setCountry($billing->getCountry())
00422 ->setEmail($payment->getOrder()->getCustomerEmail());
00423 }
00424 $shipping = $order->getShippingAddress();
00425 if (!empty($shipping)) {
00426 $request->setShiptofirstname($shipping->getFirstname())
00427 ->setShiptolastname($shipping->getLastname())
00428 ->setShiptostreet($shipping->getStreet(1))
00429 ->setShiptocity($shipping->getCity())
00430 ->setShiptostate($shipping->getRegion())
00431 ->setShiptozip($shipping->getPostcode())
00432 ->setShiptocountry($shipping->getCountry());
00433 }
00434 }
00435 return $request;
00436 }
00437
00438 protected function _generateRequestId()
00439 {
00440 return md5(microtime() . rand(0, time()));
00441 }
00442
00443
00444
00445
00446
00447
00448
00449 protected function _buildBasicRequest(Varien_Object $payment)
00450 {
00451 if( !$payment->getTender() ) {
00452 $payment->setTender(self::TENDER_CC);
00453 }
00454
00455 $request = Mage::getModel('paygate/payflow_pro_request')
00456 ->setUser($this->getConfigData('user'))
00457 ->setVendor($this->getConfigData('vendor'))
00458 ->setPartner($this->getConfigData('partner'))
00459 ->setPwd($this->getConfigData('pwd'))
00460 ->setTender($payment->getTender())
00461 ->setTrxtype($payment->getTrxtype())
00462 ->setVerbosity($this->getConfigData('verbosity'))
00463 ->setRequestId($this->_generateRequestId())
00464 ->setOrigid($payment->getTransactionId());
00465 return $request;
00466 }
00467 }