Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Public Member Functions | Protected Member Functions | Protected Attributes
Ipn Class Reference
Inheritance diagram for Ipn:
AbstractIpn IpnInterface

Public Member Functions

 __construct (\Magento\Paypal\Model\ConfigFactory $configFactory, \Psr\Log\LoggerInterface $logger, \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory, \Magento\Sales\Model\OrderFactory $orderFactory, Info $paypalInfo, OrderSender $orderSender, CreditmemoSender $creditmemoSender, array $data=[])
 
 processIpnRequest ()
 
 _registerPaymentPending ()
 
- Public Member Functions inherited from AbstractIpn
 __construct (\Magento\Paypal\Model\ConfigFactory $configFactory, \Psr\Log\LoggerInterface $logger, \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory, array $data=[])
 
 getRequestData ($key=null)
 

Protected Member Functions

 _getConfig ()
 
 _getOrder ()
 
 _processOrder ()
 
 _registerDispute ()
 
 _registerAdjustment ()
 
 _registerTransaction ()
 
 _registerPaymentCapture ($skipFraudDetection=false)
 
 _registerPaymentDenial ()
 
 _registerPaymentFailure ()
 
 _registerMasspaymentsSuccess ()
 
 _registerPaymentReversal ()
 
 _registerPaymentRefund ()
 
 _registerPaymentVoid ()
 
 _importPaymentInformation ()
 
 _createIpnComment ($comment='', $addToHistory=false)
 
- Protected Member Functions inherited from AbstractIpn
 _postBack ()
 
 _filterPaymentStatus ($ipnPaymentStatus)
 
 _debug ()
 
 _addDebugData ($key, $value)
 

Protected Attributes

 $_order
 
 $_orderFactory
 
 $_paypalInfo
 
 $orderSender
 
 $creditmemoSender
 
- Protected Attributes inherited from AbstractIpn
 $_config
 
 $_ipnRequest
 
 $_debugData = []
 
 $_configFactory
 
 $_curlFactory
 

Detailed Description

PayPal Instant Payment Notification processor model @SuppressWarnings(PHPMD.CouplingBetweenObjects)

Definition at line 18 of file Ipn.php.

Constructor & Destructor Documentation

◆ __construct()

__construct ( \Magento\Paypal\Model\ConfigFactory  $configFactory,
\Psr\Log\LoggerInterface  $logger,
\Magento\Framework\HTTP\Adapter\CurlFactory  $curlFactory,
\Magento\Sales\Model\OrderFactory  $orderFactory,
Info  $paypalInfo,
OrderSender  $orderSender,
CreditmemoSender  $creditmemoSender,
array  $data = [] 
)
Parameters
\Magento\Paypal\Model\ConfigFactory$configFactory
\Psr\Log\LoggerInterface$logger
\Magento\Framework\HTTP\Adapter\CurlFactory$curlFactory
\Magento\Sales\Model\OrderFactory$orderFactory
Info$paypalInfo
OrderSender$orderSender
CreditmemoSender$creditmemoSender
array$data

Definition at line 57 of file Ipn.php.

66  {
67  parent::__construct($configFactory, $logger, $curlFactory, $data);
68  $this->_orderFactory = $orderFactory;
69  $this->_paypalInfo = $paypalInfo;
70  $this->orderSender = $orderSender;
71  $this->creditmemoSender = $creditmemoSender;
72  }
$logger
$configFactory
Definition: config_data.php:43

Member Function Documentation

◆ _createIpnComment()

_createIpnComment (   $comment = '',
  $addToHistory = false 
)
protected

Generate an "IPN" comment with additional explanation. Returns the generated comment or order status history object

Parameters
string$comment
bool$addToHistory
Returns
string|\Magento\Sales\Model\Order\Status\History

Definition at line 577 of file Ipn.php.

578  {
579  $message = __('IPN "%1"', $this->getRequestData('payment_status'));
580  if ($comment) {
581  $message .= ' ' . $comment;
582  }
583  if ($addToHistory) {
584  $message = $this->_order->addStatusHistoryComment($message);
585  $message->setIsCustomerNotified(null);
586  }
587  return $message;
588  }
__()
Definition: __.php:13
$message

◆ _getConfig()

_getConfig ( )
protected

Get config with the method code and store id and validate

Returns
\Magento\Paypal\Model\Config
Exceptions
Exception

&content_ID= developer/e_howto_admin_IPNIntro

Definition at line 102 of file Ipn.php.

103  {
104  $order = $this->_getOrder();
105  $methodCode = $order->getPayment()->getMethod();
106  $parameters = ['params' => [$methodCode, $order->getStoreId()]];
107  $this->_config = $this->_configFactory->create($parameters);
108  if (!$this->_config->isMethodActive($methodCode) || !$this->_config->isMethodAvailable()) {
109  throw new Exception(sprintf('The "%s" method isn\'t available.', $methodCode));
110  }
113  // verify merchant email intended to receive notification
114  $merchantEmail = $this->_config->getValue('businessAccount');
115  if (!$merchantEmail) {
116  return $this->_config;
117  }
118  $receiver = $this->getRequestData('business') ?: $this->getRequestData('receiver_email');
119  if (strtolower($merchantEmail) != strtolower($receiver)) {
120  throw new Exception(
121  sprintf(
122  'The requested "%s" and the configured "%s" merchant emails don\'t match.',
123  $receiver,
124  $merchantEmail
125  )
126  );
127  }
128 
129  return $this->_config;
130  }
$order
Definition: order.php:55

◆ _getOrder()

_getOrder ( )
protected

Load order

Returns
\Magento\Sales\Model\Order
Exceptions
Exception

Definition at line 138 of file Ipn.php.

139  {
140  $incrementId = $this->getRequestData('invoice');
141  $this->_order = $this->_orderFactory->create()->loadByIncrementId($incrementId);
142  if (!$this->_order->getId()) {
143  throw new Exception(sprintf('The "%s" order ID is incorrect. Verify the ID and try again.', $incrementId));
144  }
145  return $this->_order;
146  }

◆ _importPaymentInformation()

_importPaymentInformation ( )
protected

Map payment information from IPN to payment object Returns true if there were changes in information

Returns
bool @SuppressWarnings(PHPMD.CyclomaticComplexity) @SuppressWarnings(PHPMD.NPathComplexity)

Detect pending payment, frauds TODO: implement logic in one place

See also
\Magento\Paypal\Model\Pro::importPaymentInfo()

Definition at line 510 of file Ipn.php.

511  {
512  $payment = $this->_order->getPayment();
513  $was = $payment->getAdditionalInformation();
514 
515  // collect basic information
516  $from = [];
517  foreach ([
519  'payer_email' => Info::PAYER_EMAIL,
525  ] as $privateKey => $publicKey) {
526  if (is_int($privateKey)) {
527  $privateKey = $publicKey;
528  }
529  $value = $this->getRequestData($privateKey);
530  if ($value) {
531  $from[$publicKey] = $value;
532  }
533  }
534  if (isset($from['payment_status'])) {
535  $from['payment_status'] = $this->_filterPaymentStatus($this->getRequestData('payment_status'));
536  }
537 
538  // collect fraud filters
539  $fraudFilters = [];
540  for ($i = 1; $value = $this->getRequestData("fraud_management_pending_filters_{$i}"); $i++) {
541  $fraudFilters[] = $value;
542  }
543  if ($fraudFilters) {
544  $from[Info::FRAUD_FILTERS] = $fraudFilters;
545  }
546 
547  $this->_paypalInfo->importToPayment($from, $payment);
548 
555  $payment->setIsTransactionPending(true);
556  if ($fraudFilters) {
557  $payment->setIsFraudDetected(true);
558  }
559  }
561  $payment->setIsTransactionApproved(true);
563  $payment->setIsTransactionDenied(true);
564  }
565 
566  return $was != $payment->getAdditionalInformation();
567  }
static isPaymentReviewRequired(\Magento\Payment\Model\InfoInterface $payment)
Definition: Info.php:338
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
static isPaymentFailed(\Magento\Payment\Model\InfoInterface $payment)
Definition: Info.php:411
$payment
Definition: order.php:17
_filterPaymentStatus($ipnPaymentStatus)
$value
Definition: gender.phtml:16
static isPaymentSuccessful(\Magento\Payment\Model\InfoInterface $payment)
Definition: Info.php:381
$i
Definition: gallery.phtml:31

◆ _processOrder()

_processOrder ( )
protected

IPN workflow implementation Everything should be added to order comments. In positive processing cases customer will get email notifications. Admin will be notified on errors.

Returns
void
Exceptions

Definition at line 156 of file Ipn.php.

157  {
158  $this->_getConfig();
159  try {
160  // Handle payment_status
161  $transactionType = $this->getRequestData('txn_type');
162  switch ($transactionType) {
163  // handle new case created
165  $this->_registerDispute();
166  break;
167  // handle new adjustment is created
169  $this->_registerAdjustment();
170  break;
171  //handle new transaction created
172  default:
173  $this->_registerTransaction();
174  break;
175  }
176  } catch (\Magento\Framework\Exception\LocalizedException $e) {
177  $comment = $this->_createIpnComment(__('Note: %1', $e->getMessage()), true);
178  $comment->save();
179  throw $e;
180  }
181  }
_createIpnComment($comment='', $addToHistory=false)
Definition: Ipn.php:577
__()
Definition: __.php:13

◆ _registerAdjustment()

_registerAdjustment ( )
protected

Process adjustment notification

Returns
void

Definition at line 210 of file Ipn.php.

211  {
212  $reasonCode = $this->getRequestData('reason_code');
213  $reasonComment = $this->_paypalInfo->explainReasonCode($reasonCode);
214  $notificationAmount = $this->_order->getBaseCurrency()->formatTxt($this->getRequestData('mc_gross'));
215  // Add IPN comment about registered dispute
216  $message = __(
217  'IPN "%1". A dispute has been resolved and closed. %2 Transaction amount %3.',
218  ucfirst($reasonCode),
219  $notificationAmount,
220  $reasonComment
221  );
222  $this->_order->addStatusHistoryComment($message)->setIsCustomerNotified(false)->save();
223  }
__()
Definition: __.php:13
$message

◆ _registerDispute()

_registerDispute ( )
protected

Process dispute notification

Returns
void

Definition at line 188 of file Ipn.php.

189  {
190  $reasonComment = $this->_paypalInfo->explainReasonCode($this->getRequestData('reason_code'));
191  $caseType = $this->getRequestData('case_type');
192  $caseTypeLabel = $this->_paypalInfo->getCaseTypeLabel($caseType);
193  $caseId = $this->getRequestData('case_id');
194  //Add IPN comment about registered dispute
195  $message = __(
196  'IPN "%1". Case type "%2". Case ID "%3" %4',
197  ucfirst($caseType),
198  $caseTypeLabel,
199  $caseId,
200  $reasonComment
201  );
202  $this->_order->addStatusHistoryComment($message)->setIsCustomerNotified(false)->save();
203  }
__()
Definition: __.php:13
$message

◆ _registerMasspaymentsSuccess()

_registerMasspaymentsSuccess ( )
protected

The status "Processed" is used when all Masspayments are successful

Returns
void

Definition at line 414 of file Ipn.php.

415  {
416  $comment = $this->_createIpnComment('', true);
417  $comment->save();
418  }
_createIpnComment($comment='', $addToHistory=false)
Definition: Ipn.php:577

◆ _registerPaymentCapture()

_registerPaymentCapture (   $skipFraudDetection = false)
protected

Process completed payment (either full or partial)

Parameters
bool$skipFraudDetection
Returns
void

Definition at line 283 of file Ipn.php.

284  {
285  if ($this->getRequestData('transaction_entity') == 'auth') {
286  return;
287  }
288  $parentTransactionId = $this->getRequestData('parent_txn_id');
289  $this->_importPaymentInformation();
290  $payment = $this->_order->getPayment();
291  $payment->setTransactionId($this->getRequestData('txn_id'));
292  $payment->setCurrencyCode($this->getRequestData('mc_currency'));
293  $payment->setPreparedMessage($this->_createIpnComment(''));
294  $payment->setParentTransactionId($parentTransactionId);
295  $payment->setShouldCloseParentTransaction('Completed' === $this->getRequestData('auth_status'));
296  $payment->setIsTransactionClosed(0);
297  $payment->registerCaptureNotification(
298  $this->getRequestData('mc_gross'),
299  $skipFraudDetection && $parentTransactionId
300  );
301  $this->_order->save();
302 
303  // notify customer
304  $invoice = $payment->getCreatedInvoice();
305  if ($invoice && !$this->_order->getEmailSent()) {
306  $this->orderSender->send($this->_order);
307  $this->_order->addStatusHistoryComment(
308  __('You notified customer about invoice #%1.', $invoice->getIncrementId())
309  )
310  ->setIsCustomerNotified(true)
311  ->save();
312  }
313  }
_createIpnComment($comment='', $addToHistory=false)
Definition: Ipn.php:577
__()
Definition: __.php:13
$payment
Definition: order.php:17
$invoice

◆ _registerPaymentDenial()

_registerPaymentDenial ( )
protected

Process denied payment notification

Returns
void
Exceptions
Exception

Definition at line 321 of file Ipn.php.

322  {
323  try {
324  $this->_importPaymentInformation();
325  $this->_order->getPayment()
326  ->setTransactionId($this->getRequestData('txn_id'))
327  ->setNotificationResult(true)
328  ->setIsTransactionClosed(true)
329  ->deny(false);
330  $this->_order->save();
331  } catch (LocalizedException $e) {
332  if ($e->getMessage() != __('We cannot cancel this order.')) {
333  throw $e;
334  }
335  }
336  }
__()
Definition: __.php:13

◆ _registerPaymentFailure()

_registerPaymentFailure ( )
protected

Treat failed payment as order cancellation

Returns
void

Definition at line 343 of file Ipn.php.

344  {
345  $this->_importPaymentInformation();
346  $this->_order->registerCancellation($this->_createIpnComment(''))->save();
347  }
_createIpnComment($comment='', $addToHistory=false)
Definition: Ipn.php:577

◆ _registerPaymentPending()

_registerPaymentPending ( )

Process payment pending notification

Returns
void
Exceptions
Exception

Definition at line 355 of file Ipn.php.

356  {
357  $reason = $this->getRequestData('pending_reason');
358  if ('authorization' === $reason) {
359  $this->_registerPaymentAuthorization();
360  return;
361  }
362  if ('order' === $reason) {
363  throw new Exception('The "order" authorizations aren\'t implemented.');
364  }
365  // case when was placed using PayPal standard
366  if (\Magento\Sales\Model\Order::STATE_PENDING_PAYMENT == $this->_order->getState()
367  && !$this->getRequestData('transaction_entity')
368  ) {
369  $this->_registerPaymentCapture();
370  return;
371  }
372 
373  $this->_importPaymentInformation();
374 
375  $this->_order->getPayment()
376  ->setPreparedMessage($this->_createIpnComment($this->_paypalInfo->explainPendingReason($reason)))
377  ->setTransactionId($this->getRequestData('txn_id'))
378  ->setIsTransactionClosed(0)
379  ->update(false);
380  $this->_order->save();
381  }
_createIpnComment($comment='', $addToHistory=false)
Definition: Ipn.php:577
_registerPaymentCapture($skipFraudDetection=false)
Definition: Ipn.php:283

◆ _registerPaymentRefund()

_registerPaymentRefund ( )
protected

Process a refund

Returns
void

Definition at line 455 of file Ipn.php.

456  {
457  $this->_importPaymentInformation();
458  $reason = $this->getRequestData('reason_code');
459  $isRefundFinal = !$this->_paypalInfo->isReversalDisputable($reason);
460  $payment = $this->_order->getPayment()
461  ->setPreparedMessage($this->_createIpnComment($this->_paypalInfo->explainReasonCode($reason)))
462  ->setTransactionId($this->getRequestData('txn_id'))
463  ->setParentTransactionId($this->getRequestData('parent_txn_id'))
464  ->setIsTransactionClosed($isRefundFinal)
465  ->registerRefundNotification(-1 * $this->getRequestData('mc_gross'));
466  $this->_order->save();
467 
468  // TODO: there is no way to close a capture right now
469 
470  $creditMemo = $payment->getCreatedCreditmemo();
471  if ($creditMemo) {
472  $this->creditmemoSender->send($creditMemo);
473  $this->_order->addStatusHistoryComment(
474  __('You notified customer about creditmemo #%1.', $creditMemo->getIncrementId())
475  )
476  ->setIsCustomerNotified(true)
477  ->save();
478  }
479  }
_createIpnComment($comment='', $addToHistory=false)
Definition: Ipn.php:577
__()
Definition: __.php:13
$payment
Definition: order.php:17

◆ _registerPaymentReversal()

_registerPaymentReversal ( )
protected

Process payment reversal and cancelled reversal notification

Returns
void

Definition at line 425 of file Ipn.php.

426  {
427  $reasonCode = $this->getRequestData('reason_code');
428  $reasonComment = $this->_paypalInfo->explainReasonCode($reasonCode);
429  $notificationAmount = $this->_order->getBaseCurrency()
430  ->formatTxt(
431  $this->getRequestData('mc_gross') + $this->getRequestData('mc_fee')
432  );
433  $paymentStatus = $this->_filterPaymentStatus($this->getRequestData('payment_status'));
434  $orderStatus = $paymentStatus ==
436  //Change order status to PayPal Reversed/PayPal Cancelled Reversal if it is possible.
437  $message = __(
438  'IPN "%1". %2 Transaction amount %3. Transaction ID: "%4"',
439  $this->getRequestData('payment_status'),
440  $reasonComment,
441  $notificationAmount,
442  $this->getRequestData('txn_id')
443  );
444  $this->_order->setStatus($orderStatus);
445  $this->_order->addStatusHistoryComment($message, $orderStatus)
446  ->setIsCustomerNotified(false)
447  ->save();
448  }
__()
Definition: __.php:13
const ORDER_STATUS_CANCELED_REVERSAL
Definition: Info.php:163
$message
_filterPaymentStatus($ipnPaymentStatus)
$orderStatus
Definition: order_status.php:9
const PAYMENTSTATUS_REVERSED
Definition: Info.php:133

◆ _registerPaymentVoid()

_registerPaymentVoid ( )
protected

Process voided authorization

Returns
void

Definition at line 486 of file Ipn.php.

487  {
488  $this->_importPaymentInformation();
489 
490  $parentTxnId = $this->getRequestData('transaction_entity') == 'auth'
491  ? $this->getRequestData('txn_id')
492  : $this->getRequestData('parent_txn_id');
493 
494  $this->_order->getPayment()
495  ->setPreparedMessage($this->_createIpnComment(''))
496  ->setParentTransactionId($parentTxnId)
497  ->registerVoidNotification();
498 
499  $this->_order->save();
500  }
_createIpnComment($comment='', $addToHistory=false)
Definition: Ipn.php:577

◆ _registerTransaction()

_registerTransaction ( )
protected

Process regular IPN notifications

Returns
void
Exceptions

Definition at line 233 of file Ipn.php.

234  {
235  // Handle payment_status
236  $paymentStatus = $this->_filterPaymentStatus($this->getRequestData('payment_status'));
237  switch ($paymentStatus) {
238  // paid
240  $this->_registerPaymentCapture(true);
241  break;
242  // the holded payment was denied on paypal side
244  $this->_registerPaymentDenial();
245  break;
246  // customer attempted to pay via bank account, but failed
248  // cancel order
249  $this->_registerPaymentFailure();
250  break;
251  // payment was obtained, but money were not captured yet
253  $this->_registerPaymentPending();
254  break;
257  break;
259  //break is intentionally omitted
261  $this->_registerPaymentReversal();
262  break;
264  $this->_registerPaymentRefund();
265  break;
266  // authorization expire/void
268  // break is intentionally omitted
270  $this->_registerPaymentVoid();
271  break;
272  default:
273  throw new Exception("The '{$paymentStatus}' payment status couldn't be handled.");
274  }
275  }
const PAYMENTSTATUS_COMPLETED
Definition: Info.php:117
const PAYMENTSTATUS_PROCESSED
Definition: Info.php:137
_registerPaymentCapture($skipFraudDetection=false)
Definition: Ipn.php:283
_filterPaymentStatus($ipnPaymentStatus)
const PAYMENTSTATUS_UNREVERSED
Definition: Info.php:135
const PAYMENTSTATUS_REFUNDED
Definition: Info.php:129
const PAYMENTSTATUS_REVERSED
Definition: Info.php:133

◆ processIpnRequest()

processIpnRequest ( )

Get ipn data, send verification to PayPal, run corresponding handler

Returns
void
Exceptions
Exception

Implements IpnInterface.

Definition at line 80 of file Ipn.php.

81  {
82  $this->_addDebugData('ipn', $this->getRequestData());
83 
84  try {
85  $this->_getConfig();
86  $this->_postBack();
87  $this->_processOrder();
88  } catch (Exception $e) {
89  $this->_addDebugData('exception', $e->getMessage());
90  $this->_debug();
91  throw $e;
92  }
93  $this->_debug();
94  }

Field Documentation

◆ $_order

$_order
protected

Definition at line 23 of file Ipn.php.

◆ $_orderFactory

$_orderFactory
protected

Definition at line 28 of file Ipn.php.

◆ $_paypalInfo

$_paypalInfo
protected

Definition at line 35 of file Ipn.php.

◆ $creditmemoSender

$creditmemoSender
protected

Definition at line 45 of file Ipn.php.

◆ $orderSender

$orderSender
protected

Definition at line 40 of file Ipn.php.


The documentation for this class was generated from the following file: