servicePaypalIpn = new ServicePaypalIpn(); $this->servicePaypalOrder = new ServicePaypalOrder(); } public function run() { try { if ($this->requestIsValid()) { if ($this->handleIpn(Tools::getAllValues())) { header("HTTP/1.1 200 OK"); } else { header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500); } } } catch (\Exception $e) { $message = 'Error code: ' . $e->getCode() . '.'; $message .= 'Short message: ' . $e->getMessage() . '.'; ProcessLoggerHandler::openLogger(); ProcessLoggerHandler::logError( $message, null, null, null, null, \Tools::getValue('txn_id') ? \Tools::getValue('txn_id') : null, (int)\Configuration::get('PAYPAL_SANDBOX'), null ); ProcessLoggerHandler::closeLogger(); header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500); } } /** * @param $data array Ipn message data * @return bool */ protected function handleIpn($data) { if ($this->alreadyHandled($data)) { return true; } $logResponse = array( 'payment_status' => isset($data['payment_status']) ? $data['payment_status'] : null, 'ipn_track_id' => isset($data['ipn_track_id']) ? $data['ipn_track_id'] : null ); if ($data['payment_status'] == 'Refunded' && isset($data['parent_txn_id'])) { $transactionRef = $data['parent_txn_id']; } else { $transactionRef = $data['txn_id']; } $paypalOrder = $this->servicePaypalOrder->getPaypalOrderByTransaction($transactionRef); if (Validate::isLoadedObject($paypalOrder) == false) { return false; } $orders = $this->servicePaypalOrder->getPsOrders($paypalOrder); ProcessLoggerHandler::openLogger(); foreach ($orders as $order) { ProcessLoggerHandler::logInfo( 'IPN response : ' . $this->jsonEncode($logResponse), $data['txn_id'], $order->id, $order->id_cart, null, 'PayPal', (int)Configuration::get('PAYPAL_SANDBOX') ); } ProcessLoggerHandler::closeLogger(); $paypalIpn = new PaypalIpn(); $paypalIpn->id_transaction = $data['txn_id']; $paypalIpn->status = $data['payment_status']; $paypalIpn->response = $this->jsonEncode($logResponse); $paypalIpn->save(); $psOrderStatus = $this->getPsOrderStatus($data['payment_status']); if ($psOrderStatus > 0) { $this->servicePaypalOrder->setOrderStatus($paypalOrder, $psOrderStatus); } return true; } protected function getPsOrderStatus($transactionStatus) { $orderStatus = 0; if ((int)Configuration::get('PAYPAL_CUSTOMIZE_ORDER_STATUS')) { switch ($transactionStatus) { case 'Completed': $orderStatus = (int)Configuration::get('PAYPAL_OS_ACCEPTED_TWO'); break; case 'Refunded': $orderStatus = (int)Configuration::get('PAYPAL_OS_REFUNDED_PAYPAL'); break; case 'Failed': $orderStatus = (int)Configuration::get('PAYPAL_OS_VALIDATION_ERROR'); break; case 'Reversed': $orderStatus = (int)Configuration::get('PAYPAL_OS_VALIDATION_ERROR'); break; case 'Denied': $orderStatus = (int)Configuration::get('PAYPAL_OS_VALIDATION_ERROR'); break; } } else { switch ($transactionStatus) { case 'Completed': $orderStatus = (int)Configuration::get('PS_OS_PAYMENT'); break; case 'Refunded': $orderStatus = (int)Configuration::get('PS_OS_REFUND'); break; case 'Failed': $orderStatus = (int)Configuration::get('PS_OS_CANCELED'); break; case 'Reversed': $orderStatus = (int)Configuration::get('PS_OS_CANCELED'); break; case 'Denied': $orderStatus = (int)Configuration::get('PS_OS_CANCELED'); break; } } return $orderStatus; } /** * @return bool */ protected function requestIsValid() { $curl = curl_init($this->module->getIpnPaypalListener() . '?cmd=_notify-validate&' . http_build_query($_POST)); curl_setopt($curl, CURLOPT_HEADER, 0); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_TIMEOUT, 90); $response = curl_exec($curl); return trim($response) == 'VERIFIED'; } protected function alreadyHandled($data) { return $this->servicePaypalIpn->exists($data['txn_id'], $data['payment_status']); } /** * @param $orders array * @param $idState int * @return bool */ protected function setOrderStatus($orders, $idState) { /** @var $order \Order*/ foreach ($orders as $order) { $order->setCurrentState((int)$idState); } return true; } /** * @param $value mixed * @return string */ public function jsonEncode($value) { $result = json_encode($value); if (json_last_error() == JSON_ERROR_UTF8) { $result = json_encode($this->utf8ize($value)); } return $result; } public function utf8ize($mixed) { if (is_array($mixed)) { foreach ($mixed as $key => $value) { $mixed[$key] = $this->utf8ize($value); } } else if (is_string($mixed)) { return utf8_encode($mixed); } return $mixed; } }