Blog'a Dön

C# / .NET Döviz Kuru API'si — Kapsamlı Entegrasyon Rehberi (2026)

V
Vlado Grigirov
May 26, 2026
C# .NET Currency API Exchange Rates Tutorial Fintech ASP.NET Core

Microsoft yığını üzerinde bir ödeme backend'i, SaaS faturalama motoru veya kurumsal fiyatlandırma servisi inşa ediyorsanız, bu hafta sahaya çıkarabileceğiniz en yüksek etkili işlerden biri bir C# / .NET döviz kuru API'si entegrasyonudur. Modern .NET size ihtiyacınız olan her şeyi hazır verir — HttpClient, IHttpClientFactory, System.Text.Json, IMemoryCache ve birinci sınıf bağımlılık enjeksiyonu — buna rağmen tutorialların çoğu hâlâ üretim kod incelemesinden geçemeyecek tek bir WebClient.DownloadString parçası gösteriyor. Bu rehber sizi ilk istekten başlayıp ASP.NET Core, Blazor, WPF veya Azure Function'a doğrudan bırakabileceğiniz tipli, önbellekli ve dayanıklı bir istemciye taşır.

Rehber bittiğinde elinizde Finexly API dokümantasyonunu çağıran yeniden kullanılabilir bir Finexly istemcisi, küçük bir konsol çevirici ve yığınınızın geri kalanına gerçek zamanlı kurlar sunan bir ASP.NET Core Minimal API olacak — hepsi Microsoft'un kendi önerdiği desenlerle yazılmış deyimsel .NET 8 / .NET 9.

C# / .NET döviz entegrasyonları için neden güçlü bir seçim

Üretimdeki kur dönüşümü çoğunlukla bir I/O problemidir: kurları çek, önbelleğe al, biraz ondalık çarp, JSON döndür. .NET çalışma zamanı son on yıldır tam olarak bu yük için optimize edildi:

  • IHttpClientFactory soket tükenmesini çözer. HttpMessageHandler örneklerini havuzlar, böylece HttpClient'ı her yere soket sızdırmadan enjekte edebilirsiniz — eski .NET kodunda gördüğümüz aralıklı kur API hatalarının en büyük kaynağı.
  • System.Text.Json hızlı ve düşük tahsislidir. Tipik 170 para birimli yanıtı milisaniyenin çok altında, üçüncü taraf bağımlılığı olmadan ayrıştırır.
  • decimal dile gömülüdür. Parayı doğru ele almak için harici bir BigDecimal'a hiç ihtiyacınız yok — binlerce dönüştürülmüş fatura satırını topladığınızda bu fark eder.
  • Polly fiili dayanıklılık kütüphanesidir. Yeniden deneme, devre kesici ve zaman aşımı bir AddPolicyHandler çağrısı uzaktadır.
  • Minimal API'ler ve AOT. 30 satırda küçük bir kur mikroservisi açmak artık gerçekçi ve soğuk başlangıç milisaniyelerle ölçülüyor.

Diğer yığınları değerlendiriyorsanız Node.js, Python, Go ve PHP için paralel rehberlerimiz var. Bu makale özellikle C# için ve async/await, Generic Hosting ile bağımlılık enjeksiyonuna aşina olduğunuzu varsayar.

Önkoşullar ve proje kurulumu

.NET 8 veya .NET 9 yüklü olmalı. SDK'yı doğrulayın:

dotnet --version

İstemci için bir sınıf kütüphanesi ve onu denemek için bir konsol uygulaması içeren yeni bir çözüm oluşturun:

mkdir Finexly.Sample && cd Finexly.Sample
dotnet new sln -n Finexly.Sample
dotnet new classlib -n Finexly.Client
dotnet new console   -n Finexly.ConsoleApp
dotnet sln add Finexly.Client/Finexly.Client.csproj
dotnet sln add Finexly.ConsoleApp/Finexly.ConsoleApp.csproj
dotnet add Finexly.ConsoleApp/Finexly.ConsoleApp.csproj reference Finexly.Client/Finexly.Client.csproj

Ayrıca bir Finexly API anahtarına ihtiyacınız var. Ücretsiz kaydolun — kredi kartı gerekmez, ücretsiz plan ayda 1.000 istek sunar; geliştirme ve CI için fazlasıyla yeterlidir.

Anahtarı asla kod içine gömmeyin. Onu bir ortam değişkeninde saklayın:

# macOS / Linux
export FINEXLY_API_KEY="your_api_key_here"
# Windows PowerShell
$env:FINEXLY_API_KEY = "your_api_key_here"

Üretimde Azure Key Vault, AWS Secrets Manager veya yerel geliştirme için dotnet user-secrets kullanın.

HttpClient ile ilk isteğiniz

En basit çalışan örnekle başlayalım. Finexly.ConsoleApp/Program.cs dosyasını açın:

using System.Net.Http;
using System.Net.Http.Json;

var apiKey = Environment.GetEnvironmentVariable("FINEXLY_API_KEY")
    ?? throw new InvalidOperationException("FINEXLY_API_KEY not set");

using var http = new HttpClient
{
    BaseAddress = new Uri("https://api.finexly.com/v1/")
};

var url = $"latest?base=USD&apikey={apiKey}";
var payload = await http.GetFromJsonAsync<Dictionary<string, object>>(url);

Console.WriteLine(payload?["rates"]);

Çalıştırın:

dotnet run --project Finexly.ConsoleApp

Para birimi kodlarını ve bunların USD karşısındaki kurlarını içeren bir sözlük göreceksiniz. Çalışıyor, ama 10 satırlık bir örnekten beklenebilecek tüm kokular var: tipsiz object değerleri, önbellek yok, yeniden deneme yok, elle oluşturulmuş HttpClient ve URL'de API anahtarı. Bunların hepsini düzeltelim.

Güçlü tipli yanıt modelleri tanımlama

System.Text.Json C# record tiplerine temiz şekilde ayrıştırır. Finexly.Client projesinde Models/LatestRatesResponse.cs dosyasını oluşturun:

using System.Text.Json.Serialization;

namespace Finexly.Client.Models;

public sealed record LatestRatesResponse(
    [property: JsonPropertyName("base")] string Base,
    [property: JsonPropertyName("date")] DateOnly Date,
    [property: JsonPropertyName("rates")] IReadOnlyDictionary<string, decimal> Rates
);

Dikkat etmek gereken birkaç detay:

  • double yerine decimal. Para için kayan nokta hatası kabul edilemez. decimal size 28–29 anlamlı basamak ve kesin 10 tabanlı aritmetik verir.
  • IReadOnlyDictionary. Yanıt salt okunurdur — bunu tipte ifade edin.
  • DateOnly. Modern .NET düzgün bir tarih tipi getiriyor. Saat bileşeni olmadığında DateTime yerine bunu kullanın.

Artık dynamic veya Dictionary<string, object> jimnastiği olmadan ayrıştırabiliyoruz.

IHttpClientFactory ile tipli HttpClient oluşturma

.NET'in önerdiği desen, IHttpClientFactory üzerinden kayıtlı bir tipli istemcidir. Bağlantı havuzlama, ayarlanabilir handler'lar ve kolay DI sağlar. Finexly.Client projesinde FinexlyClient.cs oluşturun:

using System.Net.Http.Json;
using Finexly.Client.Models;

namespace Finexly.Client;

public sealed class FinexlyClient
{
    private readonly HttpClient _http;
    private readonly string _apiKey;

    public FinexlyClient(HttpClient http, FinexlyOptions options)
    {
        _http = http;
        _apiKey = options.ApiKey;
        _http.BaseAddress = new Uri("https://api.finexly.com/v1/");
        _http.DefaultRequestHeaders.Add("X-Api-Key", _apiKey);
        _http.Timeout = TimeSpan.FromSeconds(5);
    }

    public async Task<LatestRatesResponse> GetLatestRatesAsync(
        string baseCurrency = "USD",
        IEnumerable<string>? symbols = null,
        CancellationToken cancellationToken = default)
    {
        var query = $"latest?base={baseCurrency}";
        if (symbols is not null)
        {
            query += $"&symbols={string.Join(",", symbols)}";
        }

        var response = await _http.GetFromJsonAsync<LatestRatesResponse>(
            query, cancellationToken);

        return response
            ?? throw new InvalidOperationException("Empty response from Finexly");
    }

    public async Task<decimal> ConvertAsync(
        string from, string to, decimal amount,
        CancellationToken cancellationToken = default)
    {
        var rates = await GetLatestRatesAsync(from, new[] { to }, cancellationToken);
        if (!rates.Rates.TryGetValue(to, out var rate))
        {
            throw new ArgumentException($"Unknown currency: {to}");
        }
        return amount * rate;
    }
}

public sealed class FinexlyOptions
{
    public required string ApiKey { get; init; }
}

Vurgulanması gereken noktalar:

  • API anahtarı URL'ye değil bir başlığa gider — log, proxy ve trace için daha güvenli.
  • 5 saniyelik Timeout, takılan bir kur API'sinin yavaş bir ödemeye dönüşmesini önler.
  • İstemci her metoduna CancellationToken alır — modern ASP.NET'te tartışmasız.
  • GetFromJsonAsync<T> kullanır; GET, durum kontrolü ve ayrıştırmayı düşük tahsisli tek bir çağrıda birleştirir.

İstemciyi Dependency Injection'a kaydetme

Program.cs'inizde (Console, ASP.NET Core, Worker — her yerde aynı API):

using Finexly.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddSingleton(new FinexlyOptions
{
    ApiKey = Environment.GetEnvironmentVariable("FINEXLY_API_KEY")!
});

builder.Services.AddHttpClient<FinexlyClient>();

using var host = builder.Build();

var finexly = host.Services.GetRequiredService<FinexlyClient>();
var eur = await finexly.ConvertAsync("USD", "EUR", 100m);
Console.WriteLine($"100 USD = {eur:0.00} EUR");

AddHttpClient<FinexlyClient>(), FinexlyClient'ı transient olarak kaydeder ve fabrikadan havuzlanmış bir HttpClient verir. Artık FinexlyClient'ı herhangi bir controller, Minimal API endpoint veya arka plan servisine enjekte edebilirsiniz.

Polly ile yeniden deneme ve devre kesici ekleme

Harici API'ler ara sıra bir isteği düşürür, kısıtlar veya ağ katmanında tıkanır. Polly .NET'in standart dayanıklılık kütüphanesidir ve IHttpClientFactory ile iki satırda entegre olur.

Paketi yükleyin:

dotnet add Finexly.ConsoleApp package Microsoft.Extensions.Http.Polly

Geri çekilmeli yeniden deneme ve devre kesici tanımlayın:

using Polly;
using Polly.Extensions.Http;

builder.Services.AddHttpClient<FinexlyClient>()
    .AddPolicyHandler(HttpPolicyExtensions
        .HandleTransientHttpError()
        .OrResult(r => (int)r.StatusCode == 429)
        .WaitAndRetryAsync(
            retryCount: 3,
            sleepDurationProvider: attempt =>
                TimeSpan.FromMilliseconds(200 * Math.Pow(2, attempt))))
    .AddPolicyHandler(HttpPolicyExtensions
        .HandleTransientHttpError()
        .CircuitBreakerAsync(
            handledEventsAllowedBeforeBreaking: 5,
            durationOfBreak: TimeSpan.FromSeconds(30)));

Bu tek kayıt 5xx, 408 ve 429'da üstel geri çekilmeyle (200ms, 400ms, 800ms) yeniden dener ve API tamamen düşerse devre kesiciyi tetikler — ödeme sayfası dakikalarca bağlantıyı tutmak yerine zarif şekilde bozulur.

Yanıtları IMemoryCache ile önbellekleme

Canlı kurlar dakikada bir kereden fazla değişmez nadiren; küçük bir süreç içi önbellek genellikle üst akış çağrılarını %95 veya daha fazla azaltır. IMemoryCache kutudan çıkıyor.

dotnet add Finexly.Client package Microsoft.Extensions.Caching.Memory

CachedFinexlyClient.cs oluşturun:

using Finexly.Client.Models;
using Microsoft.Extensions.Caching.Memory;

namespace Finexly.Client;

public sealed class CachedFinexlyClient
{
    private readonly FinexlyClient _inner;
    private readonly IMemoryCache _cache;
    private static readonly TimeSpan DefaultTtl = TimeSpan.FromSeconds(60);

    public CachedFinexlyClient(FinexlyClient inner, IMemoryCache cache)
    {
        _inner = inner;
        _cache = cache;
    }

    public Task<LatestRatesResponse> GetLatestRatesAsync(
        string baseCurrency,
        CancellationToken cancellationToken = default)
    {
        var key = $"finexly:latest:{baseCurrency}";

        return _cache.GetOrCreateAsync(key, entry =>
        {
            entry.AbsoluteExpirationRelativeToNow = DefaultTtl;
            return _inner.GetLatestRatesAsync(baseCurrency,
                cancellationToken: cancellationToken);
        })!;
    }
}

IMemoryCache ile birlikte kaydedin:

builder.Services.AddMemoryCache();
builder.Services.AddSingleton<CachedFinexlyClient>();

60 saniyelik TTL ödeme fiyatları, faturalama önizlemeleri ve yönetim panelleri için harika bir varsayılan. Tarihsel veriler için TTL'yi saatlere veya günlere çıkarın — tarihsel kurlar değişmez.

Çalışan bir konsol döviz çeviricisi

Hepsini birleştirince currencyconverter --amount 100 --from USD --to JPY benzeri küçük bir CLI çıkıyor:

using Finexly.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddMemoryCache();
builder.Services.AddSingleton(new FinexlyOptions
{
    ApiKey = Environment.GetEnvironmentVariable("FINEXLY_API_KEY")!
});
builder.Services.AddHttpClient<FinexlyClient>();
builder.Services.AddSingleton<CachedFinexlyClient>();

using var host = builder.Build();

decimal amount = 1m;
string from = "USD", to = "EUR";

for (int i = 0; i < args.Length - 1; i++)
{
    switch (args[i])
    {
        case "--amount": amount = decimal.Parse(args[i + 1]); break;
        case "--from":   from   = args[i + 1].ToUpperInvariant(); break;
        case "--to":     to     = args[i + 1].ToUpperInvariant(); break;
    }
}

var finexly = host.Services.GetRequiredService<CachedFinexlyClient>();
var rates   = await finexly.GetLatestRatesAsync(from);

if (!rates.Rates.TryGetValue(to, out var rate))
{
    Console.Error.WriteLine($"Unknown currency: {to}");
    return 1;
}

Console.WriteLine($"{amount:0.00} {from} = {amount * rate:0.00} {to}");
return 0;

Herhangi bir sunucuya bırakabileceğiniz tek dosyalı bir binary derleyin:

dotnet publish Finexly.ConsoleApp -c Release -r linux-x64 \
  --self-contained -p:PublishSingleFile=true

ASP.NET Core Minimal API ile kurları yayınlama

Birçok ekip için doğru mimari, üst akış API'sini sarıp önbellek ekleyen ve diğer tüm servislere hızlı, ücretsiz, VPC içi bir endpoint sunan dahili bir kur mikroservisidir. ASP.NET Core Minimal API bunu 30 satırlık bir dosyaya indirir:

using Finexly.Client;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddMemoryCache();
builder.Services.AddSingleton(new FinexlyOptions
{
    ApiKey = builder.Configuration["Finexly:ApiKey"]!
});
builder.Services.AddHttpClient<FinexlyClient>();
builder.Services.AddSingleton<CachedFinexlyClient>();

var app = builder.Build();

app.MapGet("/rates", async (
    string? @base,
    CachedFinexlyClient finexly,
    CancellationToken ct) =>
{
    var rates = await finexly.GetLatestRatesAsync(@base ?? "USD", ct);
    return Results.Ok(rates);
});

app.MapGet("/convert", async (
    string from, string to, decimal amount,
    CachedFinexlyClient finexly,
    CancellationToken ct) =>
{
    var rates = await finexly.GetLatestRatesAsync(from, ct);
    return rates.Rates.TryGetValue(to, out var rate)
        ? Results.Ok(new { from, to, amount, converted = amount * rate })
        : Results.NotFound(new { error = $"Unknown currency {to}" });
});

app.Run();

Bunu her zamanki API gateway'inizin arkasına dağıtın; filonuzdaki herhangi bir servis önbellek isabetinde 10 milisaniyenin altında gecikmeyle GET /convert?from=USD&to=EUR&amount=99.95 çağırabilir. Tarayıcı tarafı deneyim için aynı veri barındırılan döviz çeviricimizde de mevcut.

C#'ta parayı doğru ele almak

Bir ödeme defterini ilk denetlediğinizde geri ödenen savunmacı desenler:

  • Her zaman decimal kullanın, asla double veya float değil. 0.1 + 0.2 ünlü şekilde kayan noktada 0.3 değildir — ve bu tek yuvarlama hatası size bir chargeback davasına mal olabilir.
  • Hesaplamada değil sunumda yuvarlayın. Her çarpımda tam hassasiyeti koruyun ve yalnızca gösterirken veya kaydederken Math.Round(value, 2, MidpointRounding.ToEven) çağırın.
  • Yuvarlama modunu sabitleyin. Banker yuvarlaması (ToEven), IEEE 754 ve ISO 80000-1'de finans endüstrisinin varsayılanıdır.
  • Para birimlerini opak kodlar olarak ele alın. ISO 4217 dizelerini kullanın — bir para biriminin iki ondalık basamağı olduğunu varsaymayın. JPY'de sıfır, BHD'de üç vardır. ISO 4217 rehberimiz sınır durumlarını kapsıyor.

Üretim için en iyi pratikler

Bir hobi entegrasyonunu yıllarca işletebileceğiniz bir sistemden ayıran ek desenler:

  • Sıkı HTTP zaman aşımları belirleyin. Varsayılan 100 saniyelik HttpClient.Timeout yük altında thread havuzunuzu bloke eder. Bir kur API'si için beş saniye fazlasıyla yeterli.
  • Her dış çağrıyı bir CancellationToken ile sarın. ASP.NET Core size bedavaya verir; saygı gösterin ki düşen istekler üst akışla konuşmaya devam etmesin.
  • Durum kodlarını loglayın, gövdeleri değil. Kur API yanıtları faydalı şekilde loglanamayacak kadar büyüktür ve Splunk'a koymak istemeyebileceğiniz kur verileri içerebilir.
  • Kotanızı izleyin. Fiyatlandırma planlarını karşılaştırın ve aylık tavanınızın %80'inde CloudWatch / Application Insights uyarıları kurun.
  • Sadece gerçekten kullandığınız para birimlerini pinleyin. symbols=EUR,GBP,JPY göndermek yanıtı ~10 KB'tan 200 baytın altına düşürür.
  • Agresif önbellekleyin. Gecikmeye duyarlı ödemeler 30 saniyelik önbellekle yaşayabilir; yönetim panelleri 5 dakikayla idare eder.

Sağlayıcıları değerlendiriyorsanız, ücretsiz ve ücretli kur API karşılaştırmamız başlıca seçeneklerin doğruluk, uptime ve fiyatlarını anlatır.

Sıkça sorulan sorular

C# ve .NET ile en iyi hangi kur API'si çalışır? Temiz JSON ve sağlam uptime sunan herhangi bir REST API IHttpClientFactory üzerinden iyi entegre olur. Finexly özellikle dil bağımsız tasarlanmıştır — aynı endpoint'ler Node, Python, Go, Java ve .NET istemcileri tarafından SDK kilidi olmadan kullanılır. Ücretsiz kur API genel bakışı.

Newtonsoft.Json mı System.Text.Json mı? .NET 6+ üstündeki yeni kodlarda System.Text.Json kullanın. 2–3 kat daha hızlı, daha az tahsis eder ve BCL'in parçası, yani güncel tutulacak ekstra paket yok. Newtonsoft.Json hâlâ mükemmel ve eski kodda tutmaya değer, ancak yeni C# kur entegrasyonları varsayılan olarak System.Text.Json kullanmalı.

NuGet SDK'sına ihtiyacım var mı yoksa HttpClient yeterli mi? Elle yazılmış tipli istemci (yaklaşık 50 satır C#) neredeyse her zaman doğru yanıttır. Önbellek, yeniden deneme, telemetri ve serileştirme üzerinde tam kontrol verir; üçüncü taraf SDK'ların sürüm sapması riskinden kaçınır. Bu eğitimdeki örnek üretime hazırdır.

.NET uygulamasında kurları ne sıklıkla yenilemeliyim? Çoğu durumda — e-ticaret ödemeleri, SaaS faturalama, faturalandırma — 30 ila 60 saniyelik bir önbellek güvenlidir. Trading sistemleri elbette gerçek zamanlı veri ister, ama geri kalan her şey için dakika seviyesinde tazelik kullanıcılara görünmez ve API harcamasını ciddi şekilde azaltır.

Bunu Azure Functions veya AWS Lambda'da çalıştırabilir miyim? Evet. IHttpClientFactory, izole işlemli Azure Functions'ta ve Microsoft.Extensions.Hosting kullanan Lambda handler'larında aynı şekilde çalışır. Soğuk başlatmaya duyarlı yükler için AOT (PublishAot=true) ile yayınlayın; fonksiyonunuz 100 ms'nin altında başlar.

decimal, double'a göre yavaş mı? decimal, aritmetik işlem başına double'dan yaklaşık 10–20 kat daha yavaştır, fakat bir kur dönüşümü en fazla birkaç çarpım yapar. Gerçek bir yükte farkı asla ölçemezsiniz — ve para için doğruluğun getirisi tartışılmaz.

Toparlayalım

Artık C# / .NET döviz kuru API'sini entegre etmek için eksiksiz, üretim sınıfı bir plana sahipsiniz: güçlü tipli modeller, IHttpClientFactory destekli istemci, Polly tabanlı yeniden deneme ve devre kesici, süreç içi önbellek, konsol çeviricisi ve ASP.NET Core Minimal API. Buradaki her desen doğrudan Microsoft'un resmi rehberinden geliyor ve gerçek fintech üretim kodunda denenmiş.

.NET uygulamanıza gerçek zamanlı kurlar getirmeye hazır mısınız? Ücretsiz Finexly API anahtarınızı alın — kredi kartı gerekmez. Ayda 1.000 ücretsiz istekle başlayın ve ürününüz büyüdükçe yükseltin. Önce Finexly'yi diğer sağlayıcılarla karşılaştırmak isterseniz kur API karşılaştırmamızı okuyun.

Vlado Grigirov

Senior Currency Markets Analyst & Financial Strategist

Vlado Grigirov is a senior currency markets analyst and financial strategist with over 14 years of experience in foreign exchange markets, cross-border finance, and currency risk management. He has wo...

View full profile →