şimdi bir teklifte bulunacağım lütfen yyanlış nalamayın benim uzun zamandır üzerinde çalıştığım bşr çekiliş projesi vardı proje bitti son dakika paytr hatası çıktı ve 1 haftadır çözemiyorum r10 da 4 tane konu açtım hine çöülmedim hatayı çözene scripti sattığım zaman 200tl gibi bir miktar vereceğim hadi en kötü scripti satamadım hatayı çözen arkafalşa çekiliş scriptini hediye edeceğim.

aldığım hata: PAYTR notification failed: bad hash

! lütfen bana wp adan kişisel numaranızdan ulaşın !

kodlar bu:

1.ADIM
<?php
require_once 'includes/header.php';
$getId = $_GET['id'];
?>
<!-- partial -->
<div class="main-panel">
    <div class="content-wrapper">
        <div class="page-header">
            <h3 class="page-title">
                <span class="page-title-icon bg-gradient-primary text-white me-2">
                    <i class="mdi mdi-star"></i>
                </span> Ürün Bilgisi
            </h3>
        </div>
        <?php
if (isset($_POST['joinSweepstake'])) {
    // Ödeme İçin gerekli bilgiler
    $userInfoSQL = $db->query("SELECT * FROM `users` WHERE `id`='$userId'");
    $userInfoSQL = $userInfoSQL->fetch(PDO::FETCH_OBJ);
    $sweepstakeInfoSQL = $db->query("SELECT `name`,`price` FROM `sweepstakes` WHERE `id`='$getId'");
    $sweepstakeInfoSQL = $sweepstakeInfoSQL->fetch(PDO::FETCH_OBJ);
    // PayTR Mağaza Bilgileri
    $paytr = $db->query("SELECT * FROM paytr WHERE id=1");
    $paytr = $paytr->fetch(PDO::FETCH_OBJ);

    // kullanıcı eposta ve tel numarası
    $userFullName = $userInfoSQL->fullname;
    $userEmail = $userInfoSQL->email;
    $userGSM = $userInfoSQL->gsm;
    $orderCode = uniqid();
    $orderCodeUPDATE = $db->query("UPDATE `users` SET `orderCode` = '$orderCode' WHERE `users`.`id` = $userId;");
    // Alınıcak Tutar
    $sweepstakeName = $sweepstakeInfoSQL->name;
    $sweepstakePrice = $sweepstakeInfoSQL->price;
    // Mağaza Bilgisi
    $getMerchant_id = $paytr->merchant_id;
    $getMerchant_key = $paytr->merchant_key;
    $getMerchant_salt = $paytr->merchant_salt;

    // PAYTR

    ## 1. ADIM için örnek kodlar ##
    ####################### DÜZENLEMESİ ZORUNLU ALANLAR #######################
    #
    ## API Entegrasyon Bilgileri - Mağaza paneline giriş yaparak BİLGİ sayfasından alabilirsiniz.
    $merchant_id     = $getMerchant_id;
    $merchant_key     = $getMerchant_key;
    $merchant_salt    = $getMerchant_salt;
    #
    ## Müşterinizin sitenizde kayıtlı veya form vasıtasıyla aldığınız eposta adresi
    $email = $userEmail;
    #
    ## Tahsil edilecek tutar.
    $payment_amount    = $sweepstakePrice * 100; //9.99 için 9.99 * 100 = 999 gönderilmelidir.
    #
    ## Sipariş numarası: Her işlemde benzersiz olmalıdır!! Bu bilgi bildirim sayfanıza yapılacak bildirimde geri gönderilir.
    $merchant_oid = $orderCode;
    #
    ## Müşterinizin sitenizde kayıtlı veya form aracılığıyla aldığınız ad ve soyad bilgisi
    $user_name = $userFullName;
    #
    ## Müşterinizin sitenizde kayıtlı veya form aracılığıyla aldığınız adres bilgisi
    $user_address = "Dijital Ürün";
    #
    ## Müşterinizin sitenizde kayıtlı veya form aracılığıyla aldığınız telefon bilgisi
    $user_phone = $userGSM;
    #
    ## Başarılı ödeme sonrası müşterinizin yönlendirileceği sayfa
    ## !!! Bu sayfa siparişi onaylayacağınız sayfa değildir! Yalnızca müşterinizi bilgilendireceğiniz sayfadır!
    ## !!! Siparişi onaylayacağız sayfa "Bildirim URL" sayfasıdır (Bakınız: 2.ADIM Klasörü).
    $merchant_ok_url = "http://localhost/panel/payment/suc.php";
    #
    ## Ödeme sürecinde beklenmedik bir hata oluşması durumunda müşterinizin yönlendirileceği sayfa
    ## !!! Bu sayfa siparişi iptal edeceğiniz sayfa değildir! Yalnızca müşterinizi bilgilendireceğiniz sayfadır!
    ## !!! Siparişi iptal edeceğiniz sayfa "Bildirim URL" sayfasıdır (Bakınız: 2.ADIM Klasörü).
    $merchant_fail_url = "http://localhost/panel/payment/err.php";
    #
    ## Müşterinin sepet/sipariş içeriği
    $user_basket = base64_encode(json_encode(array(
        array($sweepstakeName, $sweepstakePrice, 1)
    )));
    ############################################################################################
    ## Kullanıcının IP adresi
    if (isset($_SERVER["HTTP_CLIENT_IP"])) {
        $ip = $_SERVER["HTTP_CLIENT_IP"];
    } elseif (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
        $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
    } else {
        $ip = $_SERVER["REMOTE_ADDR"];
    }
    ## !!! Eğer bu örnek kodu sunucuda değil local makinanızda çalıştırıyorsanız
    ## buraya dış ip adresinizi (https://www.whatismyip.com/) yazmalısınız. Aksi halde geçersiz paytr_token hatası alırsınız.
    $user_ip = $ip;
    ##
    ## İşlem zaman aşımı süresi - dakika cinsinden
    $timeout_limit = "30";
    ## Hata mesajlarının ekrana basılması için entegrasyon ve test sürecinde 1 olarak bırakın. Daha sonra 0 yapabilirsiniz.
    $debug_on = 1;
    ## Mağaza canlı modda iken test işlem yapmak için 1 olarak gönderilebilir.
    $test_mode = 0;
    $no_installment    = 0; // Taksit yapılmasını istemiyorsanız, sadece tek çekim sunacaksanız 1 yapın
    ## Sayfada görüntülenecek taksit adedini sınırlamak istiyorsanız uygun şekilde değiştirin.
    ## Sıfır (0) gönderilmesi durumunda yürürlükteki en fazla izin verilen taksit geçerli olur.
    $max_installment = 0;
    $currency = "TL";
    ####### Bu kısımda herhangi bir değişiklik yapmanıza gerek yoktur. #######
    $hash_str = $merchant_id . $user_ip . $merchant_oid . $email . $payment_amount . $user_basket . $no_installment . $max_installment . $currency . $test_mode;
    $paytr_token = base64_encode(hash_hmac('sha256', $hash_str . $merchant_salt, $merchant_key, true));
    $post_vals = array(
        'merchant_id' => $merchant_id,
        'user_ip' => $user_ip,
        'merchant_oid' => $merchant_oid,
        'email' => $email,
        'payment_amount' => $payment_amount,
        'paytr_token' => $paytr_token,
        'user_basket' => $user_basket,
        'debug_on' => $debug_on,
        'no_installment' => $no_installment,
        'max_installment' => $max_installment,
        'user_name' => $user_name,
        'user_address' => $user_address,
        'user_phone' => $user_phone,
        'merchant_ok_url' => $merchant_ok_url,
        'merchant_fail_url' => $merchant_fail_url,
        'timeout_limit' => $timeout_limit,
        'currency' => $currency,
        'test_mode' => $test_mode
    );
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://www.paytr.com/odeme/api/get-token");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_vals);
    curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 20);
    // XXX: DİKKAT: lokal makinanızda "SSL certificate problem: unable to get local issuer certificate" uyarısı alırsanız eğer
    // aşağıdaki kodu açıp deneyebilirsiniz. ANCAK, güvenlik nedeniyle sunucunuzda (gerçek ortamınızda) bu kodun kapalı kalması çok önemlidir!
    // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    $result = @curl_exec($ch);
    if (curl_errno($ch))
        die("PAYTR IFRAME connection error. err:" . curl_error($ch));
    curl_close($ch);
    $result = json_decode($result, 1);
    if ($result['status'] == 'success')
        $token = $result['token'];
    else
        die("PAYTR IFRAME failed. reason:" . $result['reason']);
    #########################################################################
?>
    <!-- Ödeme formunun açılması için gereken HTML kodlar / Başlangıç -->
    <script src="https://www.paytr.com/js/iframeResizer.min.js"></script>
    <iframe src="https://www.paytr.com/odeme/guvenli/<?php echo $token; ?>" id="paytriframe" frameborder="0" scrolling="no" style="width: 100%;"></iframe>
    <script>
        iFrameResize({}, '#paytriframe');
    </script>
    <!-- Ödeme formunun açılması için gereken HTML kodlar / Bitiş -->
<?php
  
}else{
?>

        <?php
        $sweepstakesSQL = $db->prepare("SELECT * FROM `sweepstakes` WHERE id=$getId");
        $sweepstakesSQL->execute();
        $sweepstakes = $sweepstakesSQL->fetchALL(PDO::FETCH_ASSOC);
        foreach ($sweepstakes as $row) {
        ?>
            <div class="container mt-5">
                <div class="row">
                    <div class="col-md-4">
                        <!-- Profil Resmi -->
                        <div class="mb-3">
                            <img src="assets/products/<?= $row['img'] ?>" class="img-fluid rounded" alt="<?= $row['name'] ?>">
                        </div>
                    </div>
                    <div class="col-md-8 mt-1">
                        <!-- Profil Detayları -->
                        <div class="mb-3">
                            <h1><?= $row['name'] ?></h1>
                        </div>
                        <div class="mb-3">
                            <div>
                                <?= html_entity_decode($row['info']) ?>
                                <br><br><b>Çekiliş bitiş tarihi: </b><?= $row['end_date'] ?>
                            </div>
                        </div>
                    </div>
                    <form action="" method="post" class="w-100">
                        <?php
                        // Kullanıcının çekilişe katılıp katılmadığını kontrol ediyoruz
                        $controlSQL = $db->query("SELECT * FROM participants WHERE sweepstake_id = $getId AND user_id = $userId");
                        $controlCount = $controlSQL->rowCount();
                        ?>
                        <button name="joinSweepstake" type="submit" class="btn btn-primary w-100" <?php echo $controlCount === 1 ? 'disabled' : ''; ?>>
                            <?php echo $controlCount === 1 ? 'Çekilişe Katıldınız' : 'Çekilişe Katıl (' . $row['price'] . ' TL)'; ?>
                        </button>
                    </form>
                </div>
            </div>
        <?php } } ?>
    </div>
    <?php require_once 'includes/footer.php' ?>
2. ADIM
<?php
require_once '../config/database.php';
// session_start();
// Mağaza Bilgisi
$paytr = $db->query("SELECT * FROM paytr");
$paytr = $paytr->fetch(PDO::FETCH_OBJ);
$getMerchant_key = $paytr->merchant_key;
$getMerchant_salt = $paytr->merchant_salt;

## 2. ADIM için örnek kodlar ##
## ÖNEMLİ UYARILAR ##
## 1) Bu sayfaya oturum (SESSION) ile veri taşıyamazsınız. Çünkü bu sayfa müşterilerin yönlendirildiği bir sayfa değildir.
## 2) Entegrasyonun 1. ADIM'ında gönderdiğniz merchant_oid değeri bu sayfaya POST ile gelir. Bu değeri kullanarak
## veri tabanınızdan ilgili siparişi tespit edip onaylamalı veya iptal etmelisiniz.
## 3) Aynı sipariş için birden fazla bildirim ulaşabilir (Ağ bağlantı sorunları vb. nedeniyle). Bu nedenle öncelikle
## siparişin durumunu veri tabanınızdan kontrol edin, eğer onaylandıysa tekrar işlem yapmayın. Örneği aşağıda bulunmaktadır.
$post = $_POST;


$getCodeSQL = $db->query("SELECT * FROM `users` WHERE orderCode='$orderCode'");
$getCodeSQL = $getCodeSQL->fetch(PDO::FETCH_OBJ);
$errMsg = $getCodeSQL->paytr_err_msg;
####################### DÜZENLEMESİ ZORUNLU ALANLAR #######################
#
## API Entegrasyon Bilgileri - Mağaza paneline giriş yaparak BİLGİ sayfasından alabilirsiniz.
$merchant_key   = $getMerchant_key;
$merchant_salt  = $$getMerchant_salt;
###########################################################################
####### Bu kısımda herhangi bir değişiklik yapmanıza gerek yoktur. #######
#
## POST değerleri ile hash oluştur.
$hash = base64_encode(hash_hmac('sha256', $post['merchant_oid'] . $merchant_salt . $post['status'] . $post['total_amount'], $merchant_key, true));
#
## Oluşturulan hash'i, paytr'dan gelen post içindeki hash ile karşılaştır (isteğin paytr'dan geldiğine ve değişmediğine emin olmak için)
## Bu işlemi yapmazsanız maddi zarara uğramanız olasıdır.
if ($hash != $post['hash'])
    die('PAYTR notification failed: bad hash');
###########################################################################
## BURADA YAPILMASI GEREKENLER
## 1) Siparişin durumunu $post['merchant_oid'] değerini kullanarak veri tabanınızdan sorgulayın.
## 2) Eğer sipariş zaten daha önceden onaylandıysa veya iptal edildiyse  echo "OK"; exit; yaparak sonlandırın.
/* Sipariş durum sorgulama örnek
       $durum = SQL
       if($durum == "onay" || $durum == "iptal"){
            echo "OK";
            exit;
        }
     */
if ($post['status'] == 'success') { ## Ödeme Onaylandı
    // Üyeyi çekilişe ekliyorum
    $join = $db->query("INSERT INTO `participants` (`sweepstake_id`, `user_id`) VALUES ('$getId', '$userId')");
    $count = $join->rowCount();
} else { ## Ödemeye Onay Verilmedi

    $errMsg = $post['failed_reason_msg'];
    $errMsgSQL = $db->query("UPDATE `users` SET `paytr_err_msg`='$errMsg' WHERE orderCode='$orderCode'");
}
## Bildirimin alındığını PayTR sistemine bildir.
echo "OK";
exit;