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 class Mage_Paypal_Model_Express extends Mage_Payment_Model_Method_Abstract
00034 {
00035 protected $_code = 'paypal_express';
00036 protected $_formBlockType = 'paypal/express_form';
00037 protected $_infoBlockType = 'paypal/express_info';
00038
00039
00040
00041
00042 protected $_isGateway = false;
00043 protected $_canAuthorize = true;
00044 protected $_canCapture = true;
00045 protected $_canCapturePartial = false;
00046 protected $_canRefund = false;
00047 protected $_canVoid = true;
00048 protected $_canUseInternal = false;
00049 protected $_canUseCheckout = true;
00050 protected $_canUseForMultishipping = false;
00051
00052
00053 protected $_isInitializeNeeded = true;
00054
00055 protected $_allowCurrencyCode = array('AUD', 'CAD', 'CZK', 'DKK', 'EUR', 'HKD', 'HUF', 'ILS', 'JPY', 'MXN', 'NOK', 'NZD', 'PLN', 'GBP', 'SGD', 'SEK', 'CHF', 'USD');
00056
00057
00058
00059
00060
00061
00062
00063 public function canUseForCurrency($currencyCode)
00064 {
00065 if (!in_array($currencyCode, $this->_allowCurrencyCode)) {
00066 return false;
00067 }
00068 return true;
00069 }
00070
00071
00072
00073
00074
00075
00076 public function getApi()
00077 {
00078 return Mage::getSingleton('paypal/api_nvp');
00079 }
00080
00081
00082
00083
00084
00085
00086 public function getSession()
00087 {
00088 return Mage::getSingleton('paypal/session');
00089 }
00090
00091
00092
00093
00094
00095
00096 public function getCheckout()
00097 {
00098 return Mage::getSingleton('checkout/session');
00099 }
00100
00101
00102
00103
00104
00105
00106 public function getQuote()
00107 {
00108 return $this->getCheckout()->getQuote();
00109 }
00110
00111
00112
00113
00114
00115
00116 public function getRedirectUrl()
00117 {
00118 return $this->getApi()->getRedirectUrl();
00119 }
00120
00121 public function getCountryRegionId()
00122 {
00123 $a = $this->getApi()->getShippingAddress();
00124 return $this;
00125 }
00126
00127
00128
00129
00130
00131
00132 public function canUseInternal()
00133 {
00134 return false;
00135 }
00136
00137
00138
00139
00140
00141
00142 public function canUseForMultishipping()
00143 {
00144 return false;
00145 }
00146
00147
00148
00149
00150
00151
00152 public function catchError()
00153 {
00154 if ($this->getApi()->getError()) {
00155 $s = $this->getCheckout();
00156 $e = $this->getApi()->getError();
00157 switch ($e['type']) {
00158 case 'CURL':
00159 $s->addError(Mage::helper('paypal')->__('There was an error connecting to the Paypal server: %s', $e['message']));
00160 break;
00161
00162 case 'API':
00163 $s->addError(Mage::helper('paypal')->__('There was an error during communication with Paypal: %s - %s', $e['short_message'], $e['long_message']));
00164 break;
00165 }
00166 }
00167 return $this;
00168 }
00169
00170
00171
00172
00173
00174
00175 public function throwError()
00176 {
00177 if ($this->getApi()->getError()) {
00178 $s = $this->getCheckout();
00179 $e = $this->getApi()->getError();
00180 switch ($e['type']) {
00181 case 'CURL':
00182 Mage::throwException(Mage::helper('paypal')->__('There was an error connecting to the Paypal server: %s', $e['message']));
00183 break;
00184
00185 case 'API':
00186 Mage::throwException(Mage::helper('paypal')->__('There was an error during communication with Paypal: %s - %s', $e['short_message'], $e['long_message']));
00187 break;
00188 }
00189 }
00190 return $this;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199 public function createFormBlock($name)
00200 {
00201 $block = $this->getLayout()->createBlock('paypal/express_form', $name)
00202 ->setMethod('paypal_express')
00203 ->setPayment($this->getPayment())
00204 ->setTemplate('paypal/express/form.phtml');
00205
00206 return $block;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215 public function createInfoBlock($name)
00216 {
00217 $block = $this->getLayout()->createBlock('paypal/express_info', $name)
00218 ->setPayment($this->getPayment())
00219 ->setTemplate('paypal/express/info.phtml');
00220 return $block;
00221 }
00222
00223 public function getOrderPlaceRedirectUrl()
00224 {
00225 return $this->getRedirectUrl();
00226 }
00227
00228
00229
00230
00231
00232
00233 public function getPaymentAction()
00234 {
00235 $paymentAction = $this->getConfigData('payment_action');
00236 if (!$paymentAction) {
00237 $paymentAction = Mage_Paypal_Model_Api_Nvp::PAYMENT_TYPE_AUTH;
00238 }
00239 return $paymentAction;
00240 }
00241
00242
00243
00244
00245
00246
00247 public function shortcutSetExpressCheckout()
00248 {
00249 $this->getQuote()->reserveOrderId()->save();
00250 $this->getApi()
00251 ->setPayment($this->getPayment())
00252 ->setPaymentType($this->getPaymentAction())
00253 ->setAmount($this->getQuote()->getBaseGrandTotal())
00254 ->setCurrencyCode($this->getQuote()->getBaseCurrencyCode())
00255 ->setInvNum($this->getQuote()->getReservedOrderId())
00256 ->callSetExpressCheckout();
00257
00258 $this->catchError();
00259
00260 $this->getSession()->setExpressCheckoutMethod('shortcut');
00261
00262 return $this;
00263 }
00264
00265
00266
00267
00268
00269
00270 public function returnFromPaypal()
00271 {
00272 $error = '';
00273
00274 try {
00275 $this->_getExpressCheckoutDetails();
00276 } catch (Exception $e) {
00277 $error=$e->getMessage();
00278 $this->getSession()->addError($e->getMessage());
00279 $this->getApi()->setRedirectUrl('paypal/express/review');
00280 }
00281 switch ($this->getApi()->getUserAction()) {
00282 case Mage_Paypal_Model_Api_Nvp::USER_ACTION_CONTINUE:
00283 $this->getApi()->setRedirectUrl(Mage::getUrl('paypal/express/review'));
00284 break;
00285
00286 case Mage_Paypal_Model_Api_Nvp::USER_ACTION_COMMIT:
00287 if ($this->getSession()->getExpressCheckoutMethod() == 'shortcut') {
00288 $this->getApi()->setRedirectUrl(Mage::getUrl('paypal/express/saveOrder'));
00289 } else {
00290 $this->getApi()->setRedirectUrl(Mage::getUrl('paypal/express/updateOrder'));
00291 }
00292 break;
00293 }
00294 return $this;
00295 }
00296
00297
00298
00299
00300
00301 protected function _getExpressCheckoutDetails()
00302 {
00303 $api = $this->getApi();
00304 $api->setPayment($this->getPayment());
00305 if (!$api->callGetExpressCheckoutDetails()) {
00306 Mage::throwException(Mage::helper('paypal')->__('Problem during communication with PayPal'));
00307 }
00308 $q = $this->getQuote();
00309 $a = $api->getShippingAddress();
00310
00311 $a->setCountryId(
00312 Mage::getModel('directory/country')->loadByCode($a->getCountry())->getId()
00313 );
00314 $a->setRegionId(
00315 Mage::getModel('directory/region')->loadByCode($a->getRegion(), $a->getCountryId())->getId()
00316 );
00317
00318
00319
00320
00321
00322
00323
00324 if ($this->getSession()->getExpressCheckoutMethod()=='shortcut'
00325 || ($this->getSession()->getExpressCheckoutMethod()!='shortcut' && $q->getCheckoutMethod()!=Mage_Sales_Model_Quote::CHECKOUT_METHOD_REGISTER)){
00326 $q->getBillingAddress()
00327 ->setPrefix($a->getPrefix())
00328 ->setFirstname($a->getFirstname())
00329 ->setMiddlename($a->getMiddlename())
00330 ->setLastname($a->getLastname())
00331 ->setSuffix($a->getSuffix())
00332 ->setEmail($a->getEmail());
00333 }
00334
00335 $q->getShippingAddress()
00336 ->importCustomerAddress($a)
00337 ->setCollectShippingRates(true);
00338
00339
00340
00341 $q->getPayment()
00342 ->setMethod('paypal_express')
00343 ->setPaypalCorrelationId($api->getCorrelationId())
00344 ->setPaypalPayerId($api->getPayerId())
00345 ->setPaypalPayerStatus($api->getPayerStatus())
00346 ->setAdditionalData($api->getPaypalPayerEmail())
00347 ;
00348
00349 $q->collectTotals()->save();
00350
00351 }
00352
00353
00354
00355
00356
00357
00358
00359 public function authorize(Varien_Object $payment, $amount)
00360 {
00361 $this->placeOrder($payment);
00362 return $this;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371 public function capture(Varien_Object $payment, $amount)
00372 {
00373 if ($payment->getCcTransId()) {
00374 $api = $this->getApi()
00375 ->setPaymentType(Mage_Paypal_Model_Api_Nvp::PAYMENT_TYPE_SALE)
00376 ->setAmount($amount)
00377 ->setBillingAddress($payment->getOrder()->getBillingAddress())
00378 ->setPayment($payment);
00379
00380 $api->setAuthorizationId($payment->getCcTransId())
00381 ->setCompleteType('NotComplete');
00382 $result = $api->callDoCapture()!==false;
00383
00384 if ($result) {
00385 $payment->setStatus('APPROVED');
00386
00387 $payment->setLastTransId($api->getTransactionId());
00388 } else {
00389 $e = $api->getError();
00390 if (isset($e['short_message'])) {
00391 $message = $e['short_message'];
00392 } else {
00393 $message = Mage::helper('paypal')->__("Unknown PayPal API error: %s", $e['code']);
00394 }
00395 if (isset($e['long_message'])) {
00396 $message .= ': '.$e['long_message'];
00397 }
00398 Mage::throwException($message);
00399 }
00400 } else {
00401 $this->placeOrder($payment);
00402 }
00403 return $this;
00404 }
00405
00406
00407
00408
00409
00410
00411
00412 public function placeOrder(Varien_Object $payment)
00413 {
00414 $api = $this->getApi();
00415
00416 $api->setAmount($payment->getOrder()->getBaseGrandTotal())
00417 ->setPayment($payment)
00418 ->setCurrencyCode($payment->getOrder()->getBaseCurrencyCode())
00419 ->setInvNum($this->getQuote()->getReservedOrderId());
00420
00421 if ($api->callDoExpressCheckoutPayment()!==false) {
00422 $payment->setStatus('APPROVED')
00423 ->setPayerId($api->getPayerId());
00424 if ($this->getPaymentAction()== Mage_Paypal_Model_Api_Nvp::PAYMENT_TYPE_AUTH) {
00425 $payment->setCcTransId($api->getTransactionId());
00426 } else {
00427 $payment->setLastTransId($api->getTransactionId());
00428 }
00429 } else {
00430 $e = $api->getError();
00431 die($e['short_message'].': '.$e['long_message']);
00432 }
00433 return $this;
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443 public function void(Varien_Object $payment)
00444 {
00445 $error = false;
00446 if($payment->getVoidTransactionId()){
00447 $api = $this->getApi();
00448 $api->setPayment($payment);
00449 $api->setAuthorizationId($payment->getVoidTransactionId());
00450
00451 if ($api->callDoVoid()!==false){
00452 $payment->setStatus('SUCCESS')
00453 ->setCcTransId($api->getTransactionId());
00454 }else{
00455 $e = $api->getError();
00456 $error = $e['short_message'].': '.$e['long_message'];
00457 }
00458 }else{
00459 $error = Mage::helper('paypal')->__('Invalid transaction id');
00460 }
00461 if ($error !== false) {
00462 Mage::throwException($error);
00463 }
00464 return $this;
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474 public function refund(Varien_Object $payment, $amount)
00475 {
00476 $error = false;
00477 if ($payment->getRefundTransactionId() && $amount>0) {
00478 $api = $this->getApi();
00479
00480 $api->setPayment($payment)
00481 ->setTransactionId($payment->getRefundTransactionId())
00482 ->setRefundType(Mage_Paypal_Model_Api_Nvp::REFUND_TYPE_PARTIAL)
00483 ->setAmount($amount);
00484
00485 if ($api->callRefundTransaction()!==false){
00486 $payment->setStatus('SUCCESS')
00487 ->setCcTransId($api->getTransactionId());
00488 } else {
00489 $e = $api->getError();
00490 $error = $e['short_message'].': '.$e['long_message'];
00491 }
00492 }else{
00493 $error = Mage::helper('paypal')->__('Error in refunding the payment');
00494 }
00495
00496 if ($error !== false) {
00497 Mage::throwException($error);
00498 }
00499 return $this;
00500 }
00501
00502
00503
00504
00505
00506 public function initialize($paymentAction, $stateObject)
00507 {
00508 if ($this->getQuote()->isVirtual()) {
00509 $address = $this->getQuote()->getBillingAddress();
00510 } else {
00511 $address = $this->getQuote()->getShippingAddress();
00512 }
00513
00514 $this->getApi()
00515 ->setPayment($this->getPayment())
00516 ->setPaymentType($paymentAction)
00517 ->setAmount($address->getBaseGrandTotal())
00518 ->setCurrencyCode($this->getQuote()->getBaseCurrencyCode())
00519 ->setShippingAddress($address)
00520 ->setInvNum($this->getQuote()->getReservedOrderId())
00521 ->callSetExpressCheckout();
00522
00523 $this->throwError();
00524
00525 $stateObject->setState(Mage_Sales_Model_Order::STATE_PENDING_PAYMENT);
00526 $stateObject->setStatus('pending_paypal');
00527 $stateObject->setIsNotified(false);
00528
00529 Mage::getSingleton('paypal/session')->unsExpressCheckoutMethod();
00530
00531 return $this;
00532 }
00533
00534
00535
00536
00537
00538
00539 public function isInitializeNeeded()
00540 {
00541 return is_object(Mage::registry('_singleton/checkout/type_onepage'));
00542 }
00543 }