IpnTest.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Paypal\Model;
  7. use Magento\Paypal\Model\IpnFactory;
  8. use Magento\Sales\Api\Data\OrderInterface;
  9. use Magento\Sales\Model\Order;
  10. use Magento\Sales\Model\Order\Creditmemo;
  11. /**
  12. * @magentoAppArea frontend
  13. */
  14. class IpnTest extends \PHPUnit\Framework\TestCase
  15. {
  16. /**
  17. * @var \Magento\Framework\ObjectManagerInterface
  18. */
  19. protected $_objectManager;
  20. protected function setUp()
  21. {
  22. $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
  23. }
  24. /**
  25. * @param string $currencyCode
  26. * @dataProvider currencyProvider
  27. * @magentoDataFixture Magento/Paypal/_files/order_express.php
  28. * @magentoConfigFixture current_store payment/paypal_direct/active 1
  29. * @magentoConfigFixture current_store payment/paypal_express/active 1
  30. * @magentoConfigFixture current_store paypal/general/merchant_country US
  31. */
  32. public function testProcessIpnRequestExpressCurrency($currencyCode)
  33. {
  34. $this->_processIpnRequestCurrency($currencyCode);
  35. }
  36. /**
  37. * Refund full order amount by Paypal Express IPN message service.
  38. *
  39. * @magentoDataFixture Magento/Paypal/_files/order_express_with_invoice_and_shipping.php
  40. * @magentoConfigFixture current_store payment/paypal_express/active 1
  41. * @magentoConfigFixture current_store paypal/general/merchant_country US
  42. */
  43. public function testProcessIpnRequestFullRefund()
  44. {
  45. $ipnData = require __DIR__ . '/../_files/ipn_refund.php';
  46. $ipnFactory = $this->_objectManager->create(IpnFactory::class);
  47. $ipnModel = $ipnFactory->create(
  48. [
  49. 'data' => $ipnData,
  50. 'curlFactory' => $this->_createMockedHttpAdapter()
  51. ]
  52. );
  53. $ipnModel->processIpnRequest();
  54. $order = $this->_objectManager->create(Order::class);
  55. $order->loadByIncrementId('100000001');
  56. $creditmemoItems = $order->getCreditmemosCollection()->getItems();
  57. $creditmemo = current($creditmemoItems);
  58. $this->assertEquals(Order::STATE_CLOSED, $order->getState()) ;
  59. $this->assertEquals(1, count($creditmemoItems));
  60. $this->assertEquals(Creditmemo::STATE_REFUNDED, $creditmemo->getState());
  61. $this->assertEquals(10, $order->getSubtotalRefunded());
  62. $this->assertEquals(10, $order->getBaseSubtotalRefunded());
  63. $this->assertEquals(20, $order->getShippingRefunded());
  64. $this->assertEquals(20, $order->getBaseShippingRefunded());
  65. $this->assertEquals(30, $order->getTotalRefunded());
  66. $this->assertEquals(30, $order->getBaseTotalRefunded());
  67. $this->assertEquals(30, $order->getTotalOnlineRefunded());
  68. $this->assertEmpty($order->getTotalOfflineRefunded());
  69. }
  70. /**
  71. * Partial refund of order amount by Paypal Express IPN message service.
  72. *
  73. * @magentoDataFixture Magento/Paypal/_files/order_express_with_invoice_and_shipping.php
  74. * @magentoConfigFixture current_store payment/paypal_express/active 1
  75. * @magentoConfigFixture current_store paypal/general/merchant_country US
  76. */
  77. public function testProcessIpnRequestPartialRefund()
  78. {
  79. $ipnData = require __DIR__ . '/../_files/ipn_refund.php';
  80. $refundAmount = -15;
  81. $ipnData['mc_gross'] = $refundAmount;
  82. $ipnFactory = $this->_objectManager->create(IpnFactory::class);
  83. $ipnModel = $ipnFactory->create(
  84. [
  85. 'data' => $ipnData,
  86. 'curlFactory' => $this->_createMockedHttpAdapter()
  87. ]
  88. );
  89. $ipnModel->processIpnRequest();
  90. $order = $this->_objectManager->create(Order::class);
  91. $order->loadByIncrementId('100000001');
  92. $creditmemoItems = $order->getCreditmemosCollection()->getItems();
  93. $comments = $order->load($order->getId())->getAllStatusHistory();
  94. $commentData = reset($comments);
  95. $commentOrigin = sprintf(
  96. 'IPN "Refunded". Refund issued by merchant. Registered notification about refunded amount of $%d.00. '.
  97. 'Transaction ID: "%s". Credit Memo has not been created. Please create offline Credit Memo.',
  98. abs($refundAmount),
  99. $ipnData['txn_id']
  100. );
  101. $this->assertEquals(Order::STATE_PROCESSING, $order->getState()) ;
  102. $this->assertEmpty(count($creditmemoItems));
  103. $this->assertEquals(1, count($comments));
  104. $this->assertEquals($commentOrigin, $commentData->getComment());
  105. }
  106. /**
  107. * Refund rest of order amount by Paypal Express IPN message service.
  108. *
  109. * @magentoDataFixture Magento/Paypal/_files/order_express_with_invoice_and_shipping.php
  110. * @magentoConfigFixture current_store payment/paypal_express/active 1
  111. * @magentoConfigFixture current_store paypal/general/merchant_country US
  112. */
  113. public function testProcessIpnRequestRestRefund()
  114. {
  115. $ipnData = require __DIR__ . '/../_files/ipn_refund.php';
  116. $ipnFactory = $this->_objectManager->create(IpnFactory::class);
  117. $ipnModel = $ipnFactory->create(
  118. [
  119. 'data' => $ipnData,
  120. 'curlFactory' => $this->_createMockedHttpAdapter()
  121. ]
  122. );
  123. $ipnModel->processIpnRequest();
  124. $order = $this->_objectManager->create(Order::class);
  125. $order->loadByIncrementId('100000001');
  126. $creditmemoItems = $order->getCreditmemosCollection()->getItems();
  127. $this->assertEquals(Order::STATE_CLOSED, $order->getState()) ;
  128. $this->assertEquals(1, count($creditmemoItems));
  129. $this->assertEquals(10, $order->getSubtotalRefunded());
  130. $this->assertEquals(10, $order->getBaseSubtotalRefunded());
  131. $this->assertEquals(20, $order->getShippingRefunded());
  132. $this->assertEquals(20, $order->getBaseShippingRefunded());
  133. $this->assertEquals(30, $order->getTotalRefunded());
  134. $this->assertEquals(30, $order->getBaseTotalRefunded());
  135. $this->assertEquals(30, $order->getTotalOnlineRefunded());
  136. $this->assertEmpty($order->getTotalOfflineRefunded());
  137. }
  138. /**
  139. * Test processIpnRequest() currency check for paypal_express and paypal_standard payment methods
  140. *
  141. * @param string $currencyCode
  142. */
  143. protected function _processIpnRequestCurrency($currencyCode)
  144. {
  145. $ipnData = require __DIR__ . '/../_files/ipn.php';
  146. $ipnData['mc_currency'] = $currencyCode;
  147. /** @var $ipnFactory \Magento\Paypal\Model\IpnFactory */
  148. $ipnFactory = $this->_objectManager->create(\Magento\Paypal\Model\IpnFactory::class);
  149. $model = $ipnFactory->create(['data' => $ipnData, 'curlFactory' => $this->_createMockedHttpAdapter()]);
  150. $model->processIpnRequest();
  151. $order = $this->_objectManager->create(\Magento\Sales\Model\Order::class);
  152. $order->loadByIncrementId('100000001');
  153. $this->_assertOrder($order, $currencyCode);
  154. }
  155. /**
  156. * Perform order state and status assertions depending on currency code
  157. *
  158. * @param \Magento\Sales\Model\Order $order
  159. * @param string $currencyCode
  160. */
  161. protected function _assertOrder($order, $currencyCode)
  162. {
  163. if ($currencyCode == 'USD') {
  164. $this->assertEquals('complete', $order->getState());
  165. $this->assertEquals('complete', $order->getStatus());
  166. } else {
  167. $this->assertEquals('payment_review', $order->getState());
  168. $this->assertEquals('fraud', $order->getStatus());
  169. }
  170. }
  171. /**
  172. * Data provider for currency check tests
  173. *
  174. * @static
  175. * @return array
  176. */
  177. public static function currencyProvider()
  178. {
  179. return [['USD'], ['EUR']];
  180. }
  181. /**
  182. * Mocked HTTP adapter to get VERIFIED PayPal IPN postback result
  183. *
  184. * @return \Magento\Framework\HTTP\Adapter\Curl
  185. */
  186. protected function _createMockedHttpAdapter()
  187. {
  188. $factory = $this->createPartialMock(\Magento\Framework\HTTP\Adapter\CurlFactory::class, ['create']);
  189. $adapter = $this->createPartialMock(\Magento\Framework\HTTP\Adapter\Curl::class, ['read', 'write']);
  190. $adapter->expects($this->once())->method('read')->with()->will($this->returnValue("\nVERIFIED"));
  191. $adapter->expects($this->once())->method('write');
  192. $factory->expects($this->once())->method('create')->with()->will($this->returnValue($adapter));
  193. return $factory;
  194. }
  195. }