<?php 
/* Оплата через ROBOKASSA  */
class system_of_pay_handler
{
	/* Логин в системе ROBOKASSA */
	var $mrh_login = "mylogin";

	/* Пароль #1 - Используется интерфейсом инициализации оплаты */
	var $mrh_pass1 = "1234567a";

	/* Пароль #2 - регистрационная информация */
	var $mrh_pass2 = "98765432a";

	/* язык */
	var $culture = "ru";

	/* предлагаемая валюта платежа, default payment e-currency.
	Валюта НЕ связана с $robokassa_currency, это только предлагаемая валюта по умолчанию
	Доступные валюты: http://merchant.roboxchange.com/Handler/Xml/CurrList.ashx
	*/
	var $in_curr = "YandexMerchantOceanR";

	/* Код валюты в магазине HostCMS для валюты платежа в личном кабинете Робокассы */
	var $robokassa_currency = 1;

	/* Коэффициент перерасчета при оплате ROBOKASSA */
	var $coefficient = 1;
	
	/* Режим работы, 0 - Тестовый, 1 - Рабочий */
	var $mode = 1;
	
	/**
	 * Обработка статуса оплаты
	 *
	 */
	function ProcessResult()
	{
		/* Информация о заказе */
		$order_id = to_int($_REQUEST['InvId']);

		if (!$order_id)
		{
			return false;
		}

		$shop = & singleton('shop');

		$order_row = $shop->GetOrder($order_id);

		if (!$order_row)
		{
			return false;
		}

		$shop_row = $shop->GetShop($order_row['shop_shops_id']);

		// Сумма от Robokassa
		$out_summ = to_str($_REQUEST["OutSum"]);
		
		// Хэш от Robokassa
		$crc = to_str($_REQUEST["SignatureValue"]);

		/* Сумма заказа в валюте магазина HostCMS */
		$order_sum = sprintf("%.6f", $shop->GetOrderSum($order_id) * $this->coefficient);
		
		if ($out_summ == $order_sum)
		{
			// Для ResultURL используется mrh_pass2!
			$my_crc = md5("$out_summ:$order_id:{$this->mrh_pass2}");

			/* Устанавливаем параметры */
			$param['id'] = $order_row['shop_order_id'];
			$param['shop_shops_id'] = $order_row['shop_shops_id'];
		}
		else
		{
			// Суммы не совпали
			$my_crc = '';
		}

		/* Сравниваем хэши */
		if (mb_strtoupper($my_crc) == mb_strtoupper($crc))
		{
			/* Проверка прошла успешно!
			Добавляем комментарий */
			$param['system_information'] = "Товар оплачен через ROBOKASSA.\n";

			// Обновляем информацию о заказе
			$shop->InsertOrder($param);

			// Изменяем статус оплаты ПОСЛЕ ОБНОВЛЕНИЯ ИНФОРМАЦИ, генерируем ссылки для эл.товаров, списываем товары
			$shop->SetOrderPaymentStatus($order_id);
			
			// Проводки по партнерской программе
			$affiliate = & singleton('affiliate');
			$affiliate->AcceptAffiliatePlanForSiteUsers($order_row['site_users_id'], $order_id);
		}
		else
		{
			$param['system_information'] = 'ROBOKASSA хэш не совпал!';
			
			// Обновляем информацию о заказе
			$shop->InsertOrder($param);
		}

		// Отправку письма об оплате делаем только после вставки информации об оплате
		if (mb_strtoupper($my_crc) == mb_strtoupper($crc))
		{
			$structure = & singleton('Structure');
			$structure_row = $structure->GetStructureItem(to_int($shop_row['structure_id']));

			$lib = new lib();
			$LA = $lib->LoadLibPropertiesValue(to_int($structure_row['lib_id']), to_int($structure_row['structure_id']));

			$order_row = $shop->GetOrder($order_id);

			if (trim(to_str($order_row['shop_order_account_number'])) != '')
			{
				$shop_order_account_number = trim(to_str($order_row['shop_order_account_number']));
			}
			else
			{
				$shop_order_account_number = $order_id;
			}
			
			// Отправляем письмо администратору о подтверждении платежа
			$shop->SendMailAboutOrder($order_row['shop_shops_id'], $order_id, $order_row['site_users_id'],
			to_str($LA['xsl_letter_to_admin']),
			to_str($LA['xsl_letter_to_user']),
			$order_row['shop_order_users_email'],
			array(
			'admin-content-type' => 'html',
			'user-content-type' => 'html',
			'admin-subject' => sprintf($GLOBALS['MSG_shops']['shop_order_confirm_admin_subject'], $shop_order_account_number, $shop_row['shop_shops_name'], $order_row['shop_order_date_of_pay']),
			'user-subject' => sprintf($GLOBALS['MSG_shops']['shop_order_confirm_user_subject'], $shop_order_account_number, $shop_row['shop_shops_name'], $order_row['shop_order_date_of_pay']),
			'email_from_admin' => $order_row['shop_order_users_email']));
			
			// http://www.robokassa.ru/Doc/Ru/Interface.aspx#223
			// 3. Оповещение об оплате (ResultURL)
			// Факт успешности сообщения магазину об исполнении операции определяется по результату, возвращаемому обменному пункту. Результат должен содержать "OKnMerchantInvId", т.е. для счета #5 должен быть возвращен текст "OK5".
			echo "OK{$order_id}\n";
		}
		else
		{
			 echo "bad sign\n";
		}
	}

	/* Вывод сообщения об успешности/неуспешности оплаты */
	function ShowResultMessage()
	{
		/* Информация о заказе */
		$order_id = to_int($_REQUEST['InvId']);

		if (!$order_id)
		{
			return false;
		}

		$shop = & singleton('shop');

		$order_row = $shop->GetOrder($order_id);

		if (!$order_row)
		{
			return false;
		}

		$shop_row = $shop->GetShop($order_row['shop_shops_id']);

		// Хэш1 от Robokassa
		$crc = to_str($_REQUEST["SignatureValue"]);
		
		// Сумма от Robokassa
		$out_summ = to_str($_REQUEST["OutSum"]);
		
		/* Сумма заказа в валюте магазина HostCMS */
		$order_sum = $shop->GetOrderSum($order_id) * $this->coefficient;
		$order_sum = sprintf("%.6f", $order_sum);
		
		if ($out_summ == $order_sum)
		{
			// Для SuccessURL и FailURL используется mrh_pass1!
			$my_crc = md5("$out_summ:$order_id:{$this->mrh_pass1}");
		}
		else
		{
			$my_crc = '';
		}

		/* Сравниваем хэши */
		if (mb_strtoupper($my_crc) == mb_strtoupper($crc))
		{
			if ($order_row['shop_order_status_of_pay'] == 1)
			{
				$status = "оплачен";
			}
			else
			{
				$status = "не оплачен";
			}
			?><h1>Заказ <?php echo $status?></h1>
			<p>Заказ <strong>№ <?php echo $order_row['shop_order_account_number']?></strong> <?php echo $status?>.</p>
			<?php
		}
		else
		{
			?><p>Хэш не совпал!</p><?php
		}
	}

	/**
	 * Отображает стартовую страницу для оплаты через ROBOKASSA.
	 *
	 */
	function ShowPurseRequest()
	{
		$shop = & singleton('shop');
		
		/* ID платежной системы берем из сессии */
		$system_of_pay_id = to_int($_SESSION['system_of_pay_id']);
		$row_system_of_pay = $shop->GetSystemOfPay($system_of_pay_id);
		
		if ($row_system_of_pay)
		{
			$shop_id = $row_system_of_pay['shop_shops_id'];
		}
		else
		{
			return false;
		}

		/* Получаем id текущего пользователя сайта */
		if (class_exists('SiteUsers'))
		{
			/* Получаем id текущего пользователя сайта */
			$SiteUsers = & singleton('SiteUsers');
			$site_users_id = $SiteUsers->GetCurrentSiteUser();
		}
		else
		{
			$site_users_id = false;
		}

		// статус платежа, по умолчанию 0
		$order_row['status_of_pay'] = 0 ;

		// дата платежа, по умолчанию пустая строка
		$order_row['date_of_pay'] = '';

		$order_row['description'] = to_str($_SESSION['description']);

		// описание и системная информация, по умолчанию пустая строка
		if (to_str($_SESSION['shop_coupon_text']) != '')
		{
			$order_row['description'] .= "Купон на скидку: ".to_str($_SESSION['shop_coupon_text'])."\n";
		}

		if (!isset($_SESSION['last_order_id']))
		{
			$_SESSION['last_order_id'] = 0;
		}

		// Если заказ еще не был оформлен
		if ($_SESSION['last_order_id'] == 0)
		{
			/* Оформляем заказ */
			$order_id = $shop->ProcessOrder($shop_id, $site_users_id, $system_of_pay_id, $order_row);
		}
		else
		{
			$order_id = $_SESSION['last_order_id'];
		}

		if ($order_id > 0)
		{
			if (!class_exists('SiteUsers'))
			{
				/* Класс пользователей сайта не существует, дописываем информацию о заказчике
				в поле shop_order_description из текущей сессии */
				if ($order_row)
				{
					/* Описание заказчика */
					$order_row['description'] .= "Информация о заказчике:\n"
					."Имя: ".to_str($_SESSION['site_users_name'])."\n"
					."Фамилия: ".to_str($_SESSION['site_users_surname'])."\n"
					."Отчество: ".to_str($_SESSION['site_users_patronymic'])."\n"
					."E-Mail: ".to_str($_SESSION['site_users_email'])."\n"
					."Телефон: ".to_str($_SESSION['site_users_phone'])."\n"
					."Факс: ".to_str($_SESSION['site_users_fax'])."\n"
					."Адрес: ".to_str($_SESSION['full_address'])."\n";

					/* Дополнительная информация о заказе */
					$order_row['system_information'] = to_str($_SESSION['system_information']);

					/* Обязательно добавляем идентификатор! */
					$order_row['id'] = $order_id;

					$shop->InsertOrder($order_row);
				}
			}

			$order_row = $shop->GetOrder($order_id);

			if ($order_row)
			{
				$this->PrintOrder($order_id);
			}

			$shop_row = $shop->GetShop($shop_id);

			if ($_SESSION['last_order_id'] == 0)
			{
				$structure = & singleton('Structure');
				$structure_row = $structure->GetStructureItem(to_int($shop_row['structure_id']));

				$lib = new lib();
				$LA = $lib->LoadLibPropertiesValue(to_int($structure_row['lib_id']), to_int($structure_row['structure_id']));

				$date_str = date("d.m.Y H:i:s");

				if (trim(to_str($order_row['shop_order_account_number'])) != '')
				{
					$shop_order_account_number = trim(to_str($order_row['shop_order_account_number']));
				}
				else
				{
					$shop_order_account_number = $order_id;
				}

				/* Отправляем письмо заказчику */
				$shop->SendMailAboutOrder($shop_id,
				$order_id,
				$site_users_id,
				to_str($LA['xsl_letter_to_admin']),
				to_str($LA['xsl_letter_to_user']),
				$order_row['shop_order_users_email'],
				array('admin-content-type' => 'html',
				'user-content-type' => 'html',
				'admin-subject' => sprintf($GLOBALS['MSG_shops']['shop_order_admin_subject'], $shop_order_account_number, $shop_row['shop_shops_name'], $date_str),
				'user-subject' => sprintf($GLOBALS['MSG_shops']['shop_order_user_subject'], $shop_order_account_number, $shop_row['shop_shops_name'], $date_str),
				'email_from_admin' => $order_row['shop_order_users_email']));
			}

			// Сохраняем ID последнего оформленного заказа ТОЛЬКО ПОСЛЕ ОТПРАВКИ ПИСЬМА
			$_SESSION['last_order_id'] = $order_id;
		}
		else
		{
			switch ($order_id)
			{
				case -1:
					{
						?><div id="error">Ошибка вставки заказа в базу данных. Обратитесь к администратору.</div><?php
						break;
					}
				case -2:
					{
						?><div id="error">Ошибка - не найден магазин. Обратитесь к администратору.</div><?php
						break;
					}
				case -3:
					{
						?><div id="error">Ошибка - корзина пуста. Добавьте товар в корзину и оформите заказ.</div><?php
						break;
					}
			}
		}
	}

	/**
	 * Метод, запускающий выполнение обработчика
	 */
	function Execute()
	{
		/* Пользователь перешел на страницу с уведомлением о статусе заказа */
		if (isset($_REQUEST['InvId']) && isset($_REQUEST['Culture']))
		{
			$this->ShowResultMessage();
			return true;
		}
		
		/* Пришло подтверждение оплаты, обработаем его */
		if (isset($_REQUEST['InvId']))
		{
			$this->ProcessResult();
			return true;
		}

		/* Иначе оформляем заказ и отображаем стартовую страницу для оплаты через WebMoney */
		$this->ShowPurseRequest();
	}

	/**
	 * Метод для отображения формы заказа для печати.
	 *
	 * @param int $order_id идентификатор заказа
	 */
	function PrintOrder($order_id)
	{
		$shop = & singleton('shop');

		$order_row = $shop->GetOrder($order_id);
		if (!$order_row)
		{
			return false;
		}

		if ($order_row)
		{
			$shop_row = $shop->GetShop($order_row['shop_shops_id']);

			/* Сумма заказа в валюте магазина HostCMS (далее пересчитывается в валюту) */
			$order_sum = $shop->GetOrderSum($order_id) * $this->coefficient;

			/* Валюта магазина HostCMS */
			$shop_currency_id = $shop_row['shop_currency_id'];

			$currency_row = $shop->GetCurrency($shop_currency_id);
			
			/* Получаем коэффициент пересчета в валюту ROBOKASSA */
			$currency_coefficient = $shop->GetCurrencyCoefficientToShopCurrency($shop_currency_id, $this->robokassa_currency);
			$robokassa_sum = $shop->Round($order_sum * $currency_coefficient);

			// Описание заказа
			$inv_desc = "Оплата счета N {$order_row['shop_order_account_number']}";

			// build CRC value
			$crc = md5("{$this->mrh_login}:$robokassa_sum:$order_id:{$this->mrh_pass1}");

			// Режим работы
			if ($this->mode)
			{
				// Рабочий
				$action = 'https://merchant.roboxchange.com/Index.aspx';
			}
			else
			{
				// Тестовый
				$action = 'http://test.robokassa.ru/Index.aspx';
			}
			
			?>
			<h1>Оплата через систему ROBOKASSA</h1>
			
			<p>
			<a href="http://www.robokassa.ru/" target="_blank">
			<img src="http://www.robokassa.ru/Images/logo.gif" border="0" alt="Система электронных платежей">
			</a>
			</p>

			<p>Сумма к оплате составляет <strong><?php echo $order_sum?> <?php echo $currency_row['shop_currency_name']?></strong></p>
			
			<p>Для оплаты нажмите кнопку "Оплатить".</p>
			
			<p style="color: rgb(112, 112, 112);">
			Внимание! Нажимая &laquo;Оплатить&raquo; Вы подтверждаете передачу контактных данных на сервер ROBOKASSA для оплаты.
			</p>

			<form action="<?php echo $action?>" method="POST">
				<input type="hidden" name="MrchLogin" value="<?php echo $this->mrh_login?>">
				<input type="hidden" name="OutSum" value="<?php echo $robokassa_sum?>">
				<input type="hidden" name="InvId" value="<?php echo $order_id?>">
				<input type="hidden" name="Desc" value="<?php echo $inv_desc?>">
				<input type="hidden" name="SignatureValue" value="<?php echo $crc?>">
				<input type="hidden" name="IncCurrLabel" value="<?php echo $this->in_curr?>">
				<input type="hidden" name="Culture" value="<?php echo $this->culture?>">
				<input type="submit" value="Оплатить">
			</form>
			<?php 
		}
	}

	/**
	 * Изменение статуса заказа. Позволяет пользователю внедрять собственные
	 * обработчики при изменении статуса.
	 *
	 * @param array $param массив атрибутов
	 * - $param['shop_order_id'] идентификатор заказа
	 * - $param['prev_order_row'] информация о предыдущем состоянии заказа (доступно не всегда)
	 * - $param['action'] выполняемое действие над заказом, может принимать значения:
	 * edit (редактирование заказа), cancel (отмена заказа),
	 * status (изменение статуса заказа), delete (удаление заказа),
	 * edit_item (редактирование товара в заказе), delete_item (удаление товара в заказе)
	 */
	function ChangeStatus($param = array())
	{
		// Если произошло изменение статуса
		if (isset($param['action']) && in_array($param['action'], array('status', 'edit')))
		{
			$shop_order_id = to_int($param['shop_order_id']);

			$shop = & singleton('shop');

			$order_row = $shop->GetOrder($shop_order_id);

			// Получаем информацию о магазине
			$shop_id = to_int($order_row['shop_shops_id']);

			$shop_row = $shop->GetShop($shop_id);

			$structure = & singleton('Structure');
			$structure_row = $structure->GetStructureItem(to_int($shop_row['structure_id']));

			$lib = new lib();
			$LA = $lib->LoadLibPropertiesValue(to_int($structure_row['lib_id']), to_int($structure_row['structure_id']));

			if ($order_row)
			{
				$DateClass = new DateClass();
				$date_str = $DateClass->datetime_format($order_row['shop_order_date_time']);
			}
			else
			{
				$date_str = '';
			}

			// Если предыдущий статус заказа был 1, то меняем тему на подтверждение
			if (to_int($order_row['shop_order_status_of_pay']) == 1)
			{
				$admin_subject = $GLOBALS['MSG_shops']['shop_order_confirm_admin_subject'];
				$user_subject = $GLOBALS['MSG_shops']['shop_order_confirm_user_subject'];
			}
			else
			{
				$admin_subject = $GLOBALS['MSG_shops']['shop_order_admin_subject'];
				$user_subject = $GLOBALS['MSG_shops']['shop_order_user_subject'];
			}

			$not_paid = isset($param['prev_order_row']) && $param['prev_order_row']['shop_order_status_of_pay'] == 0;
			
			// Письмо отправляем только при установке статуса активности для заказа
			if (to_int($order_row['shop_order_status_of_pay']) == 1 && $not_paid)
			{
				if (trim(to_str($order_row['shop_order_account_number'])) != '')
				{
					$shop_order_account_number = trim(to_str($order_row['shop_order_account_number']));
				}
				else
				{
					$shop_order_account_number = $shop_order_id;
				}

				/* Отправляем письмо заказчику */
				$shop->SendMailAboutOrder($shop_id,
				$shop_order_id,
				$order_row['site_users_id'],
				to_str($LA['xsl_letter_to_admin']),
				to_str($LA['xsl_letter_to_user']),
				$order_row['shop_order_users_email'],
				array('admin-content-type' => 'html',
				'user-content-type' => 'html',
				'admin-subject' => sprintf($admin_subject, $shop_order_account_number, $shop_row['shop_shops_name'], $date_str),
				'user-subject' => sprintf($user_subject, $shop_order_account_number, $shop_row['shop_shops_name'], $date_str),
				'email_from_admin' => $order_row['shop_order_users_email']));
			}
		}
	}
}
?>