PageRenderTime 41ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/MXWest/magento-ce-1.5.1.0
PHP | 686 lines | 418 code | 65 blank | 203 comment | 55 complexity | a2cc848697b43f76d33f078ece150262 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, GPL-2.0, WTFPL
  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) 2010 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->_config = Mage::getModel('paypal/config'); // empty config model, without specific payment method
  93. if (isset($request['test_ipn']) && 1 == $request['test_ipn']) {
  94. $this->_config->sandboxFlag = true;
  95. }
  96. $this->_config->debug = true;
  97. $this->_debugData = array('ipn' => $request);
  98. ksort($this->_debugData['ipn']);
  99. try {
  100. if ($httpAdapter) {
  101. $this->_postBack($httpAdapter);
  102. }
  103. if (isset($this->_request['txn_type']) && 'recurring_payment' == $this->_request['txn_type']) {
  104. $this->_processRecurringProfile();
  105. } else {
  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(stripslashes($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. throw new Exception(sprintf('Wrong order ID: "%s".', $id));
  160. }
  161. // re-initialize config with the method code and store id
  162. $methodCode = $this->_order->getPayment()->getMethod();
  163. $this->_config = Mage::getModel('paypal/config', array($methodCode, $this->_order->getStoreId()));
  164. if (!$this->_config->isMethodActive($methodCode) || !$this->_config->isMethodAvailable()) {
  165. throw new Exception(sprintf('Method "%s" is not available.', $methodCode));
  166. }
  167. $this->_verifyOrder();
  168. }
  169. return $this->_order;
  170. }
  171. /**
  172. * Load recurring profile
  173. *
  174. * @return Mage_Sales_Model_Recurring_Profile
  175. * @throws Exception
  176. */
  177. protected function _getRecurringProfile()
  178. {
  179. if (empty($this->_recurringProfile)) {
  180. // get proper recurring profile
  181. $internalReferenceId = $this->_request['rp_invoice_id'];
  182. $this->_recurringProfile = Mage::getModel('sales/recurring_profile')
  183. ->loadByInternalReferenceId($internalReferenceId);
  184. if (!$this->_recurringProfile->getId()) {
  185. throw new Exception(
  186. sprintf('Wrong recurring profile INTERNAL_REFERENCE_ID: "%s".', $internalReferenceId)
  187. );
  188. }
  189. // re-initialize config with the method code and store id
  190. $methodCode = $this->_recurringProfile->getMethodCode();
  191. $this->_config = Mage::getModel(
  192. 'paypal/config', array($methodCode, $this->_recurringProfile->getStoreId())
  193. );
  194. if (!$this->_config->isMethodActive($methodCode) || !$this->_config->isMethodAvailable()) {
  195. throw new Exception(sprintf('Method "%s" is not available.', $methodCode));
  196. }
  197. }
  198. return $this->_recurringProfile;
  199. }
  200. /**
  201. * Validate incoming request data, as PayPal recommends
  202. *
  203. * @throws Exception
  204. * @link https://cms.paypal.com/cgi-bin/marketingweb?cmd=_render-content&content_ID=developer/e_howto_admin_IPNIntro
  205. */
  206. protected function _verifyOrder()
  207. {
  208. // verify merchant email intended to receive notification
  209. $merchantEmail = $this->_config->businessAccount;
  210. if ($merchantEmail) {
  211. $receiverEmail = $this->getRequestData('business');
  212. if (!$receiverEmail) {
  213. $receiverEmail = $this->getRequestData('receiver_email');
  214. }
  215. if ($merchantEmail != $receiverEmail) {
  216. throw new Exception(
  217. sprintf(
  218. 'Requested %s and configured %s merchant emails do not match.', $receiverEmail, $merchantEmail
  219. )
  220. );
  221. }
  222. }
  223. }
  224. /**
  225. * IPN workflow implementation
  226. * Everything should be added to order comments. In positive processing cases customer will get email notifications.
  227. * Admin will be notified on errors.
  228. */
  229. protected function _processOrder()
  230. {
  231. $this->_order = null;
  232. $this->_getOrder();
  233. $this->_info = Mage::getSingleton('paypal/info');
  234. try {
  235. // handle payment_status
  236. $paymentStatus = $this->_filterPaymentStatus($this->_request['payment_status']);
  237. switch ($paymentStatus) {
  238. // paid
  239. case Mage_Paypal_Model_Info::PAYMENTSTATUS_COMPLETED:
  240. $this->_registerPaymentCapture();
  241. break;
  242. // the holded payment was denied on paypal side
  243. case Mage_Paypal_Model_Info::PAYMENTSTATUS_DENIED:
  244. $this->_registerPaymentDenial();
  245. break;
  246. // customer attempted to pay via bank account, but failed
  247. case Mage_Paypal_Model_Info::PAYMENTSTATUS_FAILED:
  248. // cancel order
  249. $this->_registerPaymentFailure();
  250. break;
  251. // refund forced by PayPal
  252. case Mage_Paypal_Model_Info::PAYMENTSTATUS_REVERSED: // break is intentionally omitted
  253. case Mage_Paypal_Model_Info::PAYMENTSTATUS_UNREVERSED: // or returned back :)
  254. $this->_registerPaymentReversal();
  255. break;
  256. // refund by merchant on PayPal side
  257. case Mage_Paypal_Model_Info::PAYMENTSTATUS_REFUNDED:
  258. $this->_registerPaymentRefund();
  259. break;
  260. // payment was obtained, but money were not captured yet
  261. case Mage_Paypal_Model_Info::PAYMENTSTATUS_PENDING:
  262. $this->_registerPaymentPending();
  263. break;
  264. // MassPayments success
  265. case Mage_Paypal_Model_Info::PAYMENTSTATUS_PROCESSED:
  266. $this->_registerMasspaymentsSuccess();
  267. break;
  268. // authorization expire/void
  269. case Mage_Paypal_Model_Info::PAYMENTSTATUS_EXPIRED: // break is intentionally omitted
  270. case Mage_Paypal_Model_Info::PAYMENTSTATUS_VOIDED:
  271. $this->_registerPaymentVoid();
  272. break;
  273. default:
  274. throw new Exception("Cannot handle payment status '{$paymentStatus}'.");
  275. }
  276. } catch (Mage_Core_Exception $e) {
  277. $comment = $this->_createIpnComment(Mage::helper('paypal')->__('Note: %s', $e->getMessage()), true);
  278. $comment->save();
  279. throw $e;
  280. }
  281. }
  282. /**
  283. * Process notification from recurring profile payments
  284. */
  285. protected function _processRecurringProfile()
  286. {
  287. $this->_recurringProfile = null;
  288. $this->_getRecurringProfile();
  289. try {
  290. // handle payment_status
  291. $paymentStatus = $this->_filterPaymentStatus($this->_request['payment_status']);
  292. switch ($paymentStatus) {
  293. // paid
  294. case Mage_Paypal_Model_Info::PAYMENTSTATUS_COMPLETED:
  295. $this->_registerRecurringProfilePaymentCapture();
  296. break;
  297. default:
  298. throw new Exception("Cannot handle payment status '{$paymentStatus}'.");
  299. }
  300. } catch (Mage_Core_Exception $e) {
  301. // TODO: add to payment profile comments
  302. // $comment = $this->_createIpnComment(Mage::helper('paypal')->__('Note: %s', $e->getMessage()), true);
  303. // $comment->save();
  304. throw $e;
  305. }
  306. }
  307. /**
  308. * Register recurring payment notification, create and process order
  309. */
  310. protected function _registerRecurringProfilePaymentCapture()
  311. {
  312. $price = $this->getRequestData('mc_gross') - $this->getRequestData('tax') - $this->getRequestData('shipping');
  313. $productItemInfo = new Varien_Object;
  314. $type = trim($this->getRequestData('period_type'));
  315. if ($type == 'Trial') {
  316. $productItemInfo->setPaymentType(Mage_Sales_Model_Recurring_Profile::PAYMENT_TYPE_TRIAL);
  317. } elseif ($type == 'Regular') {
  318. $productItemInfo->setPaymentType(Mage_Sales_Model_Recurring_Profile::PAYMENT_TYPE_REGULAR);
  319. }
  320. $productItemInfo->setTaxAmount($this->getRequestData('tax'));
  321. $productItemInfo->setShippingAmount($this->getRequestData('shipping'));
  322. $productItemInfo->setPrice($price);
  323. $order = $this->_recurringProfile->createOrder($productItemInfo);
  324. $payment = $order->getPayment();
  325. $payment->setTransactionId($this->getRequestData('txn_id'))
  326. ->setPreparedMessage($this->_createIpnComment(''))
  327. ->setIsTransactionClosed(0);
  328. $order->save();
  329. $this->_recurringProfile->addOrderRelation($order->getId());
  330. $payment->registerCaptureNotification($this->getRequestData('mc_gross'));
  331. $order->save();
  332. // notify customer
  333. if ($invoice = $payment->getCreatedInvoice()) {
  334. $message = Mage::helper('paypal')->__('Notified customer about invoice #%s.', $invoice->getIncrementId());
  335. $comment = $order->sendNewOrderEmail()->addStatusHistoryComment($message)
  336. ->setIsCustomerNotified(true)
  337. ->save();
  338. }
  339. }
  340. /**
  341. * Process completed payment (either full or partial)
  342. */
  343. protected function _registerPaymentCapture()
  344. {
  345. if ($this->getRequestData('transaction_entity') == 'auth') {
  346. return;
  347. }
  348. $this->_importPaymentInformation();
  349. $payment = $this->_order->getPayment();
  350. $payment->setTransactionId($this->getRequestData('txn_id'))
  351. ->setPreparedMessage($this->_createIpnComment(''))
  352. ->setParentTransactionId($this->getRequestData('parent_txn_id'))
  353. ->setShouldCloseParentTransaction('Completed' === $this->getRequestData('auth_status'))
  354. ->setIsTransactionClosed(0)
  355. ->registerCaptureNotification($this->getRequestData('mc_gross'));
  356. $this->_order->save();
  357. // notify customer
  358. if ($invoice = $payment->getCreatedInvoice() && !$this->_order->getEmailSent()) {
  359. $comment = $this->_order->sendNewOrderEmail()->addStatusHistoryComment(
  360. Mage::helper('paypal')->__('Notified customer about invoice #%s.', $invoice->getIncrementId())
  361. )
  362. ->setIsCustomerNotified(true)
  363. ->save();
  364. }
  365. }
  366. /**
  367. * Process denied payment notification
  368. */
  369. protected function _registerPaymentDenial()
  370. {
  371. $this->_importPaymentInformation();
  372. $this->_order->getPayment()
  373. ->setTransactionId($this->getRequestData('txn_id'))
  374. ->setNotificationResult(true)
  375. ->setIsTransactionClosed(true)
  376. ->registerPaymentReviewAction(Mage_Sales_Model_Order_Payment::REVIEW_ACTION_DENY, false);
  377. $this->_order->save();
  378. }
  379. /**
  380. * Treat failed payment as order cancellation
  381. */
  382. protected function _registerPaymentFailure()
  383. {
  384. $this->_importPaymentInformation();
  385. $this->_order
  386. ->registerCancellation($this->_createIpnComment(''), false)
  387. ->save();
  388. }
  389. /**
  390. * Process a refund or a chargeback
  391. */
  392. protected function _registerPaymentRefund()
  393. {
  394. $this->_importPaymentInformation();
  395. $reason = $this->getRequestData('reason_code');
  396. $isRefundFinal = !$this->_info->isReversalDisputable($reason);
  397. $payment = $this->_order->getPayment()
  398. ->setPreparedMessage($this->_createIpnComment($this->_info->explainReasonCode($reason)))
  399. ->setTransactionId($this->getRequestData('txn_id'))
  400. ->setParentTransactionId($this->getRequestData('parent_txn_id'))
  401. ->setIsTransactionClosed($isRefundFinal)
  402. ->registerRefundNotification(-1 * $this->getRequestData('mc_gross'));
  403. $this->_order->save();
  404. // TODO: there is no way to close a capture right now
  405. if ($creditmemo = $payment->getCreatedCreditmemo()) {
  406. $creditmemo->sendEmail();
  407. $comment = $this->_order->addStatusHistoryComment(
  408. Mage::helper('paypal')->__('Notified customer about creditmemo #%s.', $creditmemo->getIncrementId())
  409. )
  410. ->setIsCustomerNotified(true)
  411. ->save();
  412. }
  413. }
  414. /**
  415. * Process payment reversal notification
  416. */
  417. protected function _registerPaymentReversal()
  418. {
  419. /**
  420. * PayPal may send such payment status when triggered IPR denial
  421. * Note that this check is done on the old payment info object, before importing new payment information
  422. */
  423. if ($this->_info->isPaymentReviewRequired($this->_order->getPayment())) {
  424. $this->_registerPaymentDenial();
  425. return;
  426. }
  427. if ('chargeback_reimbursement' == $this->getRequestData('reason_code')) {
  428. // TODO: chargebacks reversals are not implemented
  429. return;
  430. }
  431. // treat as a usual charegeback
  432. $this->_registerPaymentRefund();
  433. }
  434. /**
  435. * Process payment pending notification
  436. *
  437. * @throws Exception
  438. */
  439. public function _registerPaymentPending()
  440. {
  441. $reason = $this->getRequestData('pending_reason');
  442. if ('authorization' === $reason) {
  443. $this->_registerPaymentAuthorization();
  444. return;
  445. }
  446. if ('order' === $reason) {
  447. throw new Exception('The "order" authorizations are not implemented.');
  448. }
  449. // case when was placed using PayPal standard
  450. if (Mage_Sales_Model_Order::STATE_PENDING_PAYMENT == $this->_order->getState()) {
  451. $this->_registerPaymentCapture();
  452. return;
  453. }
  454. $this->_importPaymentInformation();
  455. $this->_order->getPayment()
  456. ->setPreparedMessage($this->_createIpnComment($this->_info->explainPendingReason($reason)))
  457. ->setTransactionId($this->getRequestData('txn_id'))
  458. ->setIsTransactionClosed(0)
  459. ->registerPaymentReviewAction(Mage_Sales_Model_Order_Payment::REVIEW_ACTION_UPDATE, false);
  460. $this->_order->save();
  461. }
  462. /**
  463. * Register authorized payment
  464. */
  465. protected function _registerPaymentAuthorization()
  466. {
  467. $this->_importPaymentInformation();
  468. $this->_order->getPayment()
  469. ->setPreparedMessage($this->_createIpnComment(''))
  470. ->setTransactionId($this->getRequestData('txn_id'))
  471. ->setParentTransactionId($this->getRequestData('parent_txn_id'))
  472. ->setIsTransactionClosed(0)
  473. ->registerAuthorizationNotification($this->getRequestData('mc_gross'));
  474. if (!$this->_order->getEmailSent()) {
  475. $this->_order->sendNewOrderEmail();
  476. }
  477. $this->_order->save();
  478. }
  479. /**
  480. * Process voided authorization
  481. */
  482. protected function _registerPaymentVoid()
  483. {
  484. $this->_importPaymentInformation();
  485. $this->_order->getPayment()
  486. ->setPreparedMessage($this->_createIpnComment(''))
  487. ->setParentTransactionId($this->getRequestData('txn_id')) // this is the authorization transaction ID
  488. ->registerVoidNotification();
  489. $this->_order->save();
  490. }
  491. /**
  492. * TODO
  493. * The status "Processed" is used when all Masspayments are successful
  494. */
  495. protected function _registerMasspaymentsSuccess()
  496. {
  497. $comment = $this->_createIpnComment('', true);
  498. $comment->save();
  499. }
  500. /**
  501. * Generate an "IPN" comment with additional explanation.
  502. * Returns the generated comment or order status history object
  503. *
  504. * @param string $comment
  505. * @param bool $addToHistory
  506. * @return string|Mage_Sales_Model_Order_Status_History
  507. */
  508. protected function _createIpnComment($comment = '', $addToHistory = false)
  509. {
  510. $paymentStatus = $this->getRequestData('payment_status');
  511. $message = Mage::helper('paypal')->__('IPN "%s".', $paymentStatus);
  512. if ($comment) {
  513. $message .= ' ' . $comment;
  514. }
  515. if ($addToHistory) {
  516. $message = $this->_order->addStatusHistoryComment($message);
  517. $message->setIsCustomerNotified(null);
  518. }
  519. return $message;
  520. }
  521. /**
  522. * Map payment information from IPN to payment object
  523. * Returns true if there were changes in information
  524. *
  525. * @param Mage_Payment_Model_Info $payment
  526. * @return bool
  527. */
  528. protected function _importPaymentInformation()
  529. {
  530. $payment = $this->_order->getPayment();
  531. $was = $payment->getAdditionalInformation();
  532. // collect basic information
  533. $from = array();
  534. foreach (array(
  535. Mage_Paypal_Model_Info::PAYER_ID,
  536. 'payer_email' => Mage_Paypal_Model_Info::PAYER_EMAIL,
  537. Mage_Paypal_Model_Info::PAYER_STATUS,
  538. Mage_Paypal_Model_Info::ADDRESS_STATUS,
  539. Mage_Paypal_Model_Info::PROTECTION_EL,
  540. Mage_Paypal_Model_Info::PAYMENT_STATUS,
  541. Mage_Paypal_Model_Info::PENDING_REASON,
  542. ) as $privateKey => $publicKey) {
  543. if (is_int($privateKey)) {
  544. $privateKey = $publicKey;
  545. }
  546. $value = $this->getRequestData($privateKey);
  547. if ($value) {
  548. $from[$publicKey] = $value;
  549. }
  550. }
  551. if (isset($from['payment_status'])) {
  552. $from['payment_status'] = $this->_filterPaymentStatus($this->getRequestData('payment_status'));
  553. }
  554. // collect fraud filters
  555. $fraudFilters = array();
  556. for ($i = 1; $value = $this->getRequestData("fraud_management_pending_filters_{$i}"); $i++) {
  557. $fraudFilters[] = $value;
  558. }
  559. if ($fraudFilters) {
  560. $from[Mage_Paypal_Model_Info::FRAUD_FILTERS] = $fraudFilters;
  561. }
  562. $this->_info->importToPayment($from, $payment);
  563. /**
  564. * Detect pending payment, frauds
  565. * TODO: implement logic in one place
  566. * @see Mage_Paypal_Model_Pro::importPaymentInfo()
  567. */
  568. if ($this->_info->isPaymentReviewRequired($payment)) {
  569. $payment->setIsTransactionPending(true);
  570. if ($fraudFilters) {
  571. $payment->setIsFraudDetected(true);
  572. }
  573. }
  574. if ($this->_info->isPaymentSuccessful($payment)) {
  575. $payment->setIsTransactionApproved(true);
  576. } elseif ($this->_info->isPaymentFailed($payment)) {
  577. $payment->setIsTransactionDenied(true);
  578. }
  579. return $was != $payment->getAdditionalInformation();
  580. }
  581. /**
  582. * Filter payment status from NVP into paypal/info format
  583. *
  584. * @param string $ipnPaymentStatus
  585. * @return string
  586. */
  587. protected function _filterPaymentStatus($ipnPaymentStatus)
  588. {
  589. switch ($ipnPaymentStatus) {
  590. case 'Created': // break is intentionally omitted
  591. case 'Completed': return Mage_Paypal_Model_Info::PAYMENTSTATUS_COMPLETED;
  592. case 'Denied': return Mage_Paypal_Model_Info::PAYMENTSTATUS_DENIED;
  593. case 'Expired': return Mage_Paypal_Model_Info::PAYMENTSTATUS_EXPIRED;
  594. case 'Failed': return Mage_Paypal_Model_Info::PAYMENTSTATUS_FAILED;
  595. case 'Pending': return Mage_Paypal_Model_Info::PAYMENTSTATUS_PENDING;
  596. case 'Refunded': return Mage_Paypal_Model_Info::PAYMENTSTATUS_REFUNDED;
  597. case 'Reversed': return Mage_Paypal_Model_Info::PAYMENTSTATUS_REVERSED;
  598. case 'Canceled_Reversal': return Mage_Paypal_Model_Info::PAYMENTSTATUS_UNREVERSED;
  599. case 'Processed': return Mage_Paypal_Model_Info::PAYMENTSTATUS_PROCESSED;
  600. case 'Voided': return Mage_Paypal_Model_Info::PAYMENTSTATUS_VOIDED;
  601. }
  602. return '';
  603. // documented in NVP, but not documented in IPN:
  604. //Mage_Paypal_Model_Info::PAYMENTSTATUS_NONE
  605. //Mage_Paypal_Model_Info::PAYMENTSTATUS_INPROGRESS
  606. //Mage_Paypal_Model_Info::PAYMENTSTATUS_REFUNDEDPART
  607. }
  608. /**
  609. * Log debug data to file
  610. *
  611. * @param mixed $debugData
  612. */
  613. protected function _debug()
  614. {
  615. if ($this->_config->debug) {
  616. $file = $this->_config->getMethodCode() ? "payment_{$this->_config->getMethodCode()}.log"
  617. : self::DEFAULT_LOG_FILE;
  618. Mage::getModel('core/log_adapter', $file)->log($this->_debugData);
  619. }
  620. }
  621. }