/** * Check order status before save * * @param Order $order * @return $this * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function check(Order $order) { if (!$order->getId()) { return $order; } if (!$order->isCanceled() && !$order->canUnhold() && !$order->canInvoice() && !$order->canShip()) { if (0 == $order->getBaseGrandTotal() || $order->canCreditmemo()) { if ($order->getState() !== Order::STATE_COMPLETE) { $order->setState(Order::STATE_COMPLETE)->setStatus($order->getConfig()->getStateDefaultStatus(Order::STATE_COMPLETE)); } } elseif (floatval($order->getTotalRefunded()) || !$order->getTotalRefunded() && $order->hasForcedCanCreditmemo()) { if ($order->getState() !== Order::STATE_CLOSED) { $order->setState(Order::STATE_CLOSED)->setStatus($order->getConfig()->getStateDefaultStatus(Order::STATE_CLOSED)); } } } if ($order->getState() == Order::STATE_NEW && $order->getIsInProcess()) { $order->setState(Order::STATE_PROCESSING)->setStatus($order->getConfig()->getStateDefaultStatus(Order::STATE_PROCESSING)); } return $this; }
/** * Check order status before save * * @param Order $order * @return $this */ public function check(Order $order) { if (!$order->getId()) { return $order; } $userNotification = $order->hasCustomerNoteNotify() ? $order->getCustomerNoteNotify() : null; if (!$order->isCanceled() && !$order->canUnhold() && !$order->canInvoice() && !$order->canShip()) { if (0 == $order->getBaseGrandTotal() || $order->canCreditmemo()) { if ($order->getState() !== Order::STATE_COMPLETE) { $order->setState(Order::STATE_COMPLETE, true, '', $userNotification, false); } } elseif (floatval($order->getTotalRefunded()) || !$order->getTotalRefunded() && $order->hasForcedCanCreditmemo()) { if ($order->getState() !== Order::STATE_CLOSED) { $order->setState(Order::STATE_CLOSED, true, '', $userNotification, false); } } } if ($order->getState() == Order::STATE_NEW && $order->getIsInProcess()) { $order->setState(Order::STATE_PROCESSING, true, '', $userNotification); } return $this; }
protected function _processInvoice() { if ($this->_order->canInvoice()) { $invoice = $this->_order->prepareInvoice(); switch ($this->_paymentInst->getConfigPaymentAction()) { case \Magento\Payment\Model\Method\AbstractMethod::ACTION_AUTHORIZE: $invoice->register(); $this->_order->setState(\Magento\Sales\Model\Order::STATE_PROCESSING, 'authorized'); break; case \Magento\Payment\Model\Method\AbstractMethod::ACTION_AUTHORIZE_CAPTURE: $this->_paymentInst->setAssistCaptureResponse(true); $invoice->register()->capture(); break; } /** @var \Magento\Framework\DB\Transaction $transaction */ $transaction = $this->_transactionFactory->create(); $transaction->addObject($invoice)->addObject($invoice->getOrder())->save(); $this->_invoiceSender->send($invoice); } elseif ($this->_order->isCanceled()) { throw new \Magento\Framework\Exception\LocalizedException(__('Order canceled')); } else { throw new \Magento\Framework\Exception\LocalizedException(__('Order paid')); } }
/** * Process the Notification */ protected function _processNotification() { $this->_adyenLogger->addAdyenNotificationCronjob('Processing the notification'); $_paymentCode = $this->_paymentMethodCode(); switch ($this->_eventCode) { case Notification::REFUND_FAILED: // do nothing only inform the merchant with order comment history break; case Notification::REFUND: $ignoreRefundNotification = $this->_getConfigData('ignore_refund_notification', 'adyen_abstract', $this->_order->getStoreId()); if ($ignoreRefundNotification != true) { $this->_refundOrder(); //refund completed $this->_setRefundAuthorized(); } else { $this->_adyenLogger->addAdyenNotificationCronjob('Setting to ignore refund notification is enabled so ignore this notification'); } break; case Notification::PENDING: if ($this->_getConfigData('send_email_bank_sepa_on_pending', 'adyen_abstract', $this->_order->getStoreId())) { // Check if payment is banktransfer or sepa if true then send out order confirmation email $isBankTransfer = $this->_isBankTransfer(); if ($isBankTransfer || $this->_paymentMethod == 'sepadirectdebit') { if (!$this->_order->getEmailSent()) { $this->_orderSender->send($this->_order); $this->_adyenLogger->addAdyenNotificationCronjob('Send orderconfirmation email to shopper'); } } } break; case Notification::HANDLED_EXTERNALLY: case Notification::AUTHORISATION: // for POS don't do anything on the AUTHORIZATION if ($_paymentCode != "adyen_pos") { $this->_authorizePayment(); } break; case Notification::MANUAL_REVIEW_REJECT: // don't do anything it will send a CANCEL_OR_REFUND notification when this payment is captured break; case Notification::MANUAL_REVIEW_ACCEPT: /* * only process this if you are on auto capture. * On manual capture you will always get Capture or CancelOrRefund notification */ if ($this->_isAutoCapture()) { $this->_setPaymentAuthorized(false); } break; case Notification::CAPTURE: if ($_paymentCode != "adyen_pos") { /* * ignore capture if you are on auto capture * this could be called if manual review is enabled and you have a capture delay */ if (!$this->_isAutoCapture()) { $this->_setPaymentAuthorized(false, true); } } else { // FOR POS authorize the payment on the CAPTURE notification $this->_authorizePayment(); } break; case Notification::CAPTURE_FAILED: case Notification::CANCELLATION: case Notification::CANCELLED: $this->_holdCancelOrder(true); break; case Notification::CANCEL_OR_REFUND: if (isset($this->_modificationResult) && $this->_modificationResult != "") { if ($this->_modificationResult == "cancel") { $this->_holdCancelOrder(true); } elseif ($this->_modificationResult == "refund") { $this->_refundOrder(); //refund completed $this->_setRefundAuthorized(); } } else { if ($this->_order->isCanceled() || $this->_order->getState() === \Magento\Sales\Model\Order::STATE_HOLDED) { $this->_adyenLogger->addAdyenNotificationCronjob('Order is already cancelled or holded so do nothing'); } else { if ($this->_order->canCancel() || $this->_order->canHold()) { $this->_adyenLogger->addAdyenNotificationCronjob('try to cancel the order'); $this->_holdCancelOrder(true); } else { $this->_adyenLogger->addAdyenNotificationCronjob('try to refund the order'); // refund $this->_refundOrder(); //refund completed $this->_setRefundAuthorized(); } } } break; case Notification::RECURRING_CONTRACT: // storedReferenceCode $recurringDetailReference = $this->_pspReference; // check if there is already a BillingAgreement $billingAgreement = $this->_billingAgreementFactory->create(); $billingAgreement->load($recurringDetailReference, 'reference_id'); if ($billingAgreement && $billingAgreement->getAgreementId() > 0 && $billingAgreement->isValid()) { try { $billingAgreement->addOrderRelation($this->_order); $billingAgreement->setStatus($billingAgreement::STATUS_ACTIVE); $billingAgreement->setIsObjectChanged(true); $this->_order->addRelatedObject($billingAgreement); $message = __('Used existing billing agreement #%s.', $billingAgreement->getReferenceId()); } catch (Exception $e) { // could be that it is already linked to this order $message = __('Used existing billing agreement #%s.', $billingAgreement->getReferenceId()); } } else { $this->_order->getPayment()->setBillingAgreementData(['billing_agreement_id' => $recurringDetailReference, 'method_code' => $this->_order->getPayment()->getMethodCode()]); // create new object $billingAgreement = $this->_billingAgreementFactory->create(); $billingAgreement->setStoreId($this->_order->getStoreId()); $billingAgreement->importOrderPayment($this->_order->getPayment()); // get all data for this contract by doing a listRecurringCall $customerReference = $billingAgreement->getCustomerReference(); $storeId = $billingAgreement->getStoreId(); /* * for quest checkout users we can't save this in the billing agreement * because it is linked to customer */ if ($customerReference && $storeId) { $listRecurringContracts = null; try { $listRecurringContracts = $this->_adyenPaymentRequest->getRecurringContractsForShopper($customerReference, $storeId); } catch (\Exception $exception) { $this->_adyenLogger->addAdyenNotificationCronjob($exception->getMessage()); } $contractDetail = null; // get current Contract details and get list of all current ones $recurringReferencesList = []; if ($listRecurringContracts) { foreach ($listRecurringContracts as $rc) { $recurringReferencesList[] = $rc['recurringDetailReference']; if (isset($rc['recurringDetailReference']) && $rc['recurringDetailReference'] == $recurringDetailReference) { $contractDetail = $rc; } } } if ($contractDetail != null) { // update status of all the current saved agreements in magento $billingAgreements = $this->_billingAgreementCollectionFactory->create(); $billingAgreements->addFieldToFilter('customer_id', $customerReference); // get collection foreach ($billingAgreements as $updateBillingAgreement) { if (!in_array($updateBillingAgreement->getReferenceId(), $recurringReferencesList)) { $updateBillingAgreement->setStatus(\Adyen\Payment\Model\Billing\Agreement::STATUS_CANCELED); $updateBillingAgreement->save(); } else { $updateBillingAgreement->setStatus(\Adyen\Payment\Model\Billing\Agreement::STATUS_ACTIVE); $updateBillingAgreement->save(); } } // add this billing agreement $billingAgreement->parseRecurringContractData($contractDetail); if ($billingAgreement->isValid()) { $message = __('Created billing agreement #%1.', $billingAgreement->getReferenceId()); // save into sales_billing_agreement_order $billingAgreement->addOrderRelation($this->_order); // add to order to save agreement $this->_order->addRelatedObject($billingAgreement); } else { $message = __('Failed to create billing agreement for this order.'); } } else { $this->_adyenLogger->addAdyenNotificationCronjob('Failed to create billing agreement for this order ' . '(listRecurringCall did not contain contract)'); $this->_adyenLogger->addAdyenNotificationCronjob(__('recurringDetailReference in notification is %1', $recurringDetailReference)); $this->_adyenLogger->addAdyenNotificationCronjob(__('CustomerReference is: %1 and storeId is %2', $customerReference, $storeId)); $this->_adyenLogger->addAdyenNotificationCronjob(print_r($listRecurringContracts, 1)); $message = __('Failed to create billing agreement for this order ' . '(listRecurringCall did not contain contract)'); } $comment = $this->_order->addStatusHistoryComment($message); $this->_order->addRelatedObject($comment); } } break; default: $this->_adyenLogger->addAdyenNotificationCronjob(sprintf('This notification event: %s is not supported so will be ignored', $this->_eventCode)); break; } }
/** * @param $params */ protected function _processNotification() { $this->_debugData['_processNotification'] = 'Processing the notification'; $_paymentCode = $this->_paymentMethodCode(); switch ($this->_eventCode) { case Notification::REFUND_FAILED: // do nothing only inform the merchant with order comment history break; case Notification::REFUND: $ignoreRefundNotification = $this->_getConfigData('ignore_refund_notification', 'adyen_abstract', $this->_order->getStoreId()); if ($ignoreRefundNotification != true) { $this->_refundOrder(); //refund completed $this->_setRefundAuthorized(); } else { $this->_debugData['_processNotification info'] = 'Setting to ignore refund notification is enabled so ignore this notification'; } break; case Notification::PENDING: if ($this->_getConfigData('send_email_bank_sepa_on_pending', 'adyen_abstract', $this->_order->getStoreId())) { // Check if payment is banktransfer or sepa if true then send out order confirmation email $isBankTransfer = $this->_isBankTransfer($this->_paymentMethod); if ($isBankTransfer || $this->_paymentMethod == 'sepadirectdebit') { // $this->_order->sendNewOrderEmail(); // send order email $this->_orderSender->send($this->_order); $this->_debugData['_processNotification send email'] = 'Send orderconfirmation email to shopper'; } } break; case Notification::HANDLED_EXTERNALLY: case Notification::AUTHORISATION: // for POS don't do anything on the AUTHORIZATION if ($_paymentCode != "adyen_pos") { $this->_authorizePayment(); } break; case Notification::MANUAL_REVIEW_REJECT: // don't do anything it will send a CANCEL_OR_REFUND notification when this payment is captured break; case Notification::MANUAL_REVIEW_ACCEPT: // only process this if you are on auto capture. On manual capture you will always get Capture or CancelOrRefund notification if ($this->_isAutoCapture()) { $this->_setPaymentAuthorized(false); } break; case Notification::CAPTURE: if ($_paymentCode != "adyen_pos") { // ignore capture if you are on auto capture (this could be called if manual review is enabled and you have a capture delay) if (!$this->_isAutoCapture()) { $this->_setPaymentAuthorized(false, true); } } else { // uncancel the order just to be sure that order is going trough // $this->_uncancelOrder($this->_order); // FOR POS authorize the payment on the CAPTURE notification $this->_authorizePayment($this->_order, $this->_paymentMethod); } break; case Notification::CAPTURE_FAILED: case Notification::CANCELLATION: case Notification::CANCELLED: $this->_holdCancelOrder(true); break; case Notification::CANCEL_OR_REFUND: if (isset($this->_modificationResult) && $this->_modificationResult != "") { if ($this->_modificationResult == "cancel") { $this->_holdCancelOrder(true); } elseif ($this->_modificationResult == "refund") { $this->_refundOrder(); //refund completed $this->_setRefundAuthorized(); } } else { if ($this->_order->isCanceled() || $this->_order->getState() === \Magento\Sales\Model\Order::STATE_HOLDED) { $this->_debugData['_processNotification info'] = 'Order is already cancelled or holded so do nothing'; } else { if ($this->_order->canCancel() || $this->_order->canHold()) { $this->_debugData['_processNotification info'] = 'try to cancel the order'; $this->_holdCancelOrder($this->_order, true); } else { $this->_debugData['_processNotification info'] = 'try to refund the order'; // refund $this->_refundOrder(); //refund completed $this->_setRefundAuthorized(); } } } break; default: $this->_order->getPayment()->getMethodInstance()->writeLog('notification event not supported!'); break; } }