/** * @magentoDataFixture Magento/Sales/_files/order.php */ public function testRedirectActionIsContentGenerated() { $this->_order->load('100000001', 'increment_id'); $this->_order->getPayment()->setMethod(\Magento\Paypal\Model\Config::METHOD_WPS); $this->_order->save(); $this->_order->load('100000001', 'increment_id'); $this->_session->setLastRealOrderId($this->_order->getRealOrderId())->setLastQuoteId($this->_order->getQuoteId()); $this->dispatch('paypal/standard/redirect'); $this->assertContains('<form action="https://www.paypal.com/cgi-bin/webscr" id="paypal_standard_checkout"' . ' name="paypal_standard_checkout" method="POST">', $this->getResponse()->getBody()); }
/** * Process voided authorization * * @return void */ protected function _registerPaymentVoid() { $this->_importPaymentInformation(); $parentTxnId = $this->getRequestData('transaction_entity') == 'auth' ? $this->getRequestData('txn_id') : $this->getRequestData('parent_txn_id'); $this->_order->getPayment()->setPreparedMessage($this->_createIpnComment(''))->setParentTransactionId($parentTxnId)->registerVoidNotification(); $this->_order->save(); }
/** * Receives webhook events from Roadrunner */ public function execute() { $this->_logger->addDebug('paystandmagento/webhook/paystand endpoint was hit'); $body = @file_get_contents('php://input'); $json = json_decode($body); $this->_logger->addDebug(">>>>> body=" . print_r($body, TRUE)); if (isset($json->resource->meta->source) && $json->resource->meta->source == "magento 2") { $quoteId = $json->resource->meta->quote; $this->_logger->addDebug('magento 2 webhook identified with quote id = ' . $quoteId); $this->_order->loadByAttribute('quote_id', $quoteId); if (!empty($this->_order->getIncrementId())) { $this->_logger->addDebug('current order increment id = ' . $this->_order->getIncrementId()); $state = $this->_order->getState(); $this->_logger->addDebug('current order state = ' . $state); $status = $this->_order->getStatus(); $this->_logger->addDebug('current order status = ' . $status); $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE; if ($this->scopeConfig->getValue(self::USE_SANDBOX, $storeScope)) { $base_url = 'https://api.paystand.co/v3'; } else { $base_url = 'https://api.paystand.com/v3'; } $url = $base_url . "/events/" . $json->id . "/verify"; $auth_header = array("x-publishable-key: " . $this->scopeConfig->getValue(self::PUBLISHABLE_KEY, $storeScope)); $curl = $this->buildCurl("POST", $url, json_encode($json), $auth_header); $response = $this->runCurl($curl); $this->_logger->addDebug("http_response_code is " . $this->http_response_code); if (FALSE !== $response && $this->http_response_code == 200) { if ($json->resource->object = "payment") { switch ($json->resource->status) { case 'posted': $state = 'pending'; $status = 'pending'; break; case 'paid': $state = 'processing'; $status = 'processing'; break; case 'failed': $state = 'closed'; $status = 'closed'; break; case 'canceled': $state = 'canceled'; $status = 'canceled'; break; } } $this->_order->setState($state); $this->_order->setStatus($status); $this->_order->save(); $this->_logger->addDebug('new order state = ' . $state); $this->_logger->addDebug('new order status = ' . $status); } else { $this->_logger->addDebug('event verify failed'); } } } }
protected function _processDelayed($request) { try { if ($this->_paymentInst->getConfigPaymentAction() != \Magento\Payment\Model\Method\AbstractMethod::ACTION_AUTHORIZE) { throw new \Magento\Framework\Exception\LocalizedException(__('Wrong payment action.')); } // save transaction information $this->_order->getPayment()->setTransactionId($request['billnumber'])->setLastTransId($request['billnumber'])->authorize(true, $request['orderamount']); if (isset($request['approvalcode'])) { $this->_order->getPayment()->setAdditionalInformation('approvalcode', $request['approvalcode']); } $this->_processInvoice(); $this->_order->save(); } catch (\Magento\Framework\Exception\LocalizedException $e) { throw $e; } }
protected function _createInvoice($params) { try { if ($this->_order->canInvoice()) { $payment = $this->_order->getPayment(); $payment->setTransactionId($params['invoice_id']); $payment->setCurrencyCode($params['list_currency']); $payment->setParentTransactionId($params['sale_id']); $payment->setShouldCloseParentTransaction(true); $payment->setIsTransactionClosed(0); $payment->registerCaptureNotification($params['invoice_list_amount'], true); $this->_order->save(); // notify customer $invoice = $payment->getCreatedInvoice(); if ($invoice && !$this->_order->getEmailSent()) { $this->orderSender->send($this->_order); $this->_order->addStatusHistoryComment(__('You notified customer about invoice #%1.', $invoice->getIncrementId()))->setIsCustomerNotified(true)->save(); } } } catch (Exception $e) { throw new Exception(sprintf('Error Creating Invoice: "%s"', $e->getMessage())); } }
/** * Operate with order using information from silent post * * @param \Magento\Sales\Model\Order $order * @return void * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function _processOrder(\Magento\Sales\Model\Order $order) { $response = $this->getResponse(); $payment = $order->getPayment(); $payment->setTransactionId($response->getPnref())->setIsTransactionClosed(0); $canSendNewOrderEmail = true; if ($response->getResult() == self::RESPONSE_CODE_FRAUDSERVICE_FILTER || $response->getResult() == self::RESPONSE_CODE_DECLINED_BY_FILTER) { $canSendNewOrderEmail = false; $payment->setIsTransactionPending(true)->setIsFraudDetected(true); $fraudMessage = $response->getData('respmsg'); if ($response->getData('fps_prexmldata')) { $xml = new \SimpleXMLElement($response->getData('fps_prexmldata')); $fraudMessage = (string) $xml->rule->triggeredMessage; } $payment->setAdditionalInformation(Info::PAYPAL_FRAUD_FILTERS, $fraudMessage); } if ($response->getData('avsdata') && strstr(substr($response->getData('avsdata'), 0, 2), 'N')) { $payment->setAdditionalInformation(Info::PAYPAL_AVS_CODE, substr($response->getData('avsdata'), 0, 2)); } if ($response->getData('cvv2match') && $response->getData('cvv2match') != 'Y') { $payment->setAdditionalInformation(Info::PAYPAL_CVV_2_MATCH, $response->getData('cvv2match')); } switch ($response->getType()) { case self::TRXTYPE_AUTH_ONLY: $payment->registerAuthorizationNotification($payment->getBaseAmountAuthorized()); break; case self::TRXTYPE_SALE: $payment->registerCaptureNotification($payment->getBaseAmountAuthorized()); break; default: break; } $order->save(); try { if ($canSendNewOrderEmail) { $this->orderSender->send($order); } $quote = $this->quoteRepository->get($order->getQuoteId())->setIsActive(false); $this->quoteRepository->save($quote); } catch (\Exception $e) { throw new \Magento\Framework\Exception\LocalizedException(__('We cannot send the new order email.')); } }
/** * Operate with order using information from silent post * * @param \Magento\Sales\Model\Order $order * @return void * @throws \Magento\Framework\Model\Exception */ protected function _processOrder(\Magento\Sales\Model\Order $order) { $response = $this->getResponse(); $payment = $order->getPayment(); $payment->setTransactionId($response->getPnref())->setIsTransactionClosed(0); $canSendNewOrderEmail = true; if ($response->getResult() == self::RESPONSE_CODE_FRAUDSERVICE_FILTER || $response->getResult() == self::RESPONSE_CODE_DECLINED_BY_FILTER) { $canSendNewOrderEmail = false; $fraudMessage = $this->_getFraudMessage() ? $response->getFraudMessage() : $response->getRespmsg(); $payment->setIsTransactionPending(true)->setIsFraudDetected(true)->setAdditionalInformation('paypal_fraud_filters', $fraudMessage); } if ($response->getAvsdata() && strstr(substr($response->getAvsdata(), 0, 2), 'N')) { $payment->setAdditionalInformation('paypal_avs_code', substr($response->getAvsdata(), 0, 2)); } if ($response->getCvv2match() && $response->getCvv2match() != 'Y') { $payment->setAdditionalInformation('paypal_cvv2_match', $response->getCvv2match()); } switch ($response->getType()) { case self::TRXTYPE_AUTH_ONLY: $payment->registerAuthorizationNotification($payment->getBaseAmountAuthorized()); break; case self::TRXTYPE_SALE: $payment->registerCaptureNotification($payment->getBaseAmountAuthorized()); break; default: break; } $order->save(); try { if ($canSendNewOrderEmail) { $this->orderSender->send($order); } $this->_quoteFactory->create()->load($order->getQuoteId())->setIsActive(false)->save(); } catch (\Exception $e) { throw new \Magento\Framework\Model\Exception(__('We cannot send the new order email.')); } }
protected function _processOrder(\Magento\Sales\Model\Order $order, $response) { //$response = $this->getResponse(); $payment = $order->getPayment(); //$payment->setTransactionId($response->getPnref())->setIsTransactionClosed(0); //TODO: add validation for request data try { $errors = array(); //$this->readConfig(); //$order = Mage::getModel("sales/order")->load($this->getOrderId($answer)); //$order = Mage::getModel("sales/order")->loadByIncrementId($this->getOrderId($answer)); $hashArray = array($response["OutSum"], $response["InvId"], $this->getConfigData('pass_word_2')); $hashCurrent = strtoupper(md5(implode(":", $hashArray))); $correctHash = strcmp($hashCurrent, strtoupper($response['SignatureValue'])) == 0; if (!$correctHash) { $errors[] = "Incorrect HASH (need:" . $hashCurrent . ", got:" . strtoupper($response['SignatureValue']) . ") - fraud data or wrong secret Key"; $errors[] = "Maybe success payment"; } /** * @var $order Mage_Sales_Model_Order */ // if ($this->_transferCurrency != $order->getOrderCurrencyCode()) { // $outSum = round( // $order->getBaseCurrency()->convert($order->getBaseGrandTotal(), $this->_transferCurrency), // 2 // ); // } else { $outSum = round($order->getGrandTotal(), 2); // } if ($outSum != $response["OutSum"]) { $errors[] = "Incorrect Amount: " . $response["OutSum"] . " (need: " . $outSum . ")"; } // if (count($errors) > 0) { // return $errors; // } //return (bool)$correctHash; //$payment->registerCaptureNotification($payment->getBaseAmountAuthorized()); if (!$correctHash) { $payment->setTransactionId($response["InvId"])->setIsTransactionClosed(0); $order->setStatus(Order::STATE_PAYMENT_REVIEW); $order->save(); return "Ok" . $response["InvId"]; } // } catch (Exception $e) { return array("Internal error:" . $e->getMessage()); } }
/** * Keep the failed order * * @param \Magento\Sales\Model\Order $order * @param \WirecardCEE_Stdlib_Return_ReturnAbstract $return * * @throws \Magento\Framework\Exception\LocalizedException */ public function failedOrder($order, $return) { /** @var \Magento\Sales\Model\Order\Payment $payment */ $payment = $order->getPayment(); $additionalInformation = array(); foreach ($return->getReturned() as $fieldName => $fieldValue) { $additionalInformation[htmlentities($fieldName)] = htmlentities($fieldValue); } $payment->setAdditionalInformation($additionalInformation); if ($order->canUnhold()) { $order->unhold(); } $order->cancel(); $order->save(); }
/** * Capture order's payment using AIM. * * @param \Magento\Sales\Model\Order $order * @return void */ protected function _captureOrder(\Magento\Sales\Model\Order $order) { $payment = $order->getPayment(); if ($payment->getAdditionalInformation('payment_type') == self::ACTION_AUTHORIZE_CAPTURE) { try { $payment->setTransactionId(null)->setParentTransactionId($this->getResponse()->getXTransId())->capture(null); // set status from config for AUTH_AND_CAPTURE orders. if ($order->getState() == \Magento\Sales\Model\Order::STATE_PROCESSING) { $orderStatus = $this->getConfigData('order_status'); if (!$orderStatus || $order->getIsVirtual()) { $orderStatus = $order->getConfig()->getStateDefaultStatus(\Magento\Sales\Model\Order::STATE_PROCESSING); } if ($orderStatus) { $order->setStatus($orderStatus); } } $order->save(); } catch (\Exception $e) { //if we couldn't capture order, just leave it as NEW order. $this->_logger->logException($e); } } }
/** * Process the notification * @return void */ public function processNotification() { $this->_order = null; // execute notifications from 2 minute or earlier because order could not yet been created by magento $dateStart = new \DateTime(); $dateStart->modify('-5 day'); $dateEnd = new \DateTime(); $dateEnd->modify('-1 minute'); $dateRange = ['from' => $dateStart, 'to' => $dateEnd, 'datetime' => true]; // create collection $notifications = $this->_notificationFactory->create(); $notifications->addFieldToFilter('done', 0); $notifications->addFieldToFilter('created_at', $dateRange); // loop over the notifications $count = 0; foreach ($notifications as $notification) { $this->_adyenLogger->addAdyenNotificationCronjob(sprintf("Processing notification %s", $notification->getEntityId())); // log the executed notification $this->_adyenLogger->addAdyenNotificationCronjob(print_r($notification->debug(), 1)); // get order $incrementId = $notification->getMerchantReference(); $this->_order = $this->_orderFactory->create()->loadByIncrementId($incrementId); if (!$this->_order->getId()) { // order does not exists remove from queue $notification->delete(); continue; } // declare all variables that are needed $this->_declareVariables($notification); // add notification to comment history status is current status $this->_addStatusHistoryComment(); $previousAdyenEventCode = $this->_order->getData('adyen_notification_event_code'); // update order details $this->_updateAdyenAttributes($notification); // check if success is true of false if (strcmp($this->_success, 'false') == 0 || strcmp($this->_success, '0') == 0) { /* * Only cancel the order when it is in state pending, payment review or * if the ORDER_CLOSED is failed (means split payment has not be successful) */ if ($this->_order->getState() === \Magento\Sales\Model\Order::STATE_PENDING_PAYMENT || $this->_order->getState() === \Magento\Sales\Model\Order::STATE_PAYMENT_REVIEW || $this->_eventCode == Notification::ORDER_CLOSED) { $this->_adyenLogger->addAdyenNotificationCronjob('Going to cancel the order'); // if payment is API check, check if API result pspreference is the same as reference if ($this->_eventCode == NOTIFICATION::AUTHORISATION && $this->_getPaymentMethodType() == 'api') { // don't cancel the order becasue order was successfull through api $this->_adyenLogger->addAdyenNotificationCronjob('order is not cancelled because api result was succesfull'); } else { /* * don't cancel the order if previous state is authorisation with success=true * Split payments can fail if the second payment has failed the first payment is * refund/cancelled as well so if it is a split payment that failed cancel the order as well */ if ($previousAdyenEventCode != "AUTHORISATION : TRUE" || $this->_eventCode == Notification::ORDER_CLOSED) { $this->_holdCancelOrder(false); } else { $this->_order->setData('adyen_notification_event_code', $previousAdyenEventCode); $this->_adyenLogger->addAdyenNotificationCronjob('order is not cancelled because previous notification was an authorisation that succeeded'); } } } else { $this->_adyenLogger->addAdyenNotificationCronjob('Order is already processed so ignore this notification state is:' . $this->_order->getState()); } } else { // Notification is successful $this->_processNotification(); } $this->_order->save(); // set done to true $dateEnd = new \DateTime(); $notification->setDone(true); $notification->setUpdatedAt($dateEnd); $notification->save(); $this->_adyenLogger->addAdyenNotificationCronjob(sprintf("Notification %s is processed", $notification->getEntityId())); ++$count; } if ($count > 0) { $this->_adyenLogger->addAdyenNotificationCronjob(sprintf("Cronjob updated %s notification(s)", $count)); } }
public function postProcessing(\Magento\Sales\Model\Order $order, \Magento\Framework\DataObject $payment, $response) { // Update payment details $payment->setTransactionId($response['invoice_id']); $payment->setIsTransactionClosed(0); $payment->setTransactionAdditionalInfo('tco_order_number', $response['order_number']); $payment->setAdditionalInformation('tco_order_number', $response['order_number']); $payment->setAdditionalInformation('tco_order_status', 'approved'); $payment->place(); // Update order status $order->setStatus($this->getOrderStatus()); $order->setExtOrderId($response['order_number']); $order->save(); // Send email confirmation $this->orderSender->send($order); }
public function processNotification() { $this->_order = null; $this->_logger->info("START OF THE CRONJOB"); //fixme somehow the created_at is saved in my timzone $dateStart = new \DateTime(); // loop over notifications that are not processed and from 1 minute ago $dateStart = new \DateTime(); $dateStart->modify('-1 day'); // excecute notifications from 2 minute or earlier because order could not yet been created by mangento $dateEnd = new \DateTime(); $dateEnd->modify('-2 minute'); $dateRange = ['from' => $dateStart, 'to' => $dateEnd, 'datetime' => true]; $notifications = $this->_notificationFactory->create(); $notifications->addFieldToFilter('done', 0); $notifications->addFieldToFilter('created_at', $dateRange); foreach ($notifications as $notification) { // get order $incrementId = $notification->getMerchantReference(); $this->_order = $this->_orderFactory->create()->loadByIncrementId($incrementId); if (!$this->_order->getId()) { throw new Exception(sprintf('Wrong order ID: "%1".', $incrementId)); } // declare all variables that are needed $this->_declareVariables($notification); // add notification to comment history status is current status $this->_addStatusHistoryComment(); // $previousAdyenEventCode = $this->order->getAdyenNotificationEventCode(); $previousAdyenEventCode = $this->_order->getData('adyen_notification_event_code'); // set pspReference on payment object $this->_order->getPayment()->setAdditionalInformation('pspReference', $this->_pspReference); // check if success is true of false if (strcmp($this->_success, 'false') == 0 || strcmp($this->_success, '0') == 0) { // Only cancel the order when it is in state pending, payment review or if the ORDER_CLOSED is failed (means split payment has not be successful) if ($this->_order->getState() === \Magento\Sales\Model\Order::STATE_PENDING_PAYMENT || $this->_order->getState() === \Magento\Sales\Model\Order::STATE_PAYMENT_REVIEW || $this->_eventCode == \Magento\Sales\Model\Order::ADYEN_EVENT_ORDER_CLOSED) { $this->_debugData['_updateOrder info'] = 'Going to cancel the order'; // if payment is API check, check if API result pspreference is the same as reference if ($this->_eventCode == Adyen_Payment_Model_Event::ADYEN_EVENT_AUTHORISATION && $this->_getPaymentMethodType() == 'api') { if ($this->_pspReference == $this->_order->getPayment()->getAdditionalInformation('pspReference')) { // don't cancel the order if previous state is authorisation with success=true if ($previousAdyenEventCode != "AUTHORISATION : TRUE") { $this->_holdCancelOrder(false); } else { //$this->_order->setAdyenEventCode($previousAdyenEventCode); // do not update the adyenEventCode $this->_order->setData('adyen_notification_event_code', $previousAdyenEventCode); $this->_debugData['_updateOrder warning'] = 'order is not cancelled because previous notification was a authorisation that succeeded'; } } else { $this->_debugData['_updateOrder warning'] = 'order is not cancelled because pspReference does not match with the order'; } } else { // don't cancel the order if previous state is authorisation with success=true if ($previousAdyenEventCode != "AUTHORISATION : TRUE") { $this->_holdCancelOrder(false); } else { // $this->_order->setAdyenEventCode($previousAdyenEventCode); // do not update the adyenEventCode $this->_order->setData('adyen_notification_event_code', $previousAdyenEventCode); $this->_debugData['_updateOrder warning'] = 'order is not cancelled because previous notification was a authorisation that succeeded'; } } } else { $this->_debugData['_updateOrder info'] = 'Order is already processed so ignore this notification state is:' . $this->_order->getState(); } } else { // Notification is successful $this->_processNotification(); } $this->_order->save(); foreach ($this->_debugData as $debug) { $this->_logger->info($debug); } // set done to true $dateEnd = new \DateTime(); $notification->setDone(true); $notification->setUpdatedAt($dateEnd); $notification->save(); } $this->_logger->info("END OF THE CRONJOB"); }