/** * This method processes transaction data that comes from PayPal instant notifier. * * @param string $context This string gives information about that where it has been executed the trigger. * @param Joomla\Registry\Registry $params The parameters of the component * * @throws \InvalidArgumentException * @throws \OutOfBoundsException * @throws \RuntimeException * @throws \UnexpectedValueException * * @return null|stdClass */ public function onPaymentNotify($context, $params) { if (strcmp('com_crowdfunding.notify.' . $this->serviceAlias, $context) !== 0) { return null; } if ($this->app->isAdmin()) { return null; } $doc = JFactory::getDocument(); /** @var $doc JDocumentHtml */ // Check document type $docType = $doc->getType(); if (strcmp('raw', $docType) !== 0) { return null; } // Validate request method $requestMethod = $this->app->input->getMethod(); if (strcmp('POST', $requestMethod) !== 0) { $this->log->add(JText::_($this->textPrefix . '_ERROR_INVALID_REQUEST_METHOD'), $this->debugType, JText::sprintf($this->textPrefix . '_ERROR_INVALID_TRANSACTION_REQUEST_METHOD', $requestMethod)); return null; } // DEBUG DATA JDEBUG ? $this->log->add(JText::_($this->textPrefix . '_DEBUG_RESPONSE'), $this->debugType, $_POST) : null; // Decode custom data $custom = ArrayHelper::getValue($_POST, 'custom'); $custom = json_decode(base64_decode($custom), true); // DEBUG DATA JDEBUG ? $this->log->add(JText::_($this->textPrefix . '_DEBUG_CUSTOM'), $this->debugType, $custom) : null; // Verify gateway. Is it PayPal? $gateway = ArrayHelper::getValue($custom, 'gateway'); if (!$this->isValidPaymentGateway($gateway)) { $this->log->add(JText::_($this->textPrefix . '_ERROR_INVALID_PAYMENT_GATEWAY'), $this->debugType, array('custom' => $custom, '_POST' => $_POST)); return null; } // Get PayPal URL if ($this->params->get('paypal_sandbox', 1)) { $url = trim($this->params->get('paypal_sandbox_url', 'https://www.sandbox.paypal.com/cgi-bin/webscr')); } else { $url = trim($this->params->get('paypal_url', 'https://www.paypal.com/cgi-bin/webscr')); } $paypalIpn = new Prism\Payment\PayPal\Ipn($url, $_POST); $loadCertificate = (bool) $this->params->get('paypal_load_certificate', 0); $paypalIpn->verify($loadCertificate); // DEBUG DATA JDEBUG ? $this->log->add(JText::_($this->textPrefix . '_DEBUG_VERIFY_OBJECT'), $this->debugType, $paypalIpn) : null; // Prepare the array that have to be returned by this method. $paymentResult = new stdClass(); $paymentResult->project = null; $paymentResult->reward = null; $paymentResult->transaction = null; $paymentResult->paymentSession = null; $paymentResult->serviceProvider = $this->serviceProvider; $paymentResult->serviceAlias = $this->serviceAlias; if ($paypalIpn->isVerified()) { $containerHelper = new Crowdfunding\Container\Helper(); $currency = $containerHelper->fetchCurrency($this->container, $params); // Get payment session data $paymentSessionId = ArrayHelper::getValue($custom, 'payment_session_id', 0, 'int'); $paymentSessionRemote = $this->getPaymentSession(array('id' => $paymentSessionId)); // Check for valid payment session. if (!$paymentSessionRemote->getId()) { $this->log->add(JText::_($this->textPrefix . '_ERROR_PAYMENT_SESSION'), $this->errorType, $paymentSessionRemote->getProperties()); return null; } // DEBUG DATA JDEBUG ? $this->log->add(JText::_($this->textPrefix . '_DEBUG_PAYMENT_SESSION'), $this->debugType, $paymentSessionRemote->getProperties()) : null; // Validate transaction data $validData = $this->validateData($_POST, $currency->getCode(), $paymentSessionRemote); if ($validData === null) { return null; } // DEBUG DATA JDEBUG ? $this->log->add(JText::_($this->textPrefix . '_DEBUG_VALID_DATA'), $this->debugType, $validData) : null; // Set the receiver ID. $project = $containerHelper->fetchProject($this->container, $validData['project_id']); $validData['receiver_id'] = $project->getUserId(); // Get reward object. $reward = null; if ($validData['reward_id']) { $reward = $containerHelper->fetchReward($this->container, $validData['reward_id'], $project->getId()); } // Save transaction data. // If it is not completed, return empty results. // If it is complete, continue with process transaction data $transaction = $this->storeTransaction($validData); if ($transaction === null) { return null; } // Generate object of data, based on the transaction properties. $paymentResult->transaction = $transaction; // Generate object of data based on the project properties. $paymentResult->project = $project; // Generate object of data based on the reward properties. if ($reward !== null and $reward instanceof Crowdfunding\Reward) { $paymentResult->reward = $reward; } // Generate data object, based on the payment session properties. $paymentResult->paymentSession = $paymentSessionRemote; // Removing intention. $this->removeIntention($paymentSessionRemote, $transaction); } else { // Log error $this->log->add(JText::_($this->textPrefix . '_ERROR_INVALID_TRANSACTION_DATA'), $this->debugType, array('ERROR MESSAGE' => $paypalIpn->getError(), 'paypalVerify' => $paypalIpn, '_POST' => $_POST)); } return $paymentResult; }