Merhaba arkadaşlar,
PayTR İframe API entegrasyonunu projeme eklemeye çalışırken, API'den aşağıdaki hatayı alıyorum:
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:
Paytr'nin paylaştığı örnek kod:
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:
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.
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)