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 class Mage_Paypal_Model_Api_Nvp extends Mage_Paypal_Model_Api_Abstract
00033 {
00034
00035
00036
00037
00038
00039 protected $_debugReplacePrivateDataKeys = array('ACCT', 'EXPDATE', 'CVV2',
00040 'CARDISSUE', 'CARDSTART',
00041 'CREDITCARDTYPE', 'USER',
00042 'PWD', 'SIGNATURE');
00043
00044 public function getPageStyle()
00045 {
00046 return $this->getConfigData('page_style');
00047 }
00048
00049 public function getApiEndpoint()
00050 {
00051 if (!$this->getData('api_endpoint')) {
00052 if ($this->getSandboxFlag()) {
00053 $default = 'https://api-3t.sandbox.paypal.com/nvp';
00054 } else {
00055 $default = 'https://api-3t.paypal.com/nvp';
00056 }
00057 return $this->getConfigData('api_endpoint', $default);
00058 }
00059 return $this->getData('api_endpoint');
00060 }
00061
00062 public function getPaypalUrl()
00063 {
00064 if (!$this->hasPaypalUrl()) {
00065 if ($this->getSandboxFlag()) {
00066 $default = 'https://www.sandbox.paypal.com/';
00067 } else {
00068 $default = 'https://www.paypal.com/cgi-bin/';
00069 }
00070 $default .= 'webscr?cmd=_express-checkout&useraction='.$this->getUserAction().'&token=';
00071
00072 $url = $this->getConfigData('paypal_url', $default);
00073 } else {
00074 $url = $this->getData('paypal_url');
00075 }
00076 return $url . $this->getToken();
00077 }
00078
00079 public function getVersion()
00080 {
00081 return '3.0';
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 public function callSetExpressCheckout()
00095 {
00096
00097
00098
00099 $nvpArr = array(
00100 'PAYMENTACTION' => $this->getPaymentType(),
00101 'AMT' => $this->getAmount(),
00102 'CURRENCYCODE' => $this->getCurrencyCode(),
00103 'RETURNURL' => $this->getReturnUrl(),
00104 'CANCELURL' => $this->getCancelUrl(),
00105 'INVNUM' => $this->getInvNum()
00106 );
00107
00108 if ($this->getPageStyle()) {
00109 $nvpArr = array_merge($nvpArr, array(
00110 'PAGESTYLE' => $this->getPageStyle()
00111 ));
00112 }
00113
00114 $this->setUserAction(self::USER_ACTION_CONTINUE);
00115
00116
00117 if ($a = $this->getShippingAddress()) {
00118 $nvpArr = array_merge($nvpArr, array(
00119 'ADDROVERRIDE' => 1,
00120 'SHIPTONAME' => $a->getName(),
00121 'SHIPTOSTREET' => $a->getStreet(1),
00122 'SHIPTOSTREET2' => $a->getStreet(2),
00123 'SHIPTOCITY' => $a->getCity(),
00124 'SHIPTOSTATE' => $a->getRegionCode(),
00125 'SHIPTOCOUNTRYCODE' => $a->getCountry(),
00126 'SHIPTOZIP' => $a->getPostcode(),
00127 'PHONENUM' => $a->getTelephone(),
00128 ));
00129 $this->setUserAction(self::USER_ACTION_COMMIT);
00130 }
00131
00132
00133
00134
00135
00136
00137 $resArr = $this->call('SetExpressCheckout', $nvpArr);
00138
00139 if (false===$resArr) {
00140 return false;
00141 }
00142
00143 $this->setToken($resArr['TOKEN']);
00144 $this->setRedirectUrl($this->getPaypalUrl());
00145 return $resArr;
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 function callGetExpressCheckoutDetails()
00159 {
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 $nvpArr = array(
00174 'TOKEN' => $this->getToken(),
00175 );
00176
00177
00178
00179
00180
00181
00182
00183 $resArr = $this->call('GetExpressCheckoutDetails', $nvpArr);
00184 if (false===$resArr) {
00185 return false;
00186 }
00187
00188 $this->setPayerId($resArr['PAYERID']);
00189 $this->setCorrelationId($resArr['CORRELATIONID']);
00190 $this->setPayerStatus($resArr['PAYERSTATUS']);
00191 if (isset($resArr['ADDRESSID'])) {
00192 $this->setAddressId($resArr['ADDRESSID']);
00193 }
00194 $this->setAddressStatus($resArr['ADDRESSSTATUS']);
00195 $this->setPaypalPayerEmail($resArr['EMAIL']);
00196
00197 if (!$this->getShippingAddress()) {
00198 $this->setShippingAddress(Mage::getModel('customer/address'));
00199 }
00200 $a = $this->getShippingAddress();
00201 $a->setEmail($resArr['EMAIL']);
00202 $a->setFirstname($resArr['FIRSTNAME']);
00203 $a->setLastname($resArr['LASTNAME']);
00204 $street = array($resArr['SHIPTOSTREET']);
00205 if (isset($resArr['SHIPTOSTREET2'])) {
00206 $street[] = $resArr['SHIPTOSTREET2'];
00207 }
00208 $a->setStreet($street);
00209 $a->setCity($resArr['SHIPTOCITY']);
00210 $a->setRegion(isset($resArr['SHIPTOSTATE']) ? $resArr['SHIPTOSTATE'] : '');
00211 $a->setPostcode($resArr['SHIPTOZIP']);
00212 $a->setCountry($resArr['SHIPTOCOUNTRYCODE']);
00213 $a->setTelephone(Mage::helper('paypal')->__('N/A'));
00214
00215 return $resArr;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 public function callDoExpressCheckoutPayment()
00227 {
00228
00229
00230
00231
00232
00233 $nvpArr = array(
00234 'TOKEN' => $this->getToken(),
00235 'PAYERID' => $this->getPayerId(),
00236 'PAYMENTACTION' => $this->getPaymentType(),
00237 'AMT' => $this->getAmount(),
00238 'CURRENCYCODE' => $this->getCurrencyCode(),
00239 'IPADDRESS' => $this->getServerName(),
00240 'BUTTONSOURCE' => $this->getButtonSourceEc(),
00241 );
00242
00243
00244
00245
00246 $resArr = $this->call('DoExpressCheckoutPayment', $nvpArr);
00247
00248 if (false===$resArr) {
00249 return false;
00250 }
00251
00252 $this->setTransactionId($resArr['TRANSACTIONID']);
00253 $this->setAmount($resArr['AMT']);
00254
00255 return $resArr;
00256 }
00257
00258 public function callDoDirectPayment()
00259 {
00260 $p = $this->getPayment();
00261 $a = $this->getBillingAddress();
00262 if ($this->getShippingAddress()) {
00263 $s = $this->getShippingAddress();
00264 } else {
00265 $s = $a;
00266 }
00267
00268 $nvpArr = array(
00269 'PAYMENTACTION' => $this->getPaymentType(),
00270 'AMT' => $this->getAmount(),
00271 'CURRENCYCODE' => $this->getCurrencyCode(),
00272 'BUTTONSOURCE' => $this->getButtonSourceDp(),
00273 'INVNUM' => $this->getInvNum(),
00274
00275 'CREDITCARDTYPE' => $this->getCcTypeName($p->getCcType()),
00276 'ACCT' => $p->getCcNumber(),
00277 'EXPDATE' => sprintf('%02d%02d', $p->getCcExpMonth(), $p->getCcExpYear()),
00278 'CVV2' => $p->getCcCid(),
00279
00280 'FIRSTNAME' => $a->getFirstname(),
00281 'LASTNAME' => $a->getLastname(),
00282 'STREET' => $a->getStreet(1),
00283 'CITY' => $a->getCity(),
00284 'STATE' => ($a->getRegionCode() ? $a->getRegionCode() : $a->getRegion()),
00285 'ZIP' => $a->getPostcode(),
00286 'COUNTRYCODE' => 'US',
00287 'EMAIL' => $this->getEmail(),
00288
00289 'SHIPTONAME' => $s->getName(),
00290 'SHIPTOSTREET' => $s->getStreet(1),
00291 'SHIPTOSTREET2' => $s->getStreet(2),
00292 'SHIPTOCITY' => $s->getCity(),
00293 'SHIPTOSTATE' => ($s->getRegionCode() ? $s->getRegionCode() : $s->getRegion()),
00294 'SHIPTOZIP' => $s->getPostcode(),
00295 'SHIPTOCOUNTRYCODE' => $s->getCountry(),
00296 );
00297
00298 #echo "<pre>".print_r($nvpArr,1)."</pre>"; die;
00299 $resArr = $this->call('DoDirectPayment', $nvpArr);
00300
00301 if (false===$resArr) {
00302 return false;
00303 }
00304
00305 $this->setTransactionId($resArr['TRANSACTIONID']);
00306 $this->setAmount($resArr['AMT']);
00307 $this->setAvsCode($resArr['AVSCODE']);
00308 $this->setCvv2Match($resArr['CVV2MATCH']);
00309
00310 return $resArr;
00311 }
00312
00313 public function callDoReauthorization()
00314 {
00315 $nvpArr = array(
00316 'AUTHORIZATIONID' => $this->getAuthorizationId(),
00317 'AMT' => $this->getAmount(),
00318 'CURRENCYCODE' => $this->getCurrencyCode(),
00319 );
00320
00321 $resArr = $this->call('DoReauthorization', $nvpArr);
00322
00323 if (false===$resArr) {
00324 return false;
00325 }
00326
00327 $this->setAuthorizationId($resArr['AUTHORIZATIONID']);
00328
00329 return $resArr;
00330 }
00331
00332 public function callDoCapture()
00333 {
00334 $nvpArr = array(
00335 'AUTHORIZATIONID' => $this->getAuthorizationId(),
00336 'COMPLETETYPE' => $this->getCompleteType(),
00337 'AMT' => $this->getAmount(),
00338 'CURRENCYCODE' => $this->getCurrencyCode(),
00339 'NOTE' => $this->getNote(),
00340 'INVNUM' => $this->getInvNum()
00341 );
00342
00343 $resArr = $this->call('DoCapture', $nvpArr);
00344
00345 if (false===$resArr) {
00346 return false;
00347 }
00348
00349 $this->setAuthorizationId($resArr['AUTHORIZATIONID']);
00350 $this->setTransactionId($resArr['TRANSACTIONID']);
00351 $this->setPaymentStatus($resArr['PAYMENTSTATUS']);
00352 $this->setCurrencyCode($resArr['CURRENCYCODE']);
00353 $this->setAmount($resArr['AMT']);
00354
00355 return $resArr;
00356 }
00357
00358 public function callDoVoid()
00359 {
00360 $nvpArr = array(
00361 'AUTHORIZATIONID' => $this->getAuthorizationId(),
00362 'NOTE' => $this->getNote(),
00363 );
00364
00365 $resArr = $this->call('DoVoid', $nvpArr);
00366
00367 if (false===$resArr) {
00368 return false;
00369 }
00370
00371 $this->setAuthorizationId($resArr['AUTHORIZATIONID']);
00372
00373 return $resArr;
00374 }
00375
00376 public function callGetTransactionDetails()
00377 {
00378 $nvpArr = array(
00379 'TRANSACTIONID' => $this->getTransactionId(),
00380 );
00381
00382 $resArr = $this->call('GetTransactionDetails', $nvpArr);
00383
00384 if (false===$resArr) {
00385 return false;
00386 }
00387
00388 $this->setPayerEmail($resArr['RECEIVEREMAIL']);
00389 $this->setPayerId($resArr['PAYERID']);
00390 $this->setFirstname($resArr['FIRSTNAME']);
00391 $this->setLastname($resArr['LASTNAME']);
00392 $this->setTransactionId($resArr['TRANSACTIONID']);
00393 $this->setParentTransactionId($resArr['PARENTTRANSACTIONID']);
00394 $this->setCurrencyCode($resArr['CURRENCYCODE']);
00395 $this->setAmount($resArr['AMT']);
00396 $this->setPaymentStatus($resArr['PAYERSTATUS']);
00397
00398 return $resArr;
00399 }
00400
00401 public function callRefundTransaction()
00402 {
00403 $nvpArr = array(
00404 'TRANSACTIONID' => $this->getTransactionId(),
00405 'REFUNDTYPE' => $this->getRefundType(),
00406 'CURRENCYCODE' => $this->getCurrencyCode(),
00407 'NOTE' => $this->getNote(),
00408 );
00409 if ($this->getRefundType()===self::REFUND_TYPE_PARTIAL) {
00410 $nvpArr['AMT'] = $this->getAmount();
00411 }
00412
00413 $resArr = $this->call('RefundTransaction', $nvpArr);
00414
00415 if (false===$resArr) {
00416 return false;
00417 }
00418
00419 $this->setTransactionId($resArr['REFUNDTRANSACTIONID']);
00420 $this->setAmount($resArr['GROSSREFUNDAMT']);
00421
00422 return $resArr;
00423 }
00424
00425
00426
00427
00428
00429
00430
00431
00432 public function call($methodName, array $nvpArr)
00433 {
00434 $nvpArr = array_merge(array(
00435 'METHOD' => $methodName,
00436 'VERSION' => $this->getVersion(),
00437 'USER' => $this->getApiUserName(),
00438 'PWD' => $this->getApiPassword(),
00439 'SIGNATURE' => $this->getApiSignature(),
00440 ), $nvpArr);
00441
00442 $nvpReq = '';
00443 $nvpReqDebug = '';
00444
00445 foreach ($nvpArr as $k=>$v) {
00446 $nvpReq .= '&'.$k.'='.urlencode($v);
00447 $nvpReqDebug .= '&'.$k.'=';
00448 if (in_array($k, $this->_debugReplacePrivateDataKeys)) {
00449 $nvpReqDebug .= '***';
00450 } else {
00451 $nvpReqDebug .= urlencode($v);
00452 }
00453 }
00454 $nvpReq = substr($nvpReq, 1);
00455 if ($this->getDebug()) {
00456 $debug = Mage::getModel('paypal/api_debug')
00457 ->setApiEndpoint($this->getApiEndpoint())
00458 ->setRequestBody($nvpReqDebug)
00459 ->save();
00460 }
00461
00462 $http = new Varien_Http_Adapter_Curl();
00463 $config = array('timeout' => 30);
00464 if ($this->getUseProxy()) {
00465 $config['proxy'] = $this->getProxyHost(). ':' . $this->getProxyPort();
00466 }
00467 $http->setConfig($config);
00468 $http->write(Zend_Http_Client::POST, $this->getApiEndpoint(), '1.1', array(), $nvpReq);
00469 $response = $http->read();
00470 $response = preg_split('/^\r?$/m', $response, 2);
00471 $response = trim($response[1]);
00472
00473 if ($this->getDebug()) {
00474 $debug->setResponseBody($response)->save();
00475 }
00476
00477 $nvpReqArray = $this->deformatNVP($nvpReq);
00478 $this->getSession()->setNvpReqArray($nvpReqArray);
00479
00480 if ($http->getErrno()) {
00481 $http->close();
00482 $this->setError(array(
00483 'type'=>'CURL',
00484 'code'=>$http->getErrno(),
00485 'message'=>$http->getError()
00486 ));
00487 $this->setRedirectUrl($this->getApiErrorUrl());
00488 return false;
00489 }
00490 $http->close();
00491
00492
00493 $nvpResArray = $this->deformatNVP($response);
00494 $this->getSession()
00495 ->setLastCallMethod($methodName)
00496 ->setResHash($nvpResArray);
00497
00498 $ack = strtoupper($nvpResArray['ACK']);
00499
00500 if ($ack == 'SUCCESS' || $ack=='SUCCESSWITHWARNING') {
00501 $this->unsError();
00502 return $nvpResArray;
00503 }
00504
00505
00506 $errorArr = array(
00507 'type' => 'API',
00508 'ack' => $ack,
00509 );
00510 if (isset($nvpResArray['VERSION'])) {
00511 $errorArr['version'] = $nvpResArray['VERSION'];
00512 }
00513 if (isset($nvpResArray['CORRELATIONID'])) {
00514 $errorArr['correlation_id'] = $nvpResArray['CORRELATIONID'];
00515 }
00516 for ($i=0; isset($nvpResArray['L_SHORTMESSAGE'.$i]); $i++) {
00517 $errorArr['code'] = $nvpResArray['L_ERRORCODE'.$i];
00518 $errorArr['short_message'] = $nvpResArray['L_SHORTMESSAGE'.$i];
00519 $errorArr['long_message'] = $nvpResArray['L_LONGMESSAGE'.$i];
00520 }
00521 $this->setError($errorArr);
00522 $this->setRedirectUrl($this->getApiErrorUrl());
00523 return false;
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533 public function deformatNVP($nvpstr)
00534 {
00535 $intial=0;
00536 $nvpArray = array();
00537
00538 $nvpstr = strpos($nvpstr, "\r\n\r\n")!==false ? substr($nvpstr, strpos($nvpstr, "\r\n\r\n")+4) : $nvpstr;
00539
00540 while(strlen($nvpstr)) {
00541
00542 $keypos= strpos($nvpstr,'=');
00543
00544 $valuepos = strpos($nvpstr,'&') ? strpos($nvpstr,'&'): strlen($nvpstr);
00545
00546
00547 $keyval=substr($nvpstr,$intial,$keypos);
00548 $valval=substr($nvpstr,$keypos+1,$valuepos-$keypos-1);
00549
00550 $nvpArray[urldecode($keyval)] =urldecode( $valval);
00551 $nvpstr=substr($nvpstr,$valuepos+1,strlen($nvpstr));
00552 }
00553 return $nvpArray;
00554 }
00555
00556 }