# Система оплаты W2
protected function w2_request()
{
// чистим все поля, которые не начинаются на WMI2_
foreach ($_POST as $k => $v) {
if (strpos($k, 'WMI_') !== 0) {
unset($_POST[$k]);
}
}
extract($_POST);
if (empty($WMI_SIGNATURE)) {
$this->w2_response(false, 'Отсутствует параметр WMI_SIGNATURE');
}
if (empty($WMI_PAYMENT_NO)) {
$this->w2_response(false, 'Отсутствует параметр WMI_PAYMENT_NO');
}
if (!isset($WMI_ORDER_STATE)) {
$this->w2_response(false, 'Отсутствует параметр WMI_ORDER_STATE');
}
# Проверяем подпись
$crc = $WMI_SIGNATURE;
unset($_POST['WMI_SIGNATURE']);
$crc2 = $this->w2_signature($_POST, false);
if ($crc !== $crc2) {
$this->log('W2: неверная контрольная сумма "' . $crc . '" !== "' . $crc2 . '"');
$this->w2_response(false, $this->payError('crc_error'));
}
# Проверяем состояние счета (в ответе W2 корректно только ACCEPTED)
if (strtoupper($WMI_ORDER_STATE) !== 'ACCEPTED') {
$this->log('W2: неверное состояние(ORDER_STATE) "' . $WMI_ORDER_STATE . '" !== "ACCEPTED"');
$this->w2_response(false, 'Неверное состояние(WMI_ORDER_STATE)');
}
# Обрабатываем счет
$mResult = $this->processBill($WMI_PAYMENT_NO, $WMI_PAYMENT_AMOUNT, self::PS_W2, array(
'WMI_ORDER_ID' => (isset($WMI_ORDER_ID) ? $WMI_ORDER_ID : ''),
'WMI_PAYMENT_AMOUNT' => $WMI_PAYMENT_AMOUNT,
'WMI_PAYMENT_TYPE' => (isset($WMI_PAYMENT_TYPE) ? $WMI_PAYMENT_TYPE : ''),
'WMI_CURRENCY_ID' => $WMI_CURRENCY_ID,
'WMI_TO_USER_ID' => (isset($WMI_TO_USER_ID) ? $WMI_TO_USER_ID : ''),
'WMI_CREATE_DATE' => $WMI_CREATE_DATE,
'WMI_UPDATE_DATE' => $WMI_UPDATE_DATE,
)
);
if ($mResult === true) {
$this->w2_response('OK');
} else {
$this->w2_response(false, $mResult);
}
}
protected function w2_signature($aFields, $bEncode = true)
{
# Сортировка значений внутри полей
foreach ($aFields as $name => $val) {
if (is_array($val)) {
usort($val, "strcasecmp");
$aFields[$name] = $val;
}
}
# Формирование сообщения, путем объединения значений формы,
# отсортированных по именам ключей в порядке возрастания.
# Конвертация из текущей кодировки (UTF-8)
# необходима только если кодировка магазина отлична от Windows-1251
uksort($aFields, 'strcasecmp');
$fieldValues = '';
foreach ($aFields as $value) {
if (is_array($value)) {
foreach ($value as $v) {
if ($bEncode) {
$v = iconv('utf-8', 'windows-1251', $v);
}
$fieldValues .= $v;
}
} else {
if ($bEncode) {
$value = iconv('utf-8', 'windows-1251', $value);
}
$fieldValues .= $value;
}
}
# Формирование значения параметра WMI_SIGNATURE, путем
# вычисления отпечатка, сформированного выше сообщения,
# по алгоритму MD5 и представление его в Base64
return base64_encode(pack("H*", md5($fieldValues . config::sys('bills.w2.secret'))));
}
protected function w2_response($sResult = 'OK', $sDescription = false)
{
if (empty($sResult)) {
$sResult = 'RETRY';
}
echo 'WMI_RESULT=' . strtoupper($sResult);
if ($sDescription !== false) {
echo '&WMI_DESCRIPTION=' . urlencode($sDescription);
}
exit;
}