PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/magento/app/code/core/Mage/Paypal/Model/Ipn.php

https://bitbucket.org/jit_bec/shopifine
PHP | 694 lines | 425 code | 66 blank | 203 comment | 55 complexity | dcb5d96011e850079b918a46cd5e0511 MD5 | raw file
Possible License(s): LGPL-3.0
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Paypal
  23. * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * PayPal Instant Payment Notification processor model
  28. */
  29. class Mage_Paypal_Model_Ipn
  30. {
  31. /**
  32. * Default log filename
  33. *
  34. * @var string
  35. */
  36. const DEFAULT_LOG_FILE = 'paypal_unknown_ipn.log';
  37. /*
  38. * @param Mage_Sales_Model_Order
  39. */
  40. protected $_order = null;
  41. /*
  42. * Recurring profile instance
  43. *
  44. * @var Mage_Sales_Model_Recurring_Profile
  45. */
  46. protected $_recurringProfile = null;
  47. /**
  48. *
  49. * @var Mage_Paypal_Model_Config
  50. */
  51. protected $_config = null;
  52. /**
  53. * PayPal info instance
  54. *
  55. * @var Mage_Paypal_Model_Info
  56. */
  57. protected $_info = null;
  58. /**
  59. * IPN request data
  60. * @var array
  61. */
  62. protected $_request = array();
  63. /**
  64. * Collected debug information
  65. *
  66. * @var array
  67. */
  68. protected $_debugData = array();
  69. /**
  70. * IPN request data getter
  71. *
  72. * @param string $key
  73. * @return array|string
  74. */
  75. public function getRequestData($key = null)
  76. {
  77. if (null === $key) {
  78. return $this->_request;
  79. }
  80. return isset($this->_request[$key]) ? $this->_request[$key] : null;
  81. }
  82. /**
  83. * Get ipn data, send verification to PayPal, run corresponding handler
  84. *
  85. * @param array $request
  86. * @param Zend_Http_Client_Adapter_Interface $httpAdapter
  87. * @throws Exception
  88. */
  89. public function processIpnRequest(array $request, Zend_Http_Client_Adapter_Interface $httpAdapter = null)
  90. {
  91. $this->_request = $request;
  92. $this->_debugData = array('ipn' => $request);
  93. ksort($this->_debugData['ipn']);
  94. try {
  95. if (isset($this->_request['txn_type']) && 'recurring_payment' == $this->_request['txn_type']) {
  96. $this->_getRecurringProfile();
  97. if ($httpAdapter) {
  98. $this->_postBack($httpAdapter);
  99. }
  100. $this->_processRecurringProfile();
  101. } else {
  102. $this->_getOrder();
  103. if ($httpAdapter) {
  104. $this->_postBack($httpAdapter);
  105. }
  106. $this->_processOrder();
  107. }
  108. } catch (Exception $e) {
  109. $this->_debugData['exception'] = $e->getMessage();
  110. $this->_debug();
  111. throw $e;
  112. }
  113. $this->_debug();
  114. }
  115. /**
  116. * Post back to PayPal to check whether this request is a valid one
  117. *
  118. * @param Zend_Http_Client_Adapter_Interface $httpAdapter
  119. */
  120. protected function _postBack(Zend_Http_Client_Adapter_Interface $httpAdapter)
  121. {
  122. $sReq = '';
  123. foreach ($this->_request as $k => $v) {
  124. $sReq .= '&'.$k.'='.urlencode($v);
  125. }
  126. $sReq .= "&cmd=_notify-validate";
  127. $sReq = substr($sReq, 1);
  128. $this->_debugData['postback'] = $sReq;
  129. $this->_debugData['postback_to'] = $this->_config->getPaypalUrl();
  130. $httpAdapter->write(Zend_Http_Client::POST, $this->_config->getPaypalUrl(), '1.1', array(), $sReq);
  131. try {
  132. $response = $httpAdapter->read();
  133. } catch (Exception $e) {
  134. $this->_debugData['http_error'] = array('error' => $e->getMessage(), 'code' => $e->getCode());
  135. throw $e;
  136. }
  137. $this->_debugData['postback_result'] = $response;
  138. $response = preg_split('/^\r?$/m', $response, 2);
  139. $response = trim($response[1]);
  140. if ($response != 'VERIFIED') {
  141. throw new Exception('PayPal IPN postback failure. See ' . self::DEFAULT_LOG_FILE . ' for details.');
  142. }
  143. unset($this->_debugData['postback'], $this->_debugData['postback_result']);
  144. }
  145. /**
  146. * Load and validate order, instantiate proper configuration
  147. *
  148. *
  149. * @return Mage_Sales_Model_Order
  150. * @throws Exception
  151. */
  152. protected function _getOrder()
  153. {
  154. if (empty($this->_order)) {
  155. // get proper order
  156. $id = $this->_request['invoice'];
  157. $this->_order = Mage::getModel('sales/order')->loadByIncrementId($id);
  158. if (!$this->_order->getId()) {
  159. $this->_debugData['exception'] = sprintf('Wrong order ID: "%s".', $id);
  160. $this->_debug();
  161. Mage::app()->getResponse()
  162. ->setHeader('HTTP/1.1','503 Service Unavailable')
  163. ->sendResponse();
  164. exit;
  165. }
  166. // re-initialize config with the method code and store id
  167. $methodCode = $this->_order->getPayment()->getMethod();
  168. $this->_config = Mage::getModel('paypal/config', array($methodCode, $this->_order->getStoreId()));
  169. if (!$this->_config->isMethodActive($methodCode) || !$this->_config->isMethodAvailable()) {
  170. throw new Exception(sprintf('Method "%s" is not available.', $methodCode));
  171. }
  172. $this->_verifyOrder();
  173. }
  174. return $this->_order;
  175. }
  176. /**
  177. * Load recurring profile
  178. *
  179. * @return Mage_Sales_Model_Recurring_Profile
  180. * @throws Exception
  181. */
  182. protected function _getRecurringProfile()
  183. {
  184. if (empty($this->_recurringProfile)) {
  185. // get proper recurring profile
  186. $internalReferenceId = $this->_request['rp_invoice_id'];
  187. $this->_recurringProfile = Mage::getModel('sales/recurring_profile')
  188. ->loadByInternalReferenceId($internalReferenceId);
  189. if (!$this->_recurringProfile->getId()) {
  190. throw new Exception(
  191. sprintf('Wrong recurring profile INTERNAL_REFERENCE_ID: "%s".', $internalReferenceId)
  192. );
  193. }
  194. // re-initialize config with the method code and store id
  195. $methodCode = $this->_recurringProfile->getMethodCode();
  196. $this->_config = Mage::getModel(
  197. 'paypal/config', array($methodCode, $this->_recurringProfile->getStoreId())
  198. );
  199. if (!$this->_config->isMethodActive($methodCode) || !$this->_config->isMethodAvailable()) {
  200. throw new Exception(sprintf('Method "%s" is not available.', $methodCode));
  201. }
  202. }
  203. return $this->_recurringProfile;
  204. }
  205. /**
  206. * Validate incoming request data, as PayPal recommends
  207. *
  208. * @throws Exception
  209. * @link https://cms.paypal.com/cgi-bin/marketingweb?cmd=_render-content&content_ID=developer/e_howto_admin_IPNIntro
  210. */
  211. protected function _verifyOrder()
  212. {
  213. // verify merchant email intended to receive notification
  214. $merchantEmail = $this->_config->businessAccount;
  215. if ($merchantEmail) {
  216. $receiverEmail = $this->getRequestData('business');
  217. if (!$receiverEmail) {
  218. $receiverEmail = $this->getRequestData('receiver_email');
  219. }
  220. if (strtolower($merchantEmail) != strtolower($receiverEmail)) {
  221. throw new Exception(
  222. sprintf(
  223. 'Requested %s and configured %s merchant emails do not match.', $receiverEmail, $merchantEmail
  224. )
  225. );
  226. }
  227. }
  228. }
  229. /**
  230. * IPN workflow implementation
  231. * Everything should be added to order comments. In positive processing cases customer will get email notifications.
  232. * Admin will be notified on errors.
  233. */
  234. protected function _processOrder()
  235. {
  236. $this->_order = null;
  237. $this->_getOrder();
  238. $this->_info = Mage::getSingleton('paypal/info');
  239. try {
  240. // handle payment_status
  241. $paymentStatus = $this->_filterPaymentStatus($this->_request['payment_status']);
  242. switch ($paymentStatus) {
  243. // paid
  244. case Mage_Paypal_Model_Info::PAYMENTSTATUS_COMPLETED:
  245. $this->_registerPaymentCapture();
  246. break;
  247. // the holded payment was denied on paypal side
  248. case Mage_Paypal_Model_Info::PAYMENTSTATUS_DENIED:
  249. $this->_registerPaymentDenial();
  250. break;
  251. // customer attempted to pay via bank account, but failed
  252. case Mage_Paypal_Model_Info::PAYMENTSTATUS_FAILED:
  253. // cancel order
  254. $this->_registerPaymentFailure();
  255. break;
  256. // refund forced by PayPal
  257. case Mage_Paypal_Model_Info::PAYMENTSTATUS_REVERSED: // break is intentionally omitted
  258. case Mage_Paypal_Model_Info::PAYMENTSTATUS_UNREVERSED: // or returned back :)
  259. $this->_registerPaymentReversal();
  260. break;
  261. // refund by merchant on PayPal side
  262. case Mage_Paypal_Model_Info::PAYMENTSTATUS_REFUNDED:
  263. $this->_registerPaymentRefund();
  264. break;
  265. // payment was obtained, but money were not captured yet
  266. case Mage_Paypal_Model_Info::PAYMENTSTATUS_PENDING:
  267. $this->_registerPaymentPending();
  268. break;
  269. // MassPayments success
  270. case Mage_Paypal_Model_Info::PAYMENTSTATUS_PROCESSED:
  271. $this->_registerMasspaymentsSuccess();
  272. break;
  273. // authorization expire/void
  274. case Mage_Paypal_Model_Info::PAYMENTSTATUS_EXPIRED: // break is intentionally omitted
  275. case Mage_Paypal_Model_Info::PAYMENTSTATUS_VOIDED:
  276. $this->_registerPaymentVoid();
  277. break;
  278. default:
  279. throw new Exception("Cannot handle payment status '{$paymentStatus}'.");
  280. }
  281. } catch (Mage_Core_Exception $e) {
  282. $comment = $this->_createIpnComment(Mage::helper('paypal')->__('Note: %s', $e->getMessage()), true);
  283. $comment->save();
  284. throw $e;
  285. }
  286. }
  287. /**
  288. * Process notification from recurring profile payments
  289. */
  290. protected function _processRecurringProfile()
  291. {
  292. $this->_recurringProfile = null;
  293. $this->_getRecurringProfile();
  294. try {
  295. // handle payment_status
  296. $paymentStatus = $this->_filterPaymentStatus($this->_request['payment_status']);
  297. switch ($paymentStatus) {
  298. // paid
  299. case Mage_Paypal_Model_Info::PAYMENTSTATUS_COMPLETED:
  300. $this->_registerRecurringProfilePaymentCapture();
  301. break;
  302. default:
  303. throw new Exception("Cannot handle payment status '{$paymentStatus}'.");
  304. }
  305. } catch (Mage_Core_Exception $e) {
  306. // TODO: add to payment profile comments
  307. // $comment = $this->_createIpnComment(Mage::helper('paypal')->__('Note: %s', $e->getMessage()), true);
  308. // $comment->save();
  309. throw $e;
  310. }
  311. }
  312. /**
  313. * Register recurring payment notification, create and process order
  314. */
  315. protected function _registerRecurringProfilePaymentCapture()
  316. {
  317. $price = $this->getRequestData('mc_gross') - $this->getRequestData('tax') - $this->getRequestData('shipping');
  318. $productItemInfo = new Varien_Object;
  319. $type = trim($this->getRequestData('period_type'));
  320. if ($type == 'Trial') {
  321. $productItemInfo->setPaymentType(Mage_Sales_Model_Recurring_Profile::PAYMENT_TYPE_TRIAL);
  322. } elseif ($type == 'Regular') {
  323. $productItemInfo->setPaymentType(Mage_Sales_Model_Recurring_Profile::PAYMENT_TYPE_REGULAR);
  324. }
  325. $productItemInfo->setTaxAmount($this->getRequestData('tax'));
  326. $productItemInfo->setShippingAmount($this->getRequestData('shipping'));
  327. $productItemInfo->setPrice($price);
  328. $order = $this->_recurringProfile->createOrder($productItemInfo);
  329. $payment = $order->getPayment();
  330. $payment->setTransactionId($this->getRequestData('txn_id'))
  331. ->setPreparedMessage($this->_createIpnComment(''))
  332. ->setIsTransactionClosed(0);
  333. $order->save();
  334. $this->_recurringProfile->addOrderRelation($order->getId());
  335. $payment->registerCaptureNotification($this->getRequestData('mc_gross'));
  336. $order->save();
  337. // notify customer
  338. if ($invoice = $payment->getCreatedInvoice()) {
  339. $message = Mage::helper('paypal')->__('Notified customer about invoice #%s.', $invoice->getIncrementId());
  340. $comment = $order->sendNewOrderEmail()->addStatusHistoryComment($message)
  341. ->setIsCustomerNotified(true)
  342. ->save();
  343. }
  344. }
  345. /**
  346. * Process completed payment (either full or partial)
  347. */
  348. protected function _registerPaymentCapture()
  349. {
  350. if ($this->getRequestData('transaction_entity') == 'auth') {
  351. return;
  352. }
  353. $this->_importPaymentInformation();
  354. $payment = $this->_order->getPayment();
  355. $payment->setTransactionId($this->getRequestData('txn_id'))
  356. ->setPreparedMessage($this->_createIpnComment(''))
  357. ->setParentTransactionId($this->getRequestData('parent_txn_id'))
  358. ->setShouldCloseParentTransaction('Completed' === $this->getRequestData('auth_status'))
  359. ->setIsTransactionClosed(0)
  360. ->registerCaptureNotification($this->getRequestData('mc_gross'));
  361. $this->_order->save();
  362. // notify customer
  363. if ($invoice = $payment->getCreatedInvoice() && !$this->_order->getEmailSent()) {
  364. $comment = $this->_order->sendNewOrderEmail()->addStatusHistoryComment(
  365. Mage::helper('paypal')->__('Notified customer about invoice #%s.', $invoice->getIncrementId())
  366. )
  367. ->setIsCustomerNotified(true)
  368. ->save();
  369. }
  370. }
  371. /**
  372. * Process denied payment notification
  373. */
  374. protected function _registerPaymentDenial()
  375. {
  376. $this->_importPaymentInformation();
  377. $this->_order->getPayment()
  378. ->setTransactionId($this->getRequestData('txn_id'))
  379. ->setNotificationResult(true)
  380. ->setIsTransactionClosed(true)
  381. ->registerPaymentReviewAction(Mage_Sales_Model_Order_Payment::REVIEW_ACTION_DENY, false);
  382. $this->_order->save();
  383. }
  384. /**
  385. * Treat failed payment as order cancellation
  386. */
  387. protected function _registerPaymentFailure()
  388. {
  389. $this->_importPaymentInformation();
  390. $this->_order
  391. ->registerCancellation($this->_createIpnComment(''), false)
  392. ->save();
  393. }
  394. /**
  395. * Process a refund or a chargeback
  396. */
  397. protected function _registerPaymentRefund()
  398. {
  399. $this->_importPaymentInformation();
  400. $reason = $this->getRequestData('reason_code');
  401. $isRefundFinal = !$this->_info->isReversalDisputable($reason);
  402. $payment = $this->_order->getPayment()
  403. ->setPreparedMessage($this->_createIpnComment($this->_info->explainReasonCode($reason)))
  404. ->setTransactionId($this->getRequestData('txn_id'))
  405. ->setParentTransactionId($this->getRequestData('parent_txn_id'))
  406. ->setIsTransactionClosed($isRefundFinal)
  407. ->registerRefundNotification(-1 * $this->getRequestData('mc_gross'));
  408. $this->_order->save();
  409. // TODO: there is no way to close a capture right now
  410. if ($creditmemo = $payment->getCreatedCreditmemo()) {
  411. $creditmemo->sendEmail();
  412. $comment = $this->_order->addStatusHistoryComment(
  413. Mage::helper('paypal')->__('Notified customer about creditmemo #%s.', $creditmemo->getIncrementId())
  414. )
  415. ->setIsCustomerNotified(true)
  416. ->save();
  417. }
  418. }
  419. /**
  420. * Process payment reversal notification
  421. */
  422. protected function _registerPaymentReversal()
  423. {
  424. /**
  425. * PayPal may send such payment status when triggered IPR denial
  426. * Note that this check is done on the old payment info object, before importing new payment information
  427. */
  428. if ($this->_info->isPaymentReviewRequired($this->_order->getPayment())) {
  429. $this->_registerPaymentDenial();
  430. return;
  431. }
  432. if ('chargeback_reimbursement' == $this->getRequestData('reason_code')) {
  433. // TODO: chargebacks reversals are not implemented
  434. return;
  435. }
  436. // treat as a usual charegeback
  437. $this->_registerPaymentRefund();
  438. }
  439. /**
  440. * Process payment pending notification
  441. *
  442. * @throws Exception
  443. */
  444. public function _registerPaymentPending()
  445. {
  446. $reason = $this->getRequestData('pending_reason');
  447. if ('authorization' === $reason) {
  448. $this->_registerPaymentAuthorization();
  449. return;
  450. }
  451. if ('order' === $reason) {
  452. throw new Exception('The "order" authorizations are not implemented.');
  453. }
  454. // case when was placed using PayPal standard
  455. if (Mage_Sales_Model_Order::STATE_PENDING_PAYMENT == $this->_order->getState()) {
  456. $this->_registerPaymentCapture();
  457. return;
  458. }
  459. $this->_importPaymentInformation();
  460. $this->_order->getPayment()
  461. ->setPreparedMessage($this->_createIpnComment($this->_info->explainPendingReason($reason)))
  462. ->setTransactionId($this->getRequestData('txn_id'))
  463. ->setIsTransactionClosed(0)
  464. ->registerPaymentReviewAction(Mage_Sales_Model_Order_Payment::REVIEW_ACTION_UPDATE, false);
  465. $this->_order->save();
  466. }
  467. /**
  468. * Register authorized payment
  469. */
  470. protected function _registerPaymentAuthorization()
  471. {
  472. $this->_importPaymentInformation();
  473. $this->_order->getPayment()
  474. ->setPreparedMessage($this->_createIpnComment(''))
  475. ->setTransactionId($this->getRequestData('txn_id'))
  476. ->setParentTransactionId($this->getRequestData('parent_txn_id'))
  477. ->setIsTransactionClosed(0)
  478. ->registerAuthorizationNotification($this->getRequestData('mc_gross'));
  479. if (!$this->_order->getEmailSent()) {
  480. $this->_order->sendNewOrderEmail();
  481. }
  482. $this->_order->save();
  483. }
  484. /**
  485. * Process voided authorization
  486. */
  487. protected function _registerPaymentVoid()
  488. {
  489. $this->_importPaymentInformation();
  490. $parentTxnId = $this->getRequestData('transaction_entity') == 'auth'
  491. ? $this->getRequestData('txn_id') : $this->getRequestData('parent_txn_id');
  492. $this->_order->getPayment()
  493. ->setPreparedMessage($this->_createIpnComment(''))
  494. ->setParentTransactionId($parentTxnId)
  495. ->registerVoidNotification();
  496. $this->_order->save();
  497. }
  498. /**
  499. * TODO
  500. * The status "Processed" is used when all Masspayments are successful
  501. */
  502. protected function _registerMasspaymentsSuccess()
  503. {
  504. $comment = $this->_createIpnComment('', true);
  505. $comment->save();
  506. }
  507. /**
  508. * Generate an "IPN" comment with additional explanation.
  509. * Returns the generated comment or order status history object
  510. *
  511. * @param string $comment
  512. * @param bool $addToHistory
  513. * @return string|Mage_Sales_Model_Order_Status_History
  514. */
  515. protected function _createIpnComment($comment = '', $addToHistory = false)
  516. {
  517. $paymentStatus = $this->getRequestData('payment_status');
  518. $message = Mage::helper('paypal')->__('IPN "%s".', $paymentStatus);
  519. if ($comment) {
  520. $message .= ' ' . $comment;
  521. }
  522. if ($addToHistory) {
  523. $message = $this->_order->addStatusHistoryComment($message);
  524. $message->setIsCustomerNotified(null);
  525. }
  526. return $message;
  527. }
  528. /**
  529. * Map payment information from IPN to payment object
  530. * Returns true if there were changes in information
  531. *
  532. * @param Mage_Payment_Model_Info $payment
  533. * @return bool
  534. */
  535. protected function _importPaymentInformation()
  536. {
  537. $payment = $this->_order->getPayment();
  538. $was = $payment->getAdditionalInformation();
  539. // collect basic information
  540. $from = array();
  541. foreach (array(
  542. Mage_Paypal_Model_Info::PAYER_ID,
  543. 'payer_email' => Mage_Paypal_Model_Info::PAYER_EMAIL,
  544. Mage_Paypal_Model_Info::PAYER_STATUS,
  545. Mage_Paypal_Model_Info::ADDRESS_STATUS,
  546. Mage_Paypal_Model_Info::PROTECTION_EL,
  547. Mage_Paypal_Model_Info::PAYMENT_STATUS,
  548. Mage_Paypal_Model_Info::PENDING_REASON,
  549. ) as $privateKey => $publicKey) {
  550. if (is_int($privateKey)) {
  551. $privateKey = $publicKey;
  552. }
  553. $value = $this->getRequestData($privateKey);
  554. if ($value) {
  555. $from[$publicKey] = $value;
  556. }
  557. }
  558. if (isset($from['payment_status'])) {
  559. $from['payment_status'] = $this->_filterPaymentStatus($this->getRequestData('payment_status'));
  560. }
  561. // collect fraud filters
  562. $fraudFilters = array();
  563. for ($i = 1; $value = $this->getRequestData("fraud_management_pending_filters_{$i}"); $i++) {
  564. $fraudFilters[] = $value;
  565. }
  566. if ($fraudFilters) {
  567. $from[Mage_Paypal_Model_Info::FRAUD_FILTERS] = $fraudFilters;
  568. }
  569. $this->_info->importToPayment($from, $payment);
  570. /**
  571. * Detect pending payment, frauds
  572. * TODO: implement logic in one place
  573. * @see Mage_Paypal_Model_Pro::importPaymentInfo()
  574. */
  575. if ($this->_info->isPaymentReviewRequired($payment)) {
  576. $payment->setIsTransactionPending(true);
  577. if ($fraudFilters) {
  578. $payment->setIsFraudDetected(true);
  579. }
  580. }
  581. if ($this->_info->isPaymentSuccessful($payment)) {
  582. $payment->setIsTransactionApproved(true);
  583. } elseif ($this->_info->isPaymentFailed($payment)) {
  584. $payment->setIsTransactionDenied(true);
  585. }
  586. return $was != $payment->getAdditionalInformation();
  587. }
  588. /**
  589. * Filter payment status from NVP into paypal/info format
  590. *
  591. * @param string $ipnPaymentStatus
  592. * @return string
  593. */
  594. protected function _filterPaymentStatus($ipnPaymentStatus)
  595. {
  596. switch ($ipnPaymentStatus) {
  597. case 'Created': // break is intentionally omitted
  598. case 'Completed': return Mage_Paypal_Model_Info::PAYMENTSTATUS_COMPLETED;
  599. case 'Denied': return Mage_Paypal_Model_Info::PAYMENTSTATUS_DENIED;
  600. case 'Expired': return Mage_Paypal_Model_Info::PAYMENTSTATUS_EXPIRED;
  601. case 'Failed': return Mage_Paypal_Model_Info::PAYMENTSTATUS_FAILED;
  602. case 'Pending': return Mage_Paypal_Model_Info::PAYMENTSTATUS_PENDING;
  603. case 'Refunded': return Mage_Paypal_Model_Info::PAYMENTSTATUS_REFUNDED;
  604. case 'Reversed': return Mage_Paypal_Model_Info::PAYMENTSTATUS_REVERSED;
  605. case 'Canceled_Reversal': return Mage_Paypal_Model_Info::PAYMENTSTATUS_UNREVERSED;
  606. case 'Processed': return Mage_Paypal_Model_Info::PAYMENTSTATUS_PROCESSED;
  607. case 'Voided': return Mage_Paypal_Model_Info::PAYMENTSTATUS_VOIDED;
  608. }
  609. return '';
  610. // documented in NVP, but not documented in IPN:
  611. //Mage_Paypal_Model_Info::PAYMENTSTATUS_NONE
  612. //Mage_Paypal_Model_Info::PAYMENTSTATUS_INPROGRESS
  613. //Mage_Paypal_Model_Info::PAYMENTSTATUS_REFUNDEDPART
  614. }
  615. /**
  616. * Log debug data to file
  617. *
  618. * @param mixed $debugData
  619. */
  620. protected function _debug()
  621. {
  622. if ($this->_config && $this->_config->debug) {
  623. $file = $this->_config->getMethodCode() ? "payment_{$this->_config->getMethodCode()}.log"
  624. : self::DEFAULT_LOG_FILE;
  625. Mage::getModel('core/log_adapter', $file)->log($this->_debugData);
  626. }
  627. }
  628. }