WooCommerce dünyadaki çevrimiçi mağazaların yaklaşık üçte birini çalıştırıyor ve bunlardan biri sınır ötesi satışa başlamaya karar verdiği anda hep aynı soru ortaya çıkıyor: her sabah döviz piyasasını elle kontrol etmeden, on iki para biriminde fiyatları, vergileri ve ödemeleri nasıl tutarlı tutarsın? Dürüst cevap, mağazaya WooCommerce çoklu para birimi döviz kuru API'si bağlamaktır — ama bunu doğru yapmak, bir eklenti kurup unutmaktan çok daha incelikli. Yenileme sıklığı, cache stampede, ödeme ağ geçidi uyumluluğu, yuvarlama ve checkout ortasında upstream'in 503 dönmesi gibi konuları düşünmek zorundasın.
Bu kılavuz, geliştiricilerin 2026'da gerçekten kullandığı üç üretim örüntüsünü, her biri için çalışan PHP ile anlatıyor. Finexly API'sini WooCommerce'a üç farklı şekilde bağlayacağız: mevcut bir para birimi switcher eklentisi için özel besleme olarak, çekirdek filtrelerle sıfırdan kurulan bir katman olarak ve düzgün kilitlemeli bir Action Scheduler işi olarak. Sonunda, hangi yığından başlarsanız başlayın — düz WooCommerce, switcher eklentili WooCommerce ya da tamamen özel B2B build — uygun bir örüntü elinizde olacak.
WooCommerce için Gerçek Zamanlı Döviz Kuru API'si Neden Önemli
Kutudan çıktığı gibi WooCommerce, woocommerce_currency içinde tek bir baz para birimi belirler ve her siparişin, iadenin ve ödemenin o para biriminde kapatılacağını varsayar. Çoklu para birimi desteği üstüne oturan bir katmandır: header'da bir switcher, yeniden hesaplanan sepet toplamları ve (bazen) yerelleştirilmiş ödeme işleme. Bu katmanın bir yerlerden döviz kuruna ihtiyacı vardır ve "bir yerler" genelde iki şeyden biri olur — kimsenin güncellemeyi hatırlamadığı manuel girilmiş bir oran ya da 12-24 saatte bir tıklayan ücretsiz bir sağlayıcı beslemesi.
Her ikisi de 2026 FX ortamında tehlikeli. USD/JPY çifti yalnızca 6 Mayıs'ta Tokyo müdahalesinin ardından %0,95 hareket etti, yükselen piyasa para birimleri ise gün içinde sık sık %1'den fazla salınıyor. 24 saatlik bir kuru gösteren mağaza, rüzgârın yönüne göre %1-2 indirimle ya da prim ekleyerek satış yapıyor demek — ve bu, ödeme ağ geçidinin settlement'ta üzerine koyduğu spreadden önce. Makul bir cache katmanına sahip gerçek zamanlı bir WooCommerce çoklu para birimi döviz kuru API'si, gösterilen fiyatları her zaman mid-market'tan yüzdenin küçük bir bölümü kadar uzakta tutar.
Diğer önemli sebep: ödeme ağ geçidinin para birimi desteği. Stripe, PayPal ve büyük ağ geçitlerinin desteklenen settlement para birimlerine ait kendi listeleri var. Mağaza 15 para biriminde fiyat gösteriyor ama Stripe yalnızca 6'sında settlement yapıyorsa, hangi dönüşümün nerede ve hangi kurla olduğunu bilmen gerekir — ve bu hesap, FX gerçeğinin sahibi kara kutu bir ağ geçidi değil senin katmanın olduğunda çok daha kolay.
Üç Entegrasyon Örüntüsü
Bir döviz API'sini WooCommerce mağazasına bağlayabileceğin üç yer vardır, her birinin kendi takasları var:
- Mevcut switcher eklentisine kanca takmak — en hızlı yol, CURCY, FOX, Aelia, VillaTheme ve popüler eklentilerin çoğunda çalışır. Kod yüzeyi minimaldir ama eklentinin güncelleme ritmine ve mağaza UI'ına bağlı kalırsın.
- WooCommerce çekirdek hook'ları üzerinden özel filtre katmanı — hangi fiyatların çevrileceği üzerinde tam kontrol (normal, indirim, kargo, vergi), ama daha çok kod yazıp UI'ı kendin sahiplenirsin.
- Hibrit: UI eklentide, kurlar senin kodunda — zaten switcher eklentisi kullanan mağazalar için iki tarafın da en iyisi. Eklenti switcher'ı çizer; zamanlanmış işin kurları eklentinin deposuna iter.
Üçünü de kuracağız.
Örüntü 1: Mevcut Switcher Eklentisi için Özel Kur Beslemesi
Popüler WooCommerce para birimi eklentilerinin çoğu, özel kur kaynakları için bir filtre veya action hook açar. VillaTheme'in CURCY eklentisi wmc_get_currency_exchange_rates kullanır. FOX woocs_currencies_array kullanır. Aelia wc_aelia_cs_exchange_rates_request_args kullanır. Örüntü her yerde aynıdır — eklentinin yerleşik sağlayıcılarından alacağı kurları kesip kendi kurlarınla değiştirirsin.
CURCY için tam bir örnek (FOX için aynı şekil, sadece filtre adı farklı). Küçük bir mu-plugin'e ya da temanın functions.php'sine koy:
<?php
/**
* Plugin Name: Finexly Rates for CURCY
* Description: Pulls real-time WooCommerce multi-currency exchange rates from Finexly.
*/
add_filter( 'wmc_get_currency_exchange_rates', 'finexly_curcy_rates', 10, 1 );
function finexly_curcy_rates( $rates ) {
$cached = get_transient( 'finexly_curcy_rates' );
if ( false !== $cached ) {
return wp_parse_args( $cached, $rates );
}
$base = get_woocommerce_currency(); // e.g. "USD"
$symbols = array_keys( $rates ); // e.g. ["EUR","GBP","JPY",...]
$api_key = defined( 'FINEXLY_API_KEY' ) ? FINEXLY_API_KEY : '';
if ( empty( $api_key ) || empty( $symbols ) ) {
return $rates; // graceful fall-through to plugin defaults
}
$url = add_query_arg( array(
'apikey' => $api_key,
'base' => $base,
'currencies' => implode( ',', $symbols ),
), 'https://api.finexly.com/v1/latest' );
$response = wp_remote_get( $url, array( 'timeout' => 8 ) );
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
return $rates;
}
$body = json_decode( wp_remote_retrieve_body( $response ), true );
if ( empty( $body['rates'] ) ) {
return $rates;
}
// CURCY expects an associative array of CODE => rate (relative to base).
$fresh = array();
foreach ( $body['rates'] as $code => $rate ) {
$fresh[ $code ] = (float) $rate;
}
set_transient( 'finexly_curcy_rates', $fresh, HOUR_IN_SECONDS );
return wp_parse_args( $fresh, $rates );
}Birkaç önemli ayrıntı. Birincisi, wp_remote_get çağrısının timeout'u 8 saniye — yavaş bir yanıtı emecek kadar uzun, upstream bozulduğunda PHP-FPM yıkılmayacak kadar kısa. İkincisi, herhangi bir hatada (ağ hatası, 200 dışı, eksik payload) boş dizi yerine eklentinin varsayılan $rates değerini döndürüyoruz. Düşürülmüş bir checkout, kırık bir checkout'tan iyidir. Üçüncüsü, transient başarılı yanıtları bir saat cache'liyor; perakende için fazlasıyla taze ve API kotanın çok altında.
Anahtarını wp-config.php'de tanımla:
define( 'FINEXLY_API_KEY', 'your_api_key_here' );Hepsi bu. CURCY switcher header'da çıkıyor, müşteri bir para birimi seçiyor ve fiyatlar CURCY'nin varsayılan 12 saatlik Yahoo Finance beslemesi yerine senin API çağrından gelen taze kurlarla yeniden hesaplanıyor.
Örüntü 2: Çekirdek WooCommerce Filtreleriyle Sıfırdan Çoklu Para Birimi
Halkanın içinde eklenti istemiyorsan — ya da switcher'ın header'daki bir dropdown değil hesap düzeyinde bir ayar olduğu özel bir B2B mağaza kuruyorsan — tüm çoklu para birimi katmanını iki çekirdek filtreyle kurabilirsin: woocommerce_currency ve raw_woocommerce_price.
woocommerce_currency, isteği bazında aktif para birimini değiştirmeni sağlar. raw_woocommerce_price, WooCommerce'un gösterdiği her fiyatı dönüştürmeni sağlar. Bunu bir oturum değişkeniyle birleştirirsen yaklaşık 60 satırda çalışan bir para birimi switcher'ı elde edersin:
<?php
class Finexly_WC_Currency {
const SESSION_KEY = 'finexly_active_currency';
const TRANSIENT = 'finexly_rates';
public function __construct() {
add_action( 'init', array( $this, 'maybe_switch_currency' ) );
add_filter( 'woocommerce_currency', array( $this, 'active_currency' ) );
add_filter( 'raw_woocommerce_price', array( $this, 'convert_price' ) );
add_filter( 'woocommerce_package_rates', array( $this, 'convert_shipping' ), 10, 2 );
}
public function maybe_switch_currency() {
if ( isset( $_GET['set_currency'] ) ) {
$code = strtoupper( sanitize_text_field( $_GET['set_currency'] ) );
if ( array_key_exists( $code, $this->rates() ) ) {
WC()->session->set( self::SESSION_KEY, $code );
}
}
}
public function active_currency( $default ) {
$code = WC()->session ? WC()->session->get( self::SESSION_KEY ) : null;
return $code ?: $default;
}
public function convert_price( $price ) {
$code = $this->active_currency( get_option( 'woocommerce_currency' ) );
$rates = $this->rates();
if ( ! isset( $rates[ $code ] ) ) {
return $price;
}
return (float) $price * (float) $rates[ $code ];
}
public function convert_shipping( $rates, $package ) {
$code = $this->active_currency( get_option( 'woocommerce_currency' ) );
$fx = $this->rates();
if ( ! isset( $fx[ $code ] ) ) {
return $rates;
}
foreach ( $rates as $rate ) {
$rate->cost = (float) $rate->cost * (float) $fx[ $code ];
foreach ( $rate->taxes as &$tax ) {
$tax = (float) $tax * (float) $fx[ $code ];
}
}
return $rates;
}
private function rates() {
$cached = get_transient( self::TRANSIENT );
return is_array( $cached ) ? $cached : array();
}
}
new Finexly_WC_Currency();Transient'ı ayrı bir zamanlanmış iş dolduruyor (sonraki bölüm), bu yüzden bu sınıf bir istek içinde asla ağ çağrısı yapmıyor — her sayfa yüklemesi tek bir get_transient lookup'ı; object cache açık ortamlarda yaklaşık 0,1ms tutuyor. Bu, cache'siz her sayfada TTFB'ye 8ms eklemekle, saatte bir tek bir cron worker'ına 800ms eklemek arasındaki fark.
Üretim için eklemen gereken iki şey: hassasiyet ve yuvarlama. WooCommerce fiyatları decimal olarak saklar; decimal(13,4) bir değeri 1.10851234 oranıyla çarpıp tekrar decimal(13,4) olarak kaydedersen sessizce hassasiyet kaybedersin. Düşük fiyatlı ürünlerde (1 doların altı SKU'lar, bahşiş kavanozları, mikro bağışlar) iç tarafta en az 8 ondalık basamaklı hassasiyet, gösterim katmanında ise para biriminin doğal en küçük birimine yuvarlama isteyeceksin. WooCommerce'un wc_price() yardımcısı gösterim yuvarlamasını senin için yapar; senin yapman gereken altta yatan float'ları yeterince geniş tutmak.
Örüntü 3: Stampede Korumalı Action Scheduler Yenileme İşi
Yukarıdaki iki örüntü transient'tan okuyor. Birinin transient'a yazması gerek. WooCommerce'da doğru araç Action Scheduler — WooCommerce ile birlikte gelen iş çalıştırıcı — çünkü güvenilir, otomatik retry yapıyor ve eşzamanlılığı wp_schedule_event'tan daha iyi yönetiyor.
<?php
/**
* Plugin Name: Finexly Rates Refresh
* Description: Refreshes WooCommerce multi-currency exchange rates from Finexly hourly.
*/
add_action( 'init', function () {
if ( false === as_next_scheduled_action( 'finexly_refresh_rates' ) ) {
as_schedule_recurring_action(
time() + 60,
HOUR_IN_SECONDS,
'finexly_refresh_rates',
array(),
'finexly'
);
}
} );
add_action( 'finexly_refresh_rates', 'finexly_do_refresh' );
function finexly_do_refresh() {
// Stampede lock: only one worker at a time.
$lock_key = 'finexly_refresh_lock';
if ( get_transient( $lock_key ) ) {
return;
}
set_transient( $lock_key, 1, 30 );
try {
$base = get_option( 'woocommerce_currency', 'USD' );
$supported = apply_filters( 'finexly_currencies', array(
'USD','EUR','GBP','JPY','CHF','CAD','AUD','CNY','INR','BRL','MXN','SEK','NOK','SGD','HKD','TRY','ZAR','PLN'
) );
$url = add_query_arg( array(
'apikey' => FINEXLY_API_KEY,
'base' => $base,
'currencies' => implode( ',', $supported ),
), 'https://api.finexly.com/v1/latest' );
$response = wp_remote_get( $url, array( 'timeout' => 10 ) );
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
// Don't blow away existing rates on a transient upstream failure.
error_log( 'Finexly refresh failed: ' . wp_remote_retrieve_response_code( $response ) );
return;
}
$body = json_decode( wp_remote_retrieve_body( $response ), true );
if ( empty( $body['rates'] ) ) {
return;
}
$rates = array_map( 'floatval', $body['rates'] );
$rates[ $base ] = 1.0;
set_transient( 'finexly_rates', $rates, 3 * HOUR_IN_SECONDS );
// Persist to options as a durable fallback. Object cache flushes
// would otherwise wipe transients and force a cold checkout.
update_option( 'finexly_rates_persistent', array(
'fetched_at' => time(),
'base' => $base,
'rates' => $rates,
), false );
} finally {
delete_transient( $lock_key );
}
}Belirtmeye değer üç örüntü. Stampede kilidi, Action Scheduler geç çalıştırılıp iki iş arka arkaya kuyruğa girdiğinde paralel iki worker'ın upstream'i dövmesini engelliyor. Transient TTL'si × 3 vs. bir saatlik yenileme aralığı, bilinçli bir tampon — bir yenileme başarısız olursa cache'lenen değer bir sonraki denemeye kadar dayanır. Options'a kalıcı yedek, üçüncü katman: object cache herhangi bir nedenle boşalsa bile mağazada hâlâ 24 saatlik kullanılabilir bir kur seti olur ve rates() metodu boş döndürmeden önce ona düşebilir.
Cache mimarisinin kendisini daha derinlemesine merak ediyorsan, döviz API'si cache ve hata yönetimi rehberimizdeki örüntüler doğrudan WooCommerce'a uygulanabilir.
Çoklu Para Birimi Entegrasyonunu Test Etmek
WooCommerce mağazaları üretimde tahmin edilebilir üç şekilde bozulur ve üçü de test edilebilir. WP_Mock ve Mockery kullanan minimum bir PHPUnit suite:
<?php
class Finexly_WC_Currency_Test extends WP_Mock\Tools\TestCase {
public function test_convert_price_with_known_rate() {
WP_Mock::userFunction( 'get_transient' )
->with( 'finexly_rates' )
->andReturn( array( 'EUR' => 0.92, 'GBP' => 0.79 ) );
WP_Mock::userFunction( 'get_option' )
->with( 'woocommerce_currency' )
->andReturn( 'USD' );
$svc = new Finexly_WC_Currency();
$svc->set_active_currency( 'EUR' );
$this->assertEqualsWithDelta( 92.0, $svc->convert_price( 100.0 ), 0.0001 );
}
public function test_returns_original_price_when_rate_missing() {
WP_Mock::userFunction( 'get_transient' )
->andReturn( array() );
$svc = new Finexly_WC_Currency();
$svc->set_active_currency( 'XYZ' ); // unsupported code
$this->assertEquals( 100.0, $svc->convert_price( 100.0 ) );
}
public function test_refresh_handles_upstream_500() {
WP_Mock::userFunction( 'wp_remote_get' )
->andReturn( array( 'response' => array( 'code' => 500 ) ) );
WP_Mock::userFunction( 'set_transient' )->never();
WP_Mock::userFunction( 'update_option' )->never();
finexly_do_refresh();
// Test passes if no fatal error and we don't overwrite cached rates.
}
}Üçüncü test, çoğu ekibin atladığı testtir. Üretimde gördüğüm hemen her WooCommerce para birimi hatası "upstream hata döndü ve biz boş yanıtı cache'ledik"e indirgenir. Başarısızlıkta çöp yazmadığını doğrulamak, başarıda doğru olanı yazdığını doğrulamaktan daha değerlidir.
Sık Karşılaşılan Tuzaklar ve Aşmanın Yolu
Ödeme ağ geçidinin para birimi desteği. Mağazanın TRY fiyat göstermesi, Stripe'ın TRY'de settlement yapacağı anlamına gelmez. Switcher'da bir para birimi sunmadan önce WC()->payment_gateways() üzerinden aktif ağ geçitlerinin desteklediği para birimlerinin kesişimine süzme yap. Stripe FX Quotes API ile özel döviz API'si karşılaştırması ödünleşmeleri ayrıntılı ele alıyor.
İadeler ve sipariş düzenleme. USD bazlı bir siparişten üç hafta sonra EUR olarak yapılan iade bugünkü kurla değil, ağ geçidinin iade anında yakaladığı kurla yapılır. Sipariş anının kurunu sipariş meta'sına yaz (update_post_meta( $order_id, '_finexly_rate', $rate )) ki raporlama eşleştirebilsin. Bu, muhasebe yazılımı entegrasyonu katmanı için de kullanışlı.
Yuvarlama. Yuvarlamayı saklarken değil, gösterirken yap. 9.99 * 0.92 = 9,1908'i 9,19'a yuvarlayıp USD'ye geri çevirmek 9,989... verir, 9,99 değil. Geniş iç hassasiyet + gösterim sırasında yuvarlama, mantıklı tek örüntüdür.
ISO 4217 geçerliliği. Kullanıcı girdisine güvenme. Tüm para birimi kodlarını oturuma yazmadan önce ISO 4217 listesine karşı doğrula.
API Seçimi: Ücretsiz mi Ücretli mi
WooCommerce'a yerleşik sağlayıcılar (Open Exchange Rates ücretsiz katman, kullanımdan kaldırılan CurrencyLayer vb.) 12-24 saatte bir günceller ve düşük kotalarla sınırlandırır. Tek ürünlü, ayda on siparişlik küçük bir mağaza için yeterli; trafiği olan herhangi bir şey için, en az saatlik yenileme yapan ve çağrı kıstırmaya zorlamayan bir kotaya sahip özel bir sağlayıcı isteyeceksin. 2026 için ücretsiz vs ücretli döviz API'si karşılaştırmamızda gerçek rakamlar var.
Finexly API tam olarak bu kullanım senaryosunu hedefliyor — 170+ para birimi, majörlerde 60 saniyelik yenileme, long-tail'de saatlik, ve saatte bir Action Scheduler işine yetecek 1.000 istek/ay ücretsiz katman, retry için pay da kalıyor. Döviz API'lerini karşılaştırabilir ya da geliştirme mağazanda denemek için ücretsiz kayıt olabilirsin.
Sıkça Sorulan Sorular
WooCommerce çoklu para birimini yerel olarak destekler mi?
Kısmen. WooCommerce siparişler ve ödemeler için tek bir baz para birimini destekler. Çoklu para birimi gösterimi ve checkout'u ya bir switcher eklentisi (CURCY, FOX, Aelia vb.) ya da woocommerce_currency ve raw_woocommerce_price filtreleriyle yazılan özel kod gerektirir; iki yaklaşımın da senin sağladığın bir kur kaynağına ihtiyacı var.
WooCommerce'da kurları ne sıklıkta yenilemeliyim? Perakende e-ticaret için saatlik fazlasıyla yeter. Yüksek değerli faturaları olan B2B mağazalar için 15-30 dakika daha güvenli. Daha agresif olmak nadiren API kotasına değer — ödeme ağ geçitleri zaten settlement'ta yeniden fiyatlandırma yapıyor, dolayısıyla 5 dakikalık bir kurla 30 dakikalık bir kur arasındaki fark ağ geçidi spread'i karşısında gürültü kalıyor.
Halihazırda kullandığım WooCommerce switcher eklentisine özel bir döviz API'si entegre edebilir miyim?
Evet. CURCY wmc_get_currency_exchange_rates, FOX woocs_currencies_array, Aelia wc_aelia_cs_exchange_rates_request_args açar. Filtreye bağlan, kurlarını döndür, eklentinin UI'ı değişmeden çalışmaya devam eder.
Checkout sırasında kur API'si çökerse ne olur? Yukarıdaki mimariyle müşteriye görünen hiçbir şey olmaz. Fiyatlandırma katmanı, arka plan işinin doldurduğu transient'tan okur; en son yenileme başarısız olduysa önceki kur hâlâ cache'tedir ve kalıcı option 24 saatlik bir yedek tutar. Checkout son bilinen iyi kurla devam eder.
Para birimleri arası iadeleri nasıl ele alırım? Sipariş anında kullanılan kuru sipariş meta'sında sakla. İade anında o kurla tutarı hesapla, bugünkü kurla değil, böylece müşteri ödediği para biriminde tam karşılığını alır. FX kâr/zararını muhasebe sistemin ayrıca eşleştirir.
Toparlarken
Sağlam bir WooCommerce çoklu para birimi döviz kuru API'si entegrasyonu aslında API çağrısıyla ilgili değildir — etrafındaki dört katmanla ilgilidir: cache, zamanlama, yedekler ve testler. Bunları doğru kur, mağazan tek bir gece pager alarmı almadan 50+ para birimini doğru fiyatlandırır.
WooCommerce mağazana gerçek zamanlı döviz kurlarını entegre etmeye hazır mısın? Ücretsiz Finexly API anahtarını al — kredi kartı gerekmez. Ayda 1.000 ücretsiz istekle başla, yukarıdaki snippet'leri bir mu-plugin'e yapıştır, öğle yemeğinden önce çoklu para birimini canlıya alırsın. Ücretsiz katmanı aştığında fiyatlandırma planları mağazana üstel değil, doğrusal ölçeklenir.
Explore More
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 →