PayTR İframe API Entegrasyonu Hatası: "paytr_token gönderilmedi veya geçersiz"

strdewil

Centipat
Katılım
26 Şubat 2023
Mesajlar
3
Daha fazla  
Cinsiyet
Erkek
Merhaba arkadaşlar,

PayTR İframe API entegrasyonunu projeme eklemeye çalışırken, API'den aşağıdaki hatayı alıyorum:

JSON:
{"status":"failed","reason":"paytr_token gonderilmedi veya gecersiz (get-token)"}

Projemde ödeme işlemleri için PayTR'nin iframe entegrasyonunu kullanıyorum. API'ye başarılı bir şekilde istek gönderiyorum fakat geri dönen yanıt "paytr_token gönderilmedi veya geçersiz" hatasıyla sonuçlanıyor.

Kullandığım Kodlar:
  • Birinci adımda Merchant ID, Salt ve Key gibi bilgileri ayarlıyorum ve sepet verilerini hazırlıyorum.
  • HMAC-SHA256 ile token oluşturuyorum ve bu token'ı PayTR API'ye gönderiyorum.
  • Ancak API, token'ın eksik ya da geçersiz olduğunu söylüyor.
Benim kendi kodlarım:

Kod:
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using System.Collections.Specialized;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using trilancer.Models;
using trilancer.ViewModels;
using System.Text.Json; // Bu namespace'i ekle
using Microsoft.Extensions.Options;

namespace trilancer.Controllers
{
    public class PaymentController : BaseController
    {
        private readonly ApplicationDbContext _context;
        private readonly ILogger<PaymentController> _logger;
        private readonly PaytrSettings _paytrSettings;

        public PaymentController(ApplicationDbContext context, ILogger<PaymentController> logger, IOptions<PaytrSettings> paytrSettings) : base(context)
        {
            _context = context;
            _logger = logger;
            _paytrSettings = paytrSettings.Value;

        }

        [HttpPost]
        public IActionResult StartPayment()
        {
            _logger.LogInformation("StartPayment metodu başlatıldı.");

            try
            {
                // Localde test yaparken alacağın IP adresi
                string user_ip = "***.***.**.***";
                _logger.LogInformation("Kullanıcı IP adresi: {UserIP}", user_ip);

                // Merchant bilgilerini logla (güvenlik açısından dikkatli olun)
                _logger.LogInformation("Merchant ID: {MerchantId}", _paytrSettings.MerchantId);
                _logger.LogInformation("Merchant Salt: {MerchantSalt}", _paytrSettings.MerchantSalt);
                _logger.LogInformation("Merchant Key: {MerchantKey}", _paytrSettings.MerchantKey);

                // Sipariş bilgileri
                string merchant_oid = Guid.NewGuid().ToString("N"); // Alfanümerik benzersiz sipariş numarası
                _logger.LogInformation("Benzersiz Merchant OID oluşturuldu: {MerchantOID}", merchant_oid);

                string email = "testuser@gmail.com";
                _logger.LogInformation("Müşteri Email: {Email}", email);

                int payment_amount = 5125; // Ödeme tutarı 9.99 TL (TL cinsinden * 100)
                _logger.LogInformation("Ödeme Tutarı: {PaymentAmount}", payment_amount);

                string user_name = "Test Kullanici";
                _logger.LogInformation("Kullanıcı Adı: {UserName}", user_name);

                string user_address = "Test Adres";
                _logger.LogInformation("Kullanıcı Adresi: {UserAddress}", user_address);

                string user_phone = "5555555555";
                _logger.LogInformation("Kullanıcı Telefonu: {UserPhone}", user_phone);

                // Örnek sepet içeriği
                object[][] user_basket = {
                    new object[] {"Urun 1", "18.00", 1},
                    new object[] {"Urun 2", "33.25", 1},
                };
                _logger.LogInformation("Sepet içeriği: {UserBasket}", JsonSerializer.Serialize(user_basket));

                // JSON verisini serialize etmek için System.Text.Json kullanımı
                string user_basket_json = JsonSerializer.Serialize(user_basket);
                string user_basket_encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(user_basket_json));
                _logger.LogInformation("Sepet JSON'u: {UserBasketJson}", user_basket_json);
                _logger.LogInformation("Sepet Base64 encode edilmiş hali: {UserBasketEncoded}", user_basket_encoded);

                // PayTR token oluşturma için gerekli verileri birleştirelim
                string token_data = string.Concat(
                    _paytrSettings.MerchantId,
                    user_ip,
                    merchant_oid,
                    email,
                    payment_amount.ToString(),
                    user_basket_encoded,
                    "0", // Tek çekim
                    "0", // Maksimum taksit sayısı
                    "TL", // Para birimi
                    "1", // Test modu
                    _paytrSettings.MerchantSalt
                );

                _logger.LogInformation("Token oluşturma verisi: {TokenData}", token_data);

                // HMAC-SHA256 algoritması ile token oluşturma
                using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(_paytrSettings.MerchantKey)))
                {
                    byte[] hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(token_data));
                    string paytr_token = Convert.ToBase64String(hash);
                    _logger.LogInformation("PayTR Token: {PaytrToken}", paytr_token);

                    // PayTR'ye gönderilecek veriler
                    NameValueCollection data = new NameValueCollection
            {
                { "merchant_id", _paytrSettings.MerchantId },
                { "user_ip", user_ip },
                { "merchant_oid", merchant_oid },
                { "email", email },
                { "payment_amount", payment_amount.ToString() },
                { "user_basket", user_basket_encoded },
                { "paytr_token", paytr_token },
                { "debug_on", "1" },
                { "test_mode", "1" },
                { "no_installment", "0" },
                { "max_installment", "0" },
                { "user_name", user_name },
                { "user_address", user_address },
                { "user_phone", user_phone },
                { "merchant_ok_url", _paytrSettings.SuccessUrl },
                { "merchant_fail_url", _paytrSettings.FailUrl },
                { "timeout_limit", "30" },
                { "currency", "TL" },
                { "lang", "tr" }
            };

                    _logger.LogInformation("PayTR'ye gönderilecek veri: {Data}", JsonSerializer.Serialize(data.AllKeys.ToDictionary(key => key, key => data[key])));

                    // PayTR'den iframe_token alalım
                    using (WebClient client = new WebClient())
                    {
                        client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
                        byte[] result = client.UploadValues("https://www.paytr.com/odeme/api/get-token", "POST", data);
                        string response = Encoding.UTF8.GetString(result);
                        _logger.LogInformation("PayTR API yanıtı: {PaytrApiResponse}", response);

                        dynamic json = JObject.Parse(response);

                        if (json.status == "success")
                        {
                            // İframe URL'sini frontend'e gönderelim
                            string iframe_token = json.token;
                            string iframe_url = "https://www.paytr.com/odeme/guvenli/" + iframe_token;
                            _logger.LogInformation("Başarılı Token Alındı: {IframeToken}", iframe_token);
                            return Json(new { iframeUrl = iframe_url });
                        }
                        else
                        {
                            // Dynamic veriyi string'e çevir
                            string reason = json.reason.ToString();

                            // Hatanın sebebini logla
                            _logger.LogError("Token alma işlemi başarısız. Sebep: {Reason}", reason);
                            return BadRequest(new { error = "Token alma işlemi başarısız", reason = json.reason.ToString() });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("StartPayment metodunda bir hata oluştu: {Exception}", ex.ToString());
                return StatusCode(500, "Bir hata oluştu. tekrar deneyiniz.");
            }
        }

        [HttpPost]
        [Route("Payment/Callback")]
        public IActionResult Callback()
        {
            using (var reader = new StreamReader(Request.Body))
            {
                var jsonData = reader.ReadToEnd();
                dynamic data = JObject.Parse(jsonData);

                if (data.status == "success")
                {
                    // Ödeme başarılıysa sipariş durumunu güncelle
                    return Ok();
                }
                else
                {
                    return BadRequest("Ödeme işlemi başarısız.");
                }
            }
        }

        [HttpGet]
        public IActionResult Payment()
        {
            return View();
        }



        [HttpGet]
        [Route("Payment/Success")]
        public IActionResult Success()
        {
            return View(); // Başarılı ödeme sonrası gösterilecek sayfa
        }

        [HttpGet]
        [Route("Payment/Fail")]
        public IActionResult Fail()
        {
            return View(); // Başarısız ödeme sonrası gösterilecek sayfa
        }
    }
}

Paytr'nin paylaştığı örnek kod:

Kod:
// 1. ADIM için örnek kodlar

using Newtonsoft.Json.Linq; // Bu satırda hata alırsanız, site dosyalarınızın olduğu bölümde bin isimli bir klasör oluşturup içerisine Newtonsoft.Json.dll adlı DLL dosyasını kopyalayın.
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication3
{
    public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

        // ####################### DÜZENLEMESİ ZORUNLU ALANLAR #######################
        //
        // API Entegrasyon Bilgileri - Mağaza paneline giriş yaparak BİLGİ sayfasından alabilirsiniz.
        string merchant_id = "XXXXXX";
        string merchant_key = "YYYYYYYYYYYYYY";
        string merchant_salt = "ZZZZZZZZZZZZZZ";
        //
        // Müşterinizin sitenizde kayıtlı veya form vasıtasıyla aldığınız eposta adresi
        string emailstr = "ZZZZZZZZZZZZZZ";
        //
        // Tahsil edilecek tutar. 9.99 için 9.99 * 100 = 999 gönderilmelidir.
        int payment_amountstr = ;
        //
        // Sipariş numarası: Her işlemde benzersiz olmalıdır!! Bu bilgi bildirim sayfanıza yapılacak bildirimde geri gönderilir.
        string merchant_oid = "";
        //
        // Müşterinizin sitenizde kayıtlı veya form aracılığıyla aldığınız ad ve soyad bilgisi
        string user_namestr = "";
        //
        // Müşterinizin sitenizde kayıtlı veya form aracılığıyla aldığınız adres bilgisi
        string user_addressstr = "";
        //
        // Müşterinizin sitenizde kayıtlı veya form aracılığıyla aldığınız telefon bilgisi
        string user_phonestr = "";
        //
        // 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ü).
        string merchant_ok_url = "http://www.siteniz.com/basarili";
        //
        // Ö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ü).
        string merchant_fail_url = "http://www.siteniz.com/basarisiz";
        //      
        // !!! 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.
        string user_ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
        if (user_ip == "" || user_ip == null)
        {
            user_ip = Request.ServerVariables["REMOTE_ADDR"];
        }
        //
        // ÖRNEK user_basket oluşturma - Ürün adedine göre object'leri çoğaltabilirsiniz
        object[][] user_basket = {
            new object[] {"Örnek ürün 1", "18.00", 1}, // 1. ürün (Ürün Ad - Birim Fiyat - Adet)
            new object[] {"Örnek ürün 2", "33.25", 2}, // 2. ürün (Ürün Ad - Birim Fiyat - Adet)
            new object[] {"Örnek ürün 3", "45.42", 1}, // 3. ürün (Ürün Ad - Birim Fiyat - Adet)
            };
        /* ############################################################################################ */

        // İşlem zaman aşımı süresi - dakika cinsinden
        string 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.
        string debug_on = "1";
        //
        // Mağaza canlı modda iken test işlem yapmak için 1 olarak gönderilebilir.
        string test_mode = "1";
        //
        // Taksit yapılmasını istemiyorsanız, sadece tek çekim sunacaksanız 1 yapın
        string no_installment = "0";
        //
        // 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.
        string max_installment = "0";
        //
        // Para birimi olarak TL, EUR, USD gönderilebilir. USD ve EUR kullanmak için kurumsal@paytr.com
        // üzerinden bilgi almanız gerekmektedir. Boş gönderilirse TL geçerli olur.
        string currency = "TL";
        //
        // Türkçe için tr veya İngilizce için en gönderilebilir. Boş gönderilirse tr geçerli olur.
        string lang = "";

        // Gönderilecek veriler oluşturuluyor
        NameValueCollection data = new NameValueCollection();
        data["merchant_id"] = merchant_id;
        data["user_ip"] = user_ip;
        data["merchant_oid"] = merchant_oid;
        data["email"] = emailstr;
        data["payment_amount"] = payment_amountstr.ToString();
        //
        // Sepet içerği oluşturma fonksiyonu, değiştirilmeden kullanılabilir.
        JavaScriptSerializer ser = new JavaScriptSerializer();
        string user_basket_json = ser.Serialize(user_basket);
        string user_basketstr = Convert.ToBase64String(Encoding.UTF8.GetBytes(user_basket_json));
        data["user_basket"] = user_basketstr;
        //
        // Token oluşturma fonksiyonu, değiştirilmeden kullanılmalıdır.
        string Birlestir = string.Concat(merchant_id, user_ip, merchant_oid, emailstr, payment_amountstr.ToString(), user_basketstr, no_installment, max_installment, currency, test_mode, merchant_salt);
        HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(merchant_key));
        byte[] b = hmac.ComputeHash(Encoding.UTF8.GetBytes(Birlestir));
        data["paytr_token"] = Convert.ToBase64String(b);
        //
        data["debug_on"] = debug_on;
        data["test_mode"] = test_mode;
        data["no_installment"] = no_installment;
        data["max_installment"] = max_installment;
        data["user_name"] = user_namestr;
        data["user_address"] = user_addressstr;
        data["user_phone"] = user_phonestr;
        data["merchant_ok_url"] = merchant_ok_url;
        data["merchant_fail_url"] = merchant_fail_url;
        data["timeout_limit"] = timeout_limit;
        data["currency"] = currency;
        data["lang"] = lang;

        using (WebClient client = new WebClient())
        {
            client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
            byte[] result = client.UploadValues("https://www.paytr.com/odeme/api/get-token", "POST", data);
            string ResultAuthTicket = Encoding.UTF8.GetString(result);
            dynamic json = JValue.Parse(ResultAuthTicket);

            if (json.status == "success")
            {
                paytriframe.Attributes["src"] = "https://www.paytr.com/odeme/guvenli/" + json.token;
                paytriframe.Visible = true;
            }
            else
            {
                Response.Write("PAYTR IFRAME failed. reason:" + json.reason + "");
            }
        }
    }
}

}

Eğer ki local üzerinde çalışılıyorsa whatsmyip sitesindeki dış IP adresimiz girilmesi istenilmiş. Ben de kendi dış IP adresimi girerek test ediyorum. Orada da bir sıkıntı olabilme ihtimali mevcut.
Loglarım ise aşağıdaki gibi:

JSON:
trilancer.Controllers.PaymentController: Information: StartPayment metodu başlatıldı.trilancer.Controllers.PaymentController: Information: Kullanıcı IP adresi: ***.***.**.** trilancer.Controllers.PaymentController: Information: Merchant ID: ******trilancer.Controllers.PaymentController: Information: Merchant Salt: *******trilancer.Controllers.PaymentController: Information: Merchant Key: *********trilancer.Controllers.PaymentController: Information: Benzersiz Merchant OID oluşturuldu: *********ftrilancer.Controllers.PaymentController: Information: Müşteri Email: testuser@gmail.comtrilancer.Controllers.PaymentController: Information: Ödeme Tutarı: 5125trilancer.Controllers.PaymentController: Information: Kullanıcı Adı: Test Kullanicitrilancer.Controllers.PaymentController: Information: Kullanıcı Adresi: Test Adrestrilancer.Controllers.PaymentController: Information: Kullanıcı Telefonu: 5555555555trilancer.Controllers.PaymentController: Information: Sepet içeriği: [["Urun 1","18.00",1],["Urun 2","33.25",1]]trilancer.Controllers.PaymentController: Information: Sepet JSON'u: [["Urun 1","18.00",1],["Urun 2","33.25",1]]trilancer.Controllers.PaymentController: Information: Sepet Base64 encode edilmiş hali: W1siVXJ1biAxIiwiMTguMDAiLDFdLFsiVXJ1biAyIiwiMzMuMjUiLDFdXQ==trilancer.Controllers.PaymentController: Information: Token oluşturma verisi: ******trilancer.Controllers.PaymentController: Information: PayTR Token: ******=trilancer.Controllers.PaymentController: Information: PayTR'ye gönderilecek veri: {"merchant_id":"*****","user_ip":"******","merchant_oid":"*****","email":"testuser@gmail.com","payment_amount":"5125","user_basket":"W1siVXJ1biAxIiwiMTguMDAiLDFdLFsiVXJ1biAyIiwiMzMuMjUiLDFdXQ==","paytr_token":"********=","debug_on":"1","test_mode":"1","no_installment":"0","max_installment":"0","user_name":"Test Kullanici","user_address":"Test Adres","user_phone":"5555555555","merchant_ok_url":"https://localhost:7037/Payment/Success","merchant_fail_url":"https://localhost:7037/Payment/Fail","timeout_limit":"30","currency":"TL","lang":"tr"} trilancer.Controllers.PaymentController: Information: PayTR API yanıtı: {"status":"failed","reason":"paytr_token gonderilmedi veya gecersiz (get-token)"}trilancer.Controllers.PaymentController: Error: Token alma işlemi başarısız. Sebep: paytr_token gonderilmedi veya gecersiz (get-token)
 

Technopat Haberler

Geri
Yukarı