İçeriğe atlayın

API

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"
}