Bu sayfada
Hata Yönetimi
Merchant API hatalarını yönetin: yanıt zarfı, HTTP durum grupları, makine tarafından okunabilir kodlar, istek limitleri ve yeniden deneme rehberi.
API standart HTTP durum kodları kullanır. Başarılı yanıtlar kaynak gövdesini doğrudan döndürür. Hatalar, HTTP API'leri için RFC 9457 Problem Details biçimini (application/problem+json) iki genişletme üyesiyle izler: programatik olarak switch'leyeceğiniz üst düzey bir code ve tek alanlı doğrulama hatalarında üst düzey bir field (snake_case). Birden fazla alan aynı anda başarısız olduğunda field, alan bazlı dökümü taşıyan bir errors[] dizisiyle (bir Paymos genişletme üyesi, §3.2) değiştirilir.
Programatik işleme ve yerelleştirme için code üzerinden switch yapın — asla title veya detail metni üzerinden değil. Dize alanları sürümler arasında yeniden yazılabilir; code kararlı sözleşmedir.
{
"type": "https://paymos.io/docs/errors/codes#insufficient_balance",
"title": "Conflict",
"status": 409,
"detail": "Merchant balance is insufficient.",
"code": "insufficient_balance"
}
Her hata yanıtı, HTTP API'leri için RFC 9457 Problem Details biçimini izler ve Content-Type: application/problem+json olarak servis edilir.
Tek hata (çoğu yanıt)
{
"type": "https://paymos.io/docs/errors/codes#insufficient_balance",
"title": "Conflict",
"status": 409,
"detail": "Merchant balance is insufficient.",
"code": "insufficient_balance"
}
Çok alanlı doğrulama
Yalnızca birden fazla alan aynı anda doğrulamayı geçemediğinde üretilir. Üst düzey code her zaman validation_failed'dır; alan bazlı ayrıntı errors[] içinde yaşar:
{
"type": "https://paymos.io/docs/errors/codes#validation_failed",
"title": "Bad Request",
"status": 400,
"detail": "Validation failed.",
"code": "validation_failed",
"errors": [
{ "code": "field_required", "field": "currency", "message": "Currency is required." },
{ "code": "field_must_be_positive", "field": "amount", "message": "Amount must be > 0." }
]
}
Alan referansı
| Alan | Tür | RFC | Açıklama |
|---|---|---|---|
type |
string (URI) | RFC 9457 §3.1.1 | Belirli code için dokümantasyon satırına doğrudan bağlantı. Kod başına kararlıdır — yayınlandıktan sonra asla değişmez. |
title |
string | RFC 9457 §3.1.3 | Kısa HTTP durum başlığı ("Bad Request", "Conflict", …). |
status |
integer | RFC 9457 §3.1.2 | HTTP durum kodu (yanıt durumunun yansısı). |
detail |
string | RFC 9457 §3.1.4 | Bu spesifik oluşumun insan tarafından okunabilir İngilizce açıklaması. |
code |
string | genişletme (§3.2) | Kararlı, makine tarafından okunabilir tanımlayıcı — bkz. Hata Kodları. Entegrasyonunuzda bunu switch'leyin. |
field |
string | genişletme (§3.2) | Tek alanlı doğrulama hataları için kablo biçimindeki alan adı (snake_case). Alanla ilgili olmayan hatalarda tamamen atlanır — anahtar JSON'da hiç bulunmaz, asla null olmaz. Yalnızca errors[] yokken bulunur. |
errors |
array | genişletme (§3.2) | Yalnızca birden fazla alan aynı anda başarısız olduğunda bulunur. Her kayıt: { code, field, message }. |
Neden yapılandırılmış kodlar (sadece message değil)
message ve detail metni sürümler arasında evrilebilir, yerelleştirilebilir veya bağlamla genişletilebilir. code kararlı sözleşmedir — bir kod yayınlandıktan sonra anlamı asla değişmez. Programatik işleme ve yerelleştirme için code üzerinden switch yapın.
import { RateLimitError, ValidationError } from '@paymos/sdk';
try {
await paymos.withdrawals.create(request);
} catch (error) {
if (error instanceof ValidationError) {
for (const item of error.errors) highlight(item.field, item.message);
} else if (error instanceof RateLimitError) {
scheduleRetry(error.retryAfterSeconds);
}
throw error;
}
use paymos::{ApiErrorKind, Error};
match paymos.withdrawals().create(&request).await {
Ok(withdrawal) => process(withdrawal),
Err(Error::Api(error)) if error.kind == ApiErrorKind::Validation => {
for item in &error.errors {
highlight(item.field.as_deref(), &item.message);
}
}
Err(Error::Api(error)) if error.kind == ApiErrorKind::RateLimit => {
schedule_retry(error.retry_after);
}
Err(error) => return Err(error),
}
Hata türleri
Her durum, bir title ve makine tarafından okunabilir bir code ile hata zarfında gelir. Tek bir durum birden fazla senaryoyu kapsayabilir — duruma değil, code değerine göre dallanın.
| HTTP Kodu | title |
Açıklama |
|---|---|---|
400 |
Bad Request |
Girdi doğrulaması başarısız oldu veya istek gövdesi geçersiz. Tek alanlı hatalar üst düzeyde code + field taşır; çok alanlı hatalar errors[] dizisini doldurur. |
401 |
Unauthorized |
HMAC kimlik bilgileri eksik, bozuk, süresi dolmuş veya geçersiz. Özel neden için code değerine bakın (invalid_credentials, timestamp_expired, authorization_malformed, …). |
403 |
Forbidden |
Kimlik doğrulandı, ancak anahtar türü, ortam veya kapsam işleme izin vermiyor. Özel neden için code değerine bakın (merchant_suspended, whitelist_required, vb.). |
404 |
Not Found |
Kaynak yok, çağırana görünür değil (başka bir işyerine ait kaynak not_found döndürür, asla forbidden değil) veya istek yoluyla eşleşen uç nokta yok (route_not_found). |
405 |
Method Not Allowed |
Yol var, ancak bu HTTP metodu için değil. method_not_allowed kodunu taşır. |
409 |
Conflict |
İstek mevcut durumla çakışıyor — geçersiz bir geçiş, zaten var olan bir kaynak veya eylemi engelleyen bir koruma. Özel neden için code değerine bakın (insufficient_balance, withdrawal_quota_exceeded, invoice_cannot_be_cancelled, …). |
410 |
Gone |
Kaynak artık kullanılamıyor (örneğin süresi dolmuş veya iptal edilmiş bir fatura). |
413 |
Payload Too Large |
İstek gövdesi boyut sınırını aşıyor (1 MiB). payload_too_large kodunu taşır. |
415 |
Unsupported Media Type |
Content-Type application/json değil. unsupported_media_type kodunu taşır. |
429 |
Too Many Requests |
İşyeri başına rate limit aşıldı. Yeniden denemeden önce Retry-After başlığını (saniye) okuyun. |
500 |
Internal Server Error |
Bizim tarafımızda bir şey başarısız oldu. Üstel geri çekilmeyle yeniden deneyin. |
503 |
Service Unavailable |
Geçici bağımlılık veya işleme sorunu (exchange_rate_unavailable, acceptance_disabled, outbound_frozen, …). Geri çekilmeyle yeniden deneyin. |
İstemci mantığını yönlendirmek için her zaman code değerini kullanın (HTTP durumunu değil) — birden fazla farklı iş senaryosu aynı HTTP durumunu paylaşır ve kablo kodu bunları birbirinden ayırır.
Rate limit'ler
API, varsayılan olarak işyeri başına saniyede 30 isteğe izin verir; POST /v1/invoices üzerinde daha sıkı bir limit vardır (5 istek/sn). Limitler işyeri başına, bir saniyelik pencerede sayılır — elinizdeki her API anahtarı aynı bütçeyi kullanır — ve ikisi de işyeri bazında yapılandırılabilir. Limit aşıldığında, Retry-After: 1 başlığıyla bir 429 Too Many Requests yanıtı alırsınız.
{
"type": "https://paymos.io/docs/errors/codes#rate_limited",
"title": "Too Many Requests",
"status": 429,
"detail": "Rate limit exceeded (30 req/sec). Retry after 1 second.",
"code": "rate_limited"
}