cfg = stConfig::getInstance('cvIngBackend'); $this->clientId = $this->cfg->get('client_id'); $this->shopId = $this->cfg->get('shop_id'); $this->shopKey = $this->cfg->get('shop_key'); $this->testModeEnabled = $this->cfg->get('test_mode_enabled'); if($this->testModeEnabled) { error_reporting(E_ALL); register_shutdown_function([ 'cvIngService', 'handleShutdown', ]); } $this->setUrl(); } protected function setUrl() { if($this->testModeEnabled) { $this->paymentUrl = 'https://sandbox.paywall.imoje.pl/pl/payment'; } else { $this->paymentUrl = 'https://paywall.imoje.pl/pl/payment'; } } public static function validateName($string) { return preg_match('/^[^0-9!<>,;?=+()@#"°{}_$%:]+\s[^0-9!<>,;?=+()@#"°{}_$%:]+$/', $string); } public static function validateAddress($string) { return preg_match('/^[^!<>?=+@{}_$%]+\s[\w\d\/\.\/\s-]+$/', $string); } public static function validateTown($string) { return preg_match('/^[^!<>;?=+@#"°{}_$%]+$/', $string); } public static function validateCode($string) { return preg_match('/^[0-9]{2}\-[0-9]{3}$/', $string); } public static function validatePhone($string) { return preg_match('/^[0-9]{9}$/', $string); } public static function validateCountry($string = null) { return is_int(intval($string)); } public static function validateEmail($string) { return preg_match('/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i', $string); } public static function handleShutdown() { $error = error_get_last(); if($error !== null) { cvIngLog::add("[SHUTDOWN] file:" . $error['file'] . " | ln:" . $error['line'] . " | msg:" . $error['message']); } } /** * Przygotowanie danych transkcji dla płatności imoje * * @param type $order * @param type $twisto * * @return string */ public function getTransactionData($order, $twisto = 0) { if(!$order) { return false; } $userBilling = $order->getOrderUserDataBilling(); $controller = sfContext::getInstance()->getController(); $data['serviceId'] = $this->shopId; $data['merchantId'] = $this->clientId; $data['amount'] = (int) $this->getOrderAmount(stPayment::getUnpayedAmountByOrder($order)); $data['currency'] = $order->getOrderCurrency()->getShortcut(); $data['orderId'] = $order->getId(); $data['customerFirstName'] = $userBilling->getName(); $data['customerLastName'] = $userBilling->getSurname(); $data['customerEmail'] = $order->getGuardUser()->getUsername(); $data['urlReturn'] = $controller->genUrl('cvIngImojeFrontend/return', true); $data['urlSuccess'] = $controller->genUrl('cvIngImojeFrontend/returnSuccess', true); $data['urlFailure'] = $controller->genUrl('cvIngImojeFrontend/returnFail', true); if($twisto) { $payment = $order->getOrderPayment(); if(!$payment) { return false; } $cartData = $this->getCartData($order); foreach($this->getPreviousOrders($order->getGuardUser()->getUsername()) as $previousOrder) { $cartData->addPrevious($previousOrder); } $data['cartData'] = $cartData->prepareCartData(); } $data['signature'] = $this->createSignature($data, $this->shopKey, $this->hashMethod) . ';' . $this->hashMethod; return $data; } protected function getOrderAmount($orderAmountBrutto) { return number_format($orderAmountBrutto, 2, '', ''); } protected function getCartData($order) { $cartData = new \Imoje\Payment\CartData(); $cartData->setAmount((int) $this->getOrderAmount(stPayment::getUnpayedAmountByOrder($order))); $cartData->setCreatedAt(strtotime($order->getCreatedAt())); foreach($order->getOrderProducts() as $product) { $quantity = $product->getQuantity(); $cartData->addItem( $product->getId(), (int) $product->getVat(), $product->getName(), \Imoje\Payment\Util::convertAmountToFractional($product->getTotalAmount(true) / $quantity), (int) $quantity ); } $userBilling = $order->getOrderUserDataBilling(); $cartData->setAddressBilling( $userBilling->getTown(), $userBilling->getFullname(), $userBilling->getPhone(), $userBilling->getStreet() . ' ' . $userBilling->getHouse() . ' ' . $userBilling->getFlat(), $userBilling->getCountry()->getIsoA2(), $userBilling->getCode() ); $userDelivery = $order->getOrderUserDataDelivery(); $cartData->setAddressDelivery( $userDelivery->getTown(), $userDelivery->getFullname(), $userDelivery->getPhone(), $userDelivery->getStreet() . ' ' . $userDelivery->getHouse() . ' ' . $userDelivery->getFlat(), $userDelivery->getCountry()->getIsoA2(), $userDelivery->getCode() ); $shipping = $order->getOrderDelivery(); $cartData->setShipping( (int) $shipping->getOptTax(), $shipping->getName(), \Imoje\Payment\Util::convertAmountToFractional($shipping->getCostBrutto()) ); return $cartData; } /** * @param string $email * * @return array * @throws PropelException */ protected function getPreviousOrders($email) { $orderPeerCriteria = new Criteria(); $orderPeerCriteria->add(OrderPeer::OPT_CLIENT_EMAIL, $email); $prevOrders = OrderPeer::doSelect($orderPeerCriteria); $orders = []; $iteration = 0; foreach($prevOrders as $order) { if($iteration === \Imoje\Payment\CartData::MAX_PREVIOUS_ORDERS) { break; } $orderUserDataBilling = $order->getOrderUserDataDelivery(); $orderUserDataDelivery = $order->getOrderUserDataDelivery(); $orderUserDataBillingFullName = $orderUserDataBilling->getFullName(); $orderUserDataDeliveryFullName = $orderUserDataDelivery->getFullName(); $orderUserDataBillingPhone = $orderUserDataBilling->getPhone(); $orderUserDataDeliveryPhone = $orderUserDataDelivery->getPhone(); if(!$orderUserDataBillingFullName || !$orderUserDataDeliveryFullName || !$orderUserDataBillingPhone || !is_numeric($orderUserDataBillingPhone) || !$orderUserDataDeliveryPhone || !is_numeric($orderUserDataDeliveryPhone)) { continue; } $total = (int) $this->getOrderAmount(stPayment::getUnpayedAmountByOrder($order)); $calcTotal = 0; foreach($order->getOrderProducts() as $product) { $calcTotal += \Imoje\Payment\Util::convertAmountToFractional($product->getTotalAmount(true)); } $calcTotal += \Imoje\Payment\Util::convertAmountToFractional($order->getOrderDelivery()->getCostBrutto()); if($total != $calcTotal) { continue; } $orders[] = $this->getCartData($order); $iteration += 1; } return $orders; } /** * @param array $orderData * @param string $serviceKey * @param string $hashMethod * * @return string */ protected function createSignature($orderData, $serviceKey, $hashMethod) { return hash($hashMethod, $this->prepareData($orderData) . $serviceKey); } /** * @param array $data * @param string $prefix * * @return string */ protected function prepareData($data, $prefix = '') { ksort($data); $hashData = []; foreach($data as $key => $value) { if($prefix) { $key = $prefix . '[' . $key . ']'; } if(is_array($value)) { $hashData[] = prepareData($value, $key); } else { $hashData[] = $key . '=' . $value; } } return implode('&', $hashData); } #VALIDATE METHODS public function verifySignature() { $dataEncoded = file_get_contents('php://input'); $this->dataDecoded = json_decode($dataEncoded, 1); $header = $this->getHeaders(); if(!isset($header['X-Imoje-Signature']) || substr($header['Content-Type'], 0, 16) != 'application/json') { cvIngLog::add('Wrong headers'); return false; } cvIngLog::add($this->dataDecoded); cvIngLog::add($header); $headerSignature = $this->parseHeaderValues($header['X-Imoje-Signature']); $signature = hash($this->hashMethod, $dataEncoded . $this->shopKey); cvIngLog::add($headerSignature['signature']); cvIngLog::add($signature); if($signature === $headerSignature['signature']) { cvIngLog::add('Correct signature'); return true; } else { cvIngLog::add('Wrong signature'); return false; } } protected function getHeaders() { foreach($_SERVER as $name => $value) { if(substr($name, 0, 5) == 'HTTP_') { $name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5))))); $headers[$name] = $value; } elseif($name == "CONTENT_TYPE") { $headers["Content-Type"] = $value; } elseif($name == "CONTENT_LENGTH") { $headers["Content-Length"] = $value; } } return $headers; } protected function parseHeaderValues($headerValues) { $result = []; $varsets = explode(';', $headerValues); foreach($varsets as $varset) { $chunk = explode('=', $varset); $result[$chunk[0]] = $chunk[1]; } return $result; } public function verifyTransactionData() { $result = true; if(!isset($this->dataDecoded['transaction']) || empty($this->dataDecoded['transaction'])) { $result = false; } if(!isset($this->dataDecoded['transaction']['orderId']) || empty($this->dataDecoded['transaction']['orderId'])) { $result = false; } if(!isset($this->dataDecoded['transaction']['status']) || empty($this->dataDecoded['transaction']['status'])) { $result = false; } if($result) { $this->transactionData = $this->dataDecoded['transaction']; cvIngLog::add('Correct transaction data'); return true; } else { cvIngLog::add('Wrong transaction data'); return false; } } }