[PHP] Проблема с Яндекс деньги (уведомление о входящих платежах)

Discussion in 'PHP' started by Kamik, 6 May 2013.

  1. Kamik

    Kamik Member

    Joined:
    2 Dec 2008
    Messages:
    122
    Likes Received:
    85
    Reputations:
    8
    Скрипт в ЭТОМ ПОСТЕ ПРАВИЛЬНО НЕ РАБОТАЕТ!!!
    Если вы ищете рабочий скрипт обработки нотификаций о входящих платежах с Яндекс денег - ОН НИЖЕ!

    Доброго времени суток товарищи кодеры.
    В общем, необходимо мне для сайта сделать интергацию с ЯД, используя уведомления о входящих платежах. Но однако не получается :( Вся проблема в одном из "пунктов" Яндекса.

    Code:
    Чтобы проверить целостность и подлинность уведомления, рассчитайте хэш по алгоритму, приведенному ниже. Сравните полученные данные со значением параметра sha1_hash в уведомлении.
    1. Сформировать строку из параметров уведомления в кодировке UTF-8 (где notification_secret — это секретное слово для проверки уведомлений).
    
    Формат строки:
    notification_type&operation_id&amount&currency&datetime&sender&codepro&notification_secret&label
    
    Пример строки параметров:
    p2p-incoming&1234567&300.00&643&2011-07-01T09:00:00.000+04:00&41001XXXXXXXX&false&01234567890ABCDEF01234567890&
    
    2. Вычислить значение хэш-функции SHA-1 от полученной строки.
    
    3. Отформатировать полученный результат в HEX-кодированном виде.
    
    Пример рассчитанного значения параметра sha1_hash:
    090a8e7ebb6982a7ad76f4c0f0fa5665d741aafa
    Вот мой код (заранее ссори за быдлокодинг)
    PHP:
    <?

    $test '1'//Тестирование системы
    $notification_secret "01234567890ABCDEF01234567890"//Секретный код


    $notification_type $_GET["notification_type"]; 
    $operation_id $_GET["operation_id"];
    $amount $_GET["amount"];
    $currency $_GET["currency"];
    $datetime $_GET["datetime"];
    $sender $_GET["sender"];
    $codepro $_GET["codepro"];
    $label $_GET["label"];
    $sha1_hash $_GET["sha1_hash"];
    $test_notification $_GET["test_notification"];

    $hash $notification_type '&' $operation_id '&' $amount '&' $currency '&' $datetime '&' $sender '&' $codepro '&' $notification_secret '&' $label//формируем хеш
    if ($test=='1') {
    echo 
    $hash '- Суммовой хэш<br />';
    echo 
    $notification_type ' - тип нотификации<br />';
    echo 
    $operation_id '- ид операции<br />';
    echo 
    $amount '- сумма бабла<br />';
    echo 
    $currency ' - код валюты<br />';
    echo 
    $datetime ' - дата и время<br />';
    echo 
    $sender ' - номер счета<br />';
    echo 
    $codepro ' - код протекции<br />';
    echo 
    $label ' - метка платежа<br />';
    echo 
    $sha1_hash ' - переданый проверочный хеш<br />';
    echo 
    $test_notification ' - уведомление о тестовой нотификации<br />';
    }
    $sha1 sha1($hash); //кодируем в SHA1

    $sha2 bin2hex($sha1); //Хекс???

    //Ниже проверка на валидность
    if ( $sha2 !== $sha1_hash ) {

    echo (
    '<font color=\'red\'>error - ошибка - неверный проверочный хеш <br /></font>');

    } else {
    echo 
    'OK';
    }

    if (
    $test=='1') {
    echo 
    $sha1 ' - сгенерированый проверочный хеш <b>начальный</b><br />';
    echo 
    $sha2 ' - сгенерированый проверочный хеш <b>конечный</b><br />';
    }

    Проверочная процедура вызова
    Code:
    script.php?notification_type=p2p-incoming&operation_id=1234567&amount=300.00&currency=643&datetime=2011-07-01T09:00:00.000+04:00&sender=41001XXXXXXXX&codepro=false&label=&sha1_hash=090a8e7ebb6982a7ad76f4c0f0fa5665d741aafa
    
    В общем все идет нормально до пункта №2 руководства (строки $sha1 = sha1($hash); //кодируем в SHA1 )

    А вот пункт №3 (Отформатировать полученный результат в HEX-кодированном виде.) у меня не получается ( строка $sha2 = bin2hex($sha1); //Хекс??? )
    Подскажите пожалуйста как правильно.
    Спасибо заранее
     
    #1 Kamik, 6 May 2013
    Last edited: 7 May 2013
    ceg likes this.
  2. Chaak

    Chaak Elder - Старейшина

    Joined:
    1 Jun 2008
    Messages:
    1,059
    Likes Received:
    1,067
    Reputations:
    80
    Мне кажется, здесь имеется ввиду просто sha1-хэш, ну и url-encode на параметры
     
    #2 Chaak, 6 May 2013
    Last edited: 6 May 2013
    1 person likes this.
  3. Kamik

    Kamik Member

    Joined:
    2 Dec 2008
    Messages:
    122
    Likes Received:
    85
    Reputations:
    8
    Все, я разобрался =) Оказывается я все правильно сделал. Просто на сайте яндесбабла неправильно указан в самом конце проверочный хеш. Отправив себе тестовое уведомление я убедился в правильности кода (хешсуммы сошлись.) А так как этой инфы нет в инете (по крайней мере гугль мне в поиске не помог) я закину правильный рабочий скрипт.

    Кстати, спасибо за подсказку. да, это просто хеш и все. urlencode не нужен
    Почемуто вызов $sha1 - sha1($hash); счита хеш неправильно (хз почему)
    а вот вызов функции $sha1 = hash('sha1', $hash); считает верно... почему - ХЗ
     
    #3 Kamik, 7 May 2013
    Last edited: 7 May 2013
  4. Kamik

    Kamik Member

    Joined:
    2 Dec 2008
    Messages:
    122
    Likes Received:
    85
    Reputations:
    8
    Вот рабочий скрипт обработки и проверки уведомлений в входящих платежах Яндекс Денег.
    PS - знаю что этот скрипт - полная лажа, и его можно написать за полчаса, но кто знает - может кому пригодится ;)
    PHP:

    <?

    $test = '0'; //Тестирование системы: 0 - выключено, 1 - включено

    $notification_secret = "01234567890ABCDEF01234567890"; //СЮДА ВСТАВИТЬ Секретный код выданый ВАМ ЯД


    $notification_type = $_POST["notification_type"]; 
    $operation_id = $_POST["operation_id"];
    $amount = $_POST["amount"];
    $currency = $_POST["currency"];
    $datetime = $_POST["datetime"];
    $sender = $_POST["sender"];
    $codepro = $_POST["codepro"];
    $label = $_POST["label"];
    $sha1_hash = $_POST["sha1_hash"];
    $test_notification = $_POST["test_notification"];

    $hash = $notification_type . '&' . $operation_id . '&' . $amount . '&' . $currency . '&' . $datetime . '&' . $sender . '&' . $codepro . '&' . $notification_secret . '&' . $label; //формируем хеш

    $sha1 = hash("sha1", $hash); //кодируем в SHA1

    //Ниже - проверка на валидность
    if ( $sha1 == $sha1_hash ) {
    echo 'OK';
    } else {
    echo 'error';
    }

    // Ниже - отладка - запись в файл testlog.txt переданых данных с ЯД.
    if ($test=='1') {
    $test_wr = fopen ('testlog.txt', 'a+');
    fwrite ($test_wr, "$notification_type - тип нотификации\r\n$operation_id - ид операции\r\n$amount - сумма\r\n$currency -Код валюты\r\n$datetime - дата+время\r\n$sender -отправитель\r\n$codepro - наличие кода протекции\r\n$label - метка платежа\r\n$sha1_hash - переданый проверочный хеш\r\n$sha1 - расчитаный хэш\r\n$test_notification - тестовая нотификация\r\n");
    fclose ($test_wr);
    }

    ?>

     
    #4 Kamik, 7 May 2013
    Last edited: 7 May 2013
    SPASIBO_KAMIK, Sokol-117845 and makag like this.
  5. Chaak

    Chaak Elder - Старейшина

    Joined:
    1 Jun 2008
    Messages:
    1,059
    Likes Received:
    1,067
    Reputations:
    80
    Ну, ок, если поля фильтруются, то замечательно, urlencode не нужен.
    А разницы между sha1() и hash() нет, разве что в скорости выполнения в пользу последней
     
  6. Kamik

    Kamik Member

    Joined:
    2 Dec 2008
    Messages:
    122
    Likes Received:
    85
    Reputations:
    8
    Согласен, что разницы нет. Ток не понятно, поч у меня считал неправильно... МОж у меня косяк с компом какойто? Хрен его знает, ну да ладно, главное работает счас все... Еще раз спасибо за подсказку :D
     
  7. mr. Jazz

    mr. Jazz New Member

    Joined:
    15 Jun 2009
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    подскажите как сделать чтоб приходили дополнительно другие данные по платежу - телефон, адрес, Фио ( если таковые заполняются в кастомной форме оплаты)
     
  8. rikitikis

    rikitikis Banned

    Joined:
    7 Oct 2015
    Messages:
    2
    Likes Received:
    0
    Reputations:
    0
    Скрипт двумя постами выше хорошо работает, помещая значения переменных в log.txt. Но вот как при приходе переменной сразу отправить письмо с сайта на email плательщика об успешной оплате?
    Мне проверка хеша и прочие меры безопасности не нужны. Требуется только значение $_POST["label"]. Я и сам могу после проверить поступили ли деньги на кошелёк, прежде чем отправлять заказ. А вот моментальная отправка с сайта после оплаты письма в адрес плательщика важна.
    Значение $_POST["label"] равно номеру заказа. Сам номер order_id автоматически создаётся на сайте перед оплатой и откладывается вместе с адресом почты и прочими реквизитами плательщика в базу mysql. Поэтому необходимо сделать выборку в базе с проверкой наличия в ней значения соответствующего значению $_POST["label"]. В случае наличия скрипт должен отправить покупателю письмо. Как это сделать не знаю, поэтому прошу помощи.
     
    #8 rikitikis, 7 Oct 2015
    Last edited: 7 Oct 2015
  9. ol1ver

    ol1ver Active Member

    Joined:
    22 Jul 2011
    Messages:
    237
    Likes Received:
    155
    Reputations:
    0
    Ssl сертификат должен быть
     
  10. ol1ver

    ol1ver Active Member

    Joined:
    22 Jul 2011
    Messages:
    237
    Likes Received:
    155
    Reputations:
    0
    Боюсь не обрадуетесь когда сумма платежа будет подделана, security hashы для этого и нужны.

    В настройках Лк яши есть поле для ввода url куда будет идти отстук. В БД сверяйте транзакцию.

    Ваш ответ в вашем же вопросе
     
  11. rikitikis

    rikitikis Banned

    Joined:
    7 Oct 2015
    Messages:
    2
    Likes Received:
    0
    Reputations:
    0
    А тот в свою очередь https-ссоединения на выделенном ip.
    Мне это хорошо известно и я не отрицаю необходимость пороверки хеша.
    Просто, чтобы не усложнять, интересуюсь, как обратиться к базе, чтобы сравнить значение номера заказа в ней с тем значением что приходит в $_POST["label"]. А заодно выудить из неё соответствующий номеру заказа почтовый адрес. Если значения такого в базе нет, то и отправка письма не нужна.
     
  12. ol1ver

    ol1ver Active Member

    Joined:
    22 Jul 2011
    Messages:
    237
    Likes Received:
    155
    Reputations:
    0
    http://php.net/manual/ru/function.mysql-num-rows.php
    Сравнивайте количество рядов.

    Не забывайте фильтровать переменную order_id при составлении запроса к БД.
    http://php.net/manual/ru/security.database.sql-injection.php (в сети полно статей)
     
  13. SPASIBO_KAMIK

    SPASIBO_KAMIK New Member

    Joined:
    10 Sep 2018
    Messages:
    1
    Likes Received:
    0
    Reputations:
    0
    СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО СПАСИБО