Amazon SP API Entegrasyonu: Adım Adım Rehber

Ashley Innocent

Ashley Innocent

20 March 2026

Amazon SP API Entegrasyonu: Adım Adım Rehber

Kurumsal Apidog

Şirket İçi Dağıtım

SSO & RBAC

SOC 2 Uyumlu

Apidog Enterprise'ı Keşfet

TL;DR

Amazon Satış Ortağı API'si (SP-API), siparişler, envanter, listelemeler ve gönderim için satıcı verilerine programlı erişim sağlayan REST tabanlı bir API'dir. IAM rolleriyle OAuth 2.0 kimlik doğrulamasını kullanır, AWS SigV4 imzalama gerektirir ve uç noktaya göre değişen (saniyede 0,1 ila 100 istek) oran sınırları uygular. Bu kılavuz, hesap kurulumunu, kimlik doğrulamasını, temel uç noktaları, webhook aboneliklerini ve üretim dağıtım stratejilerini kapsar.

Giriş

Amazon, dünya genelinde 200'den fazla pazar yerinde 350 milyondan fazla ürünü işlemektedir. E-ticaret araçları, envanter yönetim sistemleri veya analitik platformlar geliştiren geliştiriciler için Amazon SP-API entegrasyonu isteğe bağlı değildir; zorunludur.

Gerçek şu ki: Amazon operasyonlarını yöneten satıcılar, siparişler, envanter ve listelemelerdeki manuel veri girişinde haftalık 20-30 saat kaybediyor. Sağlam bir SP-API entegrasyonu, birden fazla pazar yerinde sipariş senkronizasyonunu, envanter güncellemelerini ve listeleme yönetimini otomatikleştirir.

Bu kılavuz, eksiksiz Amazon SP-API entegrasyon sürecini anlatmaktadır. IAM rolü kurulumu, OAuth 2.0 yetkilendirmesi, AWS SigV4 istek imzalama, sipariş ve envanter yönetimi, bildirim abonelikleri ve hata giderme konularını öğreneceksiniz. Sonunda, üretime hazır bir Amazon entegrasyonuna sahip olacaksınız.

💡
Apidog, API entegrasyon testlerini basitleştirir. SP-API uç noktalarınızı test edin, OAuth akışlarını doğrulayın, istek imzalarını inceleyin ve kimlik doğrulama sorunlarını tek bir çalışma alanında ayıklayın. API özelliklerini içe aktarın, yanıtları taklit edin ve test senaryolarını ekibinizle paylaşın.

button

Amazon SP-API Nedir?

Amazon Satış Ortağı API'si (SP-API), Satıcı Merkezi verilerine programlı erişim sağlayan REST tabanlı bir API'dir. Geliştirilmiş güvenlik, performans ve işlevsellik ile eski Pazar Yeri Web Hizmeti (MWS) sisteminin yerini almıştır.

Temel Yetenekler

SP-API şunları yönetir:

SP-API ve MWS Karşılaştırması

Özellik SP-API MWS (Eski)
Mimari RESTful JSON XML tabanlı
Kimlik Doğrulama OAuth 2.0 + IAM MWS Auth Token
Güvenlik AWS SigV4 imzalama Basit belirteçler
Oran Sınırları Uç noktaya göre dinamik Sabit kotalar
Pazar Yerleri Birleşik uç noktalar Bölgeye özgü
Durum Mevcut Kullanımdan kaldırıldı (Aralık 2025)

Tüm MWS entegrasyonlarını derhal SP-API'ye geçirin. Amazon, MWS'nin tamamen kullanımdan kaldırılmasını Aralık 2025 olarak duyurdu.

API Mimari Genel Bakış

Amazon, merkezi yetkilendirme ile bölgesel bir API yapısı kullanır:

https://sellingpartnerapi-na.amazon.com (Kuzey Amerika)
https://sellingpartnerapi-eu.amazon.com (Avrupa)
https://sellingpartnerapi-fe.amazon.com (Uzak Doğu)

Tüm istekler şunları gerektirir:

  1. AWS SigV4 imzası
  2. OAuth akışından erişim belirteci
  3. Uygun IAM rol izinleri
  4. İzleme için İstek Kimliği

Desteklenen Pazar Yerleri

Bölge Pazar Yerleri API Uç Noktası
Kuzey Amerika ABD, CA, MX sellingpartnerapi-na.amazon.com
Avrupa İngiltere, DE, FR, IT, ES, NL, SE, PL, TR, EG, IN, AE, SA sellingpartnerapi-eu.amazon.com
Uzak Doğu JP, AU, SG, BR sellingpartnerapi-fe.amazon.com

Başlarken: Hesap ve IAM Kurulumu

Adım 1: Amazon Geliştirici Hesabınızı Oluşturun

SP-API'ye erişmeden önce uygun hesap erişimine sahip olmanız gerekir:

  1. Amazon Geliştirici Merkezi'ni ziyaret edin
  2. Amazon hesabınızla oturum açın (Satıcı Merkezi erişimi olmalıdır)
  3. Kontrol panelinde Selling Partner API'ye gidin
  4. Geliştirici Anlaşmasını kabul edin

Adım 2: Uygulamanızı Kaydedin

Satıcı Merkezi'nde bir uygulama profili oluşturun:

  1. Satıcı Merkezi'ne giriş yapın
  2. Uygulamalar ve Hizmetler > Uygulamalar Geliştir'e gidin
  3. Yeni Uygulama Ekle'ye tıklayın
  4. Uygulama ayrıntılarını doldurun:

Gönderimden sonra şunları alacaksınız:

Güvenlik notu: Kimlik bilgilerini kodda değil, ortam değişkenlerinde saklayın:

# .env dosyası
AMAZON_APPLICATION_ID="amzn1.application.xxxxx"
AMAZON_CLIENT_ID="amzn1.account.xxxxx"
AMAZON_CLIENT_SECRET="sırrınız_buraya"
AMAZON_SELLER_ID="satıcı_kimliğiniz_buraya"
AWS_ACCESS_KEY_ID="aws_erişim_anahtarınız"
AWS_SECRET_ACCESS_KEY="aws_gizli_anahtarınız"
AWS_REGION="us-east-1"

Adım 3: SP-API için IAM Rolü Oluşturun

SP-API, belirli izinlere sahip bir IAM rolü gerektirir:

  1. AWS IAM Konsolu'na giriş yapın
  2. Roller > Rol Oluştur'a gidin
  3. Güvenilir varlık olarak Başka bir AWS hesabı'nı seçin
  4. Bölgeniz için Amazon'un hesap kimliğini girin:

Adım 4: IAM Politikasını Yapılandırın

Bu politikayı IAM rolünüze ekleyin:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "execute-api:Invoke"
      ],
      "Resource": [
        "arn:aws:execute-api:*:*:*/prod/*/sellingpartnerapi/*"
      ]
    }
  ]
}

Rolünüzü SellingPartnerApiRole gibi açıklayıcı bir adla adlandırın ve ARN'sini not alın.

Adım 5: IAM Rolünü Uygulamaya Bağlayın

IAM rolünüzü SP-API uygulamasına bağlayın:

  1. Satıcı Merkezi > Uygulamalar Geliştir'e geri dönün
  2. Uygulamanızı seçin
  3. Düzenle > IAM Rolü ARN'ye tıklayın
  4. IAM rolünüzün ARN'sini girin
  5. Değişiklikleri kaydedin

Amazon, IAM rolünü dakikalar içinde doğrular. Hazır olduğunda "Bağlantılı" durumunu göreceksiniz.

OAuth 2.0 Kimlik Doğrulama Akışı

SP-API OAuth'ı Anlamak

Amazon, yetkilendirme için OAuth 2.0 kullanır. İşte eksiksiz akış:

1. Satıcı, uygulamanızda "Yetkilendir"e tıklar
2. Uygulamanız Amazon yetkilendirme URL'sine yönlendirir
3. Satıcı oturum açar ve izinleri verir
4. Amazon, yetkilendirme koduyla geri yönlendirir
5. Uygulamanız, kodu bir LWA (Amazon ile Giriş Yap) belirteciyle değiştirir
6. Uygulamanız, LWA belirtecini SP-API erişim belirteciyle değiştirir
7. Uygulamanız, API çağrıları için erişim belirtecini kullanır (SigV4 imzalı)
8. Erişim belirtecinin süresi dolduğunda yenileme belirtecini kullanın (1 saat)

Adım 6: Yetkilendirme URL'sini Oluşturun

OAuth yetkilendirme URL'sini oluşturun:

const generateAuthUrl = (clientId, redirectUri, state) => {
  const baseUrl = 'https://www.amazon.com/sp/apps/oauth/authorize';
  const params = new URLSearchParams({
    application_id: process.env.AMAZON_APPLICATION_ID,
    client_id: clientId,
    redirect_uri: redirectUri,
    state: state, // CSRF koruması için rastgele dize
    scope: 'sellingpartnerapi::notifications'
  });

  return `${baseUrl}?${params.toString()}`;
};

// Kullanım
const authUrl = generateAuthUrl(
  process.env.AMAZON_CLIENT_ID,
  'https://uygulamaniz.com/callback',
  crypto.randomBytes(16).toString('hex')
);

console.log(`Kullanıcıyı şuraya yönlendir: ${authUrl}`);

Gerekli OAuth Kapsamları

Yalnızca uygulamanızın ihtiyaç duyduğu izinleri isteyin:

Kapsam Açıklama Kullanım Alanı
sellingpartnerapi::notifications Bildirimleri al Webhook abonelikleri
sellingpartnerapi::migration MWS'den geçiş yap Eski entegrasyonlar

Çoğu API erişimi, OAuth kapsamları tarafından değil, IAM politikaları tarafından kontrol edilir.

Adım 7: Kodu LWA Belirteciyle Değiştirin

OAuth geri çağırmasını işleyin ve yetkilendirme kodunu değiştirin:

const exchangeCodeForLwaToken = async (code, redirectUri) => {
  const response = await fetch('https://api.amazon.com/auth/o2/token', {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      client_id: process.env.AMAZON_CLIENT_ID,
      client_secret: process.env.AMAZON_CLIENT_SECRET,
      redirect_uri: redirectUri,
      code: code
    })
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`LWA Belirteç Hatası: ${error.error_description}`);
  }

  const data = await response.json();

  return {
    access_token: data.access_token,
    refresh_token: data.refresh_token,
    expires_in: data.expires_in, // Genellikle 3600 saniye (1 saat)
    token_type: data.token_type
  };
};

// Geri arama rotasını işle
app.get('/callback', async (req, res) => {
  const { spapi_oauth_code, state } = req.query;

  // Gönderdiğiniz durumla eşleştiğini doğrulayın (CSRF koruması)
  if (state !== req.session.oauthState) {
    return res.status(400).send('Geçersiz durum parametresi');
  }

  try {
    const tokens = await exchangeCodeForLwaToken(spapi_oauth_code, 'https://uygulamaniz.com/callback');

    // Belirteçleri satıcıyla ilişkilendirerek veritabanında saklayın
    await db.sellers.update(req.session.sellerId, {
      amazon_lwa_access_token: tokens.access_token,
      amazon_lwa_refresh_token: tokens.refresh_token,
      amazon_token_expires: Date.now() + (tokens.expires_in * 1000)
    });

    res.redirect('/dashboard');
  } catch (error) {
    console.error('Belirteç değişimi başarısız:', error);
    res.status(500).send('Kimlik doğrulama başarısız oldu');
  }
});

Adım 8: LWA Belirtecini SP-API Kimlik Bilgileriyle Değiştirin

Geçici AWS kimlik bilgilerini almak için LWA erişim belirtecini kullanın:

const assumeRole = async (lwaAccessToken) => {
  const response = await fetch('https://api.amazon.com/auth/o2/token', {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'client_credentials',
      client_id: process.env.AMAZON_CLIENT_ID,
      client_secret: process.env.AMAZON_CLIENT_SECRET,
      scope: 'sellingpartnerapi::notifications'
    })
  });

  const data = await response.json();

  // STS aracılığıyla AWS kimlik bilgileriyle değiştirin
  const stsResponse = await fetch('https://sts.amazonaws.com/', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Authorization': `Bearer ${data.access_token}`
    },
    body: new URLSearchParams({
      Action: 'AssumeRole',
      RoleArn: 'arn:aws:iam::HESABINIZ_NUMARASI:role/SellingPartnerApiRole',
      RoleSessionName: 'sp-api-session',
      Version: '2011-06-15'
    })
  });

  return stsResponse;
};

Adım 9: Belirteç Yenilemeyi Uygulayın

Erişim belirteçlerinin süresi 1 saat sonra dolar. Otomatik yenilemeyi uygulayın:

const refreshLwaToken = async (refreshToken) => {
  const response = await fetch('https://api.amazon.com/auth/o2/token', {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'refresh_token',
      client_id: process.env.AMAZON_CLIENT_ID,
      client_secret: process.env.AMAZON_CLIENT_SECRET,
      refresh_token: refreshToken
    })
  });

  const data = await response.json();

  return {
    access_token: data.access_token,
    refresh_token: data.refresh_token, // Her zaman yeni yenileme belirtecini kaydedin
    expires_in: data.expires_in
  };
};

// Geçerli belirteci sağlamak için ara yazılım
const ensureValidToken = async (sellerId) => {
  const seller = await db.sellers.findById(sellerId);

  // Belirtecin 5 dakika içinde süresinin dolup dolmadığını kontrol edin
  if (seller.amazon_token_expires < Date.now() + 300000) {
    const newTokens = await refreshLwaToken(seller.amazon_lwa_refresh_token);

    await db.sellers.update(sellerId, {
      amazon_lwa_access_token: newTokens.access_token,
      amazon_lwa_refresh_token: newTokens.refresh_token,
      amazon_token_expires: Date.now() + (newTokens.expires_in * 1000)
    });

    return newTokens.access_token;
  }

  return seller.amazon_lwa_access_token;
};

AWS SigV4 İstek İmzalama

SigV4'ü Anlamak

Tüm SP-API istekleri, AWS İmza Sürüm 4 (SigV4) imzası gerektirir. Bu, isteğin orijinalliğini ve bütünlüğünü sağlar.

SigV4 İmzalama Süreci

const crypto = require('crypto');

class SigV4Signer {
  constructor(accessKey, secretKey, region, service = 'execute-api') {
    this.accessKey = accessKey;
    this.secretKey = secretKey;
    this.region = region;
    this.service = service;
  }

  sign(method, url, body = '', headers = {}) {
    const parsedUrl = new URL(url);
    const now = new Date();

    // Adım 1: Kanonik istek oluştur
    const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '');
    const dateStamp = amzDate.slice(0, 8);

    headers['host'] = parsedUrl.host;
    headers['x-amz-date'] = amzDate;
    headers['x-amz-access-token'] = this.accessToken;
    headers['content-type'] = 'application/json';

    const canonicalHeaders = Object.entries(headers)
      .sort(([a], [b]) => a.localeCompare(b))
      .map(([k, v]) => `${k.toLowerCase()}:${v.trim()}`)
      .join('\n');

    const signedHeaders = Object.keys(headers)
      .sort()
      .map(k => k.toLowerCase())
      .join(';');

    const payloadHash = crypto.createHash('sha256').update(body).digest('hex');

    const canonicalRequest = [
      method.toUpperCase(),
      parsedUrl.pathname,
      parsedUrl.search.slice(1),
      canonicalHeaders,
      '',
      signedHeaders,
      payloadHash
    ].join('\n');

    // Adım 2: İmzalanacak dizeyi oluştur
    const algorithm = 'AWS4-HMAC-SHA256';
    const credentialScope = `${dateStamp}/${this.region}/${this.service}/aws4_request`;

    const stringToSign = [
      algorithm,
      amzDate,
      credentialScope,
      crypto.createHash('sha256').update(canonicalRequest).digest('hex')
    ].join('\n');

    // Adım 3: İmzayı hesapla
    const kDate = this.hmac(`AWS4${this.secretKey}`, dateStamp);
    const kRegion = this.hmac(kDate, this.region);
    const kService = this.hmac(kRegion, this.service);
    const kSigning = this.hmac(kService, 'aws4_request');
    const signature = this.hmac(kSigning, stringToSign, 'hex');

    // Adım 4: Yetkilendirme başlığını ekle
    const authorization = `${algorithm} Credential=${this.accessKey}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;

    return {
      headers: {
        ...headers,
        'Authorization': authorization
      },
      canonicalRequest,
      stringToSign,
      signature
    };
  }

  hmac(key, data, encoding = 'buffer') {
    return crypto.createHmac('sha256', key).update(data).digest(encoding);
  }
}

// Kullanım
const signer = new SigV4Signer(
  process.env.AWS_ACCESS_KEY_ID,
  process.env.AWS_SECRET_ACCESS_KEY,
  'us-east-1'
);

const signedRequest = signer.sign('GET', 'https://sellingpartnerapi-na.amazon.com/orders/v0/orders', '', {
  'x-amz-access-token': accessToken
});

SigV4 için AWS SDK Kullanımı

AWS SDK ile imzalamayı basitleştirin:

const { SignatureV4 } = require('@aws-sdk/signature-v4');
const { Sha256 } = require('@aws-crypto/sha256-js');

const signer = new SignatureV4({
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
  },
  region: 'us-east-1',
  service: 'execute-api',
  sha256: Sha256
});

const makeSpApiRequest = async (method, endpoint, accessToken, body = null) => {
  const url = new URL(endpoint);

  const headers = {
    'host': url.host,
    'content-type': 'application/json',
    'x-amz-access-token': accessToken,
    'x-amz-date': new Date().toISOString().replace(/[:-]|\.\d{3}/g, '')
  };

  const signedRequest = await signer.sign({
    method,
    hostname: url.hostname,
    path: url.pathname,
    query: Object.fromEntries(url.searchParams),
    headers,
    body: body ? JSON.stringify(body) : undefined
  });

  const response = await fetch(endpoint, {
    method,
    headers: signedRequest.headers,
    body: signedRequest.body
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`SP-API Hatası: ${error.errors?.[0]?.message || response.statusText}`);
  }

  return response.json();
};

Siparişler API'si

Siparişleri Alma

Filtreleme seçenekleriyle siparişleri alın:

const getOrders = async (accessToken, options = {}) => {
  const params = new URLSearchParams({
    createdAfter: options.createdAfter, // ISO 8601 formatı
    createdBefore: options.createdBefore,
    orderStatuses: options.orderStatuses?.join(',') || '',
    marketplaceIds: options.marketplaceIds?.join(',') || ['ATVPDKIKX0DER'], // ABD
    maxResultsPerPage: options.maxResultsPerPage || 100
  });

  // Boş parametreleri kaldır
  for (const [key, value] of params.entries()) {
    if (!value) params.delete(key);
  }

  const endpoint = `https://sellingpartnerapi-na.amazon.com/orders/v0/orders?${params.toString()}`;

  return makeSpApiRequest('GET', endpoint, accessToken);
};

// Kullanım örneği
const orders = await getOrders(accessToken, {
  createdAfter: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), // Son 24 saat
  orderStatuses: ['Unshipped', 'PartiallyShipped'],
  marketplaceIds: ['ATVPDKIKX0DER'] // ABD pazar yeri
});

Sipariş Yanıt Yapısı

{
  "payload": {
    "orders": [
      {
        "amazon_order_id": "112-1234567-1234567",
        "seller_order_id": "ORDER-001",
        "purchase_date": "2026-03-19T10:30:00Z",
        "last_update_date": "2026-03-19T14:45:00Z",
        "order_status": "Unshipped",
        "fulfillment_channel": "AFN", // AFN = FBA, MFN = Satıcı
        "sales_channel": "Amazon.com",
        "order_channel": "Amazon.com",
        "ship_service_level": "Std US D2D Dom",
        "order_total": {
          "currency_code": "USD",
          "amount": "89.99"
        },
        "number_of_items_shipped": 0,
        "number_of_items_unshipped": 2,
        "payment_execution_detail": [],
        "payment_method": "CreditCard",
        "payment_method_details": ["CreditCard"],
        "marketplace_id": "ATVPDKIKX0DER",
        "shipment_service_level_category": "Standard",
        "easy_ship_shipment_status": null,
        "is_business_order": false,
        "is_prime": true,
        "is_premium_order": false,
        "is_global_express_enabled": false
      }
    ],
    "next_token": "eyJleHBpcmF0aW9uVGltZU9mTmV4dFRva2VuIjoxNzEwOTUwNDAwfQ=="
  }
}

Sipariş Öğelerini Alma

Bir sipariş için detaylı satır öğelerini alın:

const getOrderItems = async (accessToken, orderId) => {
  const endpoint = `https://sellingpartnerapi-na.amazon.com/orders/v0/orders/${orderId}/orderItems`;

  return makeSpApiRequest('GET', endpoint, accessToken);
};

// Kullanım
const orderItems = await getOrderItems(accessToken, '112-1234567-1234567');

// Beklenen yanıt
{
  "payload": {
    "order_items": [
      {
        "asin": "B08N5WRWNW",
        "seller_sku": "MYSKU-001",
        "title": "Kablosuz Bluetooth Kulaklıklar",
        "quantity_ordered": 2,
        "quantity_shipped": 0,
        "product_info": {
          "number_of_items": 2
        },
        "item_price": {
          "currency_code": "USD",
          "amount": "44.99"
        },
        "item_total": {
          "currency_code": "USD",
          "amount": "89.98"
        },
        "tax_collection": {
          "tax_collection_model": "MarketplaceFacilitator",
          "responsible_party": "Amazon Services, Inc."
        }
      }
    ]
  }
}

Gönderim Durumunu Güncelleme

Takip bilgileriyle siparişleri gönderildi olarak işaretleyin:

const confirmShipment = async (accessToken, orderId, shipmentData) => {
  const endpoint = `https://sellingpartnerapi-na.amazon.com/orders/v0/orders/${orderId}/shipmentConfirmation`;

  const payload = {
    packageDetails: {
      packageReferenceId: shipmentData.packageReferenceId || '1',
      carrier_code: shipmentData.carrierCode, // örn., 'USPS', 'FEDEX', 'UPS'
      tracking_number: shipmentData.trackingNumber,
      ship_date: shipmentData.shipDate || new Date().toISOString(),
      items: shipmentData.items.map(item => ({
        order_item_id: item.orderItemId,
        quantity: item.quantity
      }))
    }
  };

  return makeSpApiRequest('POST', endpoint, accessToken, payload);
};

// Kullanım
await confirmShipment(accessToken, '112-1234567-1234567', {
  carrierCode: 'USPS',
  trackingNumber: '9400111899223456789012',
  items: [
    { orderItemId: '12345678901234', quantity: 2 }
  ]
});

Yaygın Taşıyıcı Kodları

Taşıyıcı Taşıyıcı Kodu
USPS USPS
FedEx FEDEX
UPS UPS
DHL DHL
Canada Post CANADA_POST
Royal Mail ROYAL_MAIL
Australia Post AUSTRALIA_POST
Amazon Logistics AMZN_UK

Envanter API'si

Envanter Özetlerini Alma

Pazar yerleri genelinde envanter seviyelerini alın:

const getInventorySummaries = async (accessToken, options = {}) => {
  const params = new URLSearchParams({
    granularityType: options.granularityType || 'Marketplace',
    granularityId: options.granularityId || 'ATVPDKIKX0DER', // ABD
    startDateTime: options.startDateTime || '',
    sellerSkus: options.sellerSkus?.join(',') || ''
  });

  const endpoint = `https://sellingpartnerapi-na.amazon.com/fba/inventory/v1/summaries?${params.toString()}`;

  return makeSpApiRequest('GET', endpoint, accessToken);
};

// Kullanım
const inventory = await getInventorySummaries(accessToken, {
  granularityId: 'ATVPDKIKX0DER',
  sellerSkus: ['MYSKU-001', 'MYSKU-002']
});

Envanter Yanıt Yapısı

{
  "payload": {
    "inventorySummaries": [
      {
        "asin": "B08N5WRWNW",
        "seller_sku": "MYSKU-001",
        "condition": "NewItem",
        "details": {
          "quantity": 150,
          "fulfillable_quantity": 145,
          "inbound_working_quantity": 0,
          "inbound_shipped_quantity": 5,
          "inbound_receiving_quantity": 0,
          "reserved_quantity": 5,
          "unfulfillable_quantity": 0,
          "warehouse_damage_quantity": 0,
          "distributor_damaged_quantity": 0,
          "carrier_damaged_quantity": 0,
          "defective_quantity": 0,
          "customer_damaged_quantity": 0
        },
        "marketplace_id": "ATVPDKIKX0DER"
      }
    ]
  }
}

Envanteri Güncelleme

Not: SP-API, doğrudan envanter güncelleme uç noktaları sağlamaz. Envanter şunlar aracılığıyla yönetilir:

  1. FBA gönderileri - Envanteri Amazon depolarına gönderin
  2. MFN siparişleri - Siparişler gönderildiğinde envanter otomatik olarak azalır
  3. Listeleme güncellemeleri - Listelemeler API'si aracılığıyla miktarı ayarlayın

FBA için gönderim planları oluşturun:

const createInboundShipmentPlan = async (accessToken, shipmentData) => {
  const endpoint = 'https://sellingpartnerapi-na.amazon.com/fba/inbound/v0/plans';

  const payload = {
    ShipFromAddress: {
      Name: shipmentData.shipFromName,
      AddressLine1: shipmentData.shipFromAddress,
      City: shipmentData.shipFromCity,
      StateOrProvinceCode: shipmentData.shipFromState,
      CountryCode: shipmentData.shipFromCountry,
      PostalCode: shipmentData.shipFromPostalCode
    },
    LabelPrepPreference: 'SELLER_LABEL',
    InboundPlanItems: shipmentData.items.map(item => ({
      SellerSKU: item.sku,
      ASIN: item.asin,
      Quantity: item.quantity,
      Condition: 'NewItem'
    }))
  };

  return makeSpApiRequest('POST', endpoint, accessToken, payload);
};

Listelemeler API'si

Listelemeleri Alma

Filtrelemeyle ürün listelemelerini alın:

const getListings = async (accessToken, options = {}) => {
  const params = new URLSearchParams({
    marketplaceIds: options.marketplaceIds?.join(',') || ['ATVPDKIKX0DER'],
    itemTypes: options.itemTypes?.join(',') || ['ASIN', 'SKU'],
    identifiers: options.identifiers?.join(',') || '',
    issuesLocale: options.locale || 'en_US'
  });

  const endpoint = `https://sellingpartnerapi-na.amazon.com/listings/2021-08-01/items?${params.toString()}`;

  return makeSpApiRequest('GET', endpoint, accessToken);
};

// Kullanım
const listings = await getListings(accessToken, {
  identifiers: ['B08N5WRWNW', 'B09JQKJXYZ'],
  itemTypes: ['ASIN']
});

Listeleme Yanıt Yapısı

{
  "identifiers": {
    "marketplaceId": "ATVPDKIKX0DER",
    "sku": "MYSKU-001",
    "asin": "B08N5WRWNW"
  },
  "attributes": {
    "title": "Kablosuz Bluetooth Kulaklıklar",
    "description": "Gürültü önleyici özellikli premium kablosuz kulaklıklar",
    "brand": "Markam",
    "color": "Siyah",
    "size": "Tek Beden",
    "item_weight": "0.5 pound",
    "product_dimensions": "7 x 6 x 3 inç"
  },
  "product_type": "LUGGAGE",
  "sales_price": {
    "currency_code": "USD",
    "amount": "89.99"
  },
  "list_price": {
    "currency_code": "USD",
    "amount": "129.99"
  },
  "fulfillment_availability": [
    {
      "fulfillment_channel_code": "AFN",
      "quantity": 150
    }
  ],
  "condition_type": "New",
  "status": "ACTIVE",
  "procurement": null
}

Listelemeler Oluşturma veya Güncelleme

Toplu işlemler için submitListingsSubmission kullanın:

const submitListingUpdate = async (accessToken, listingData) => {
  const endpoint = 'https://sellingpartnerapi-na.amazon.com/listings/2021-08-01/items/MYSKU-001';

  const payload = {
    productType: 'LUGGAGE',
    patches: [
      {
        op: 'replace',
        path: '/attributes/title',
        value: 'Güncellenmiş Kablosuz Bluetooth Kulaklıklar - Premium Ses'
      },
      {
        op: 'replace',
        path: '/salesPrice',
        value: {
          currencyCode: 'USD',
          amount: '79.99'
        }
      }
    ]
  };

  return makeSpApiRequest('PATCH', endpoint, accessToken, payload);
};

Bir Listelemeyi Silme

Bir listelemeyi kaldırın veya devre dışı bırakın:

const deleteListing = async (accessToken, sku, marketplaceIds) => {
  const params = new URLSearchParams({
    marketplaceIds: marketplaceIds.join(',')
  });

  const endpoint = `https://sellingpartnerapi-na.amazon.com/listings/2021-08-01/items/${sku}?${params.toString()}`;

  return makeSpApiRequest('DELETE', endpoint, accessToken);
};

Raporlar API'si

Rapor Programları Oluşturma

Rapor oluşturmayı otomatikleştirin:

const createReport = async (accessToken, reportType, dateRange) => {
  const endpoint = 'https://sellingpartnerapi-na.amazon.com/reports/2021-06-30/reports';

  const payload = {
    reportType: reportType,
    marketplaceIds: dateRange.marketplaceIds || ['ATVPDKIKX0DER'],
    dataStartTime: dateRange.startTime?.toISOString(),
    dataEndTime: dateRange.endTime?.toISOString()
  };

  return makeSpApiRequest('POST', endpoint, accessToken, payload);
};

// Yaygın rapor türleri
const REPORT_TYPES = {
  ORDERS: 'GET_FLAT_FILE_ALL_ORDERS_DATA_BY_LAST_UPDATE_GENERAL',
  ORDER_ITEMS: 'GET_FLAT_FILE_ORDER_ITEMS_DATA_BY_LAST_UPDATE_GENERAL',
  INVENTORY: 'GET_MERCHANT_LISTINGS_ALL_DATA',
  FBA_INVENTORY: 'GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA',
  SETTLEMENT: 'GET_V2_SETTLEMENT_REPORT_DATA_FLAT_FILE',
  SALES_AND_TRAFFIC: 'GET_SALES_AND_TRAFFIC_REPORT',
  ADVERTISING: 'GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT'
};

// Kullanım
const report = await createReport(accessToken, REPORT_TYPES.ORDERS, {
  marketplaceIds: ['ATVPDKIKX0DER'],
  startTime: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // Son 7 gün
  endTime: new Date()
});

Rapor Belgesini Alma

Oluşturulan raporu indirin:

const getReportDocument = async (accessToken, reportId) => {
  const endpoint = `https://sellingpartnerapi-na.amazon.com/reports/2021-06-30/reports/${reportId}/document`;

  return makeSpApiRequest('GET', endpoint, accessToken);
};

// Raporu indir ve ayrıştır
const downloadReport = async (accessToken, reportId) => {
  const documentInfo = await getReportDocument(accessToken, reportId);

  const response = await fetch(documentInfo.payload.url);
  const content = await response.text();

  // Raporlar genellikle sekme ayrılmış veya JSON'dur
  if (documentInfo.payload.compressionAlgorithm === 'GZIP') {
    const decompressed = await decompressGzip(content);
    return decompressed;
  }

  return content;
};

Bildirimler API'si

Abonelikler Oluşturma

Gerçek zamanlı olaylar için webhook'lar ayarlayın:

const createSubscription = async (accessToken, subscriptionData) => {
  const endpoint = 'https://sellingpartnerapi-na.amazon.com/notifications/v1/subscriptions';

  const payload = {
    payload: {
      destination: {
        resource: subscriptionData.destinationArn, // SNS konu ARN'si
        name: subscriptionData.name
      },
      modelVersion: '1.0',
      eventFilter: {
        eventCode: subscriptionData.eventCode,
        marketplaceIds: subscriptionData.marketplaceIds
      }
    }
  };

  return makeSpApiRequest('POST', endpoint, accessToken, payload);
};

// Mevcut olay türleri
const EVENT_CODES = {
  ORDER_STATUS_CHANGE: 'OrderStatusChange',
  ORDER_ITEM_CHANGE: 'OrderItemChange',
  ORDER_CHANGE: 'OrderChange',
  FBA_ORDER_STATUS_CHANGE: 'FBAOrderStatusChange',
  FBA_OUTBOUND_SHIPMENT_STATUS: 'FBAOutboundShipmentStatus',
  INVENTORY_LEVELS: 'InventoryLevels',
  PRICING_HEALTH: 'PricingHealth'
};

// Kullanım
await createSubscription(accessToken, {
  destinationArn: 'arn:aws:sns:us-east-1:123456789012:sp-api-notifications',
  name: 'OrderStatusNotifications',
  eventCode: EVENT_CODES.ORDER_STATUS_CHANGE,
  marketplaceIds: ['ATVPDKIKX0DER']
});

SNS Hedefi Kurulumu

Amazon, bildirimleri SNS konularına gönderir:

const createSnsDestination = async (accessToken, destinationData) => {
  const endpoint = 'https://sellingpartnerapi-na.amazon.com/notifications/v1/destinations';

  const payload = {
    resource: destinationData.snsTopicArn,
    name: destinationData.name
  };

  return makeSpApiRequest('POST', endpoint, accessToken, { payload });
};

// SNS konu politikası Amazon SES'in yayınlamasına izin vermelidir
const snsTopicPolicy = {
  Version: '2012-10-17',
  Statement: [
    {
      Effect: 'Allow',
      Principal: {
        Service: 'notifications.amazon.com'
      },
      Action: 'SNS:Publish',
      Resource: 'arn:aws:sns:us-east-1:123456789012:sp-api-notifications'
    }
  ]
};

Bildirimleri İşleme

Bildirimleri almak için bir SNS uç noktası ayarlayın:

const express = require('express');
const crypto = require('crypto');
const app = express();

app.post('/webhooks/amazon', express.raw({ type: 'application/json' }), async (req, res) => {
  const signature = req.headers['x-amz-sns-message-signature'];
  const payload = req.body;

  // SNS mesaj imzasını doğrula
  const isValid = await verifySnsSignature(payload, signature);

  if (!isValid) {
    console.error('Geçersiz SNS imzası');
    return res.status(401).send('Yetkisiz');
  }

  const message = JSON.parse(payload.toString());

  // Farklı mesaj türlerini işle
  switch (message.Type) {
    case 'SubscriptionConfirmation':
      // Aboneliği otomatik onayla
      await fetch(message.SubscribeURL);
      break;
    case 'Notification':
      const notification = JSON.parse(message.Message);
      await handleSpApiNotification(notification);
      break;
  }

  res.status(200).send('OK');
});

async function handleSpApiNotification(notification) {
  const { notificationType, payload } = notification;

  switch (notificationType) {
    case 'OrderStatusChange':
      await syncOrderStatus(payload.amazonOrderId);
      break;
    case 'OrderChange':
      await syncOrderDetails(payload.amazonOrderId);
      break;
    case 'InventoryLevels':
      await updateInventoryCache(payload);
      break;
  }
}

Oran Sınırlama ve Kotalar

Oran Sınırlarını Anlamak

SP-API, uç noktaya göre dinamik oran sınırları uygular:

Uç Nokta Kategorisi Oran Sınırı Anlık Sınır
Siparişler saniyede 10 istek 20
Sipariş Öğeleri saniyede 5 istek 10
Envanter saniyede 2 istek 5
Listelemeler saniyede 10 istek 20
Raporlar saniyede 0.5 istek 1
Bildirimler saniyede 1 istek 2
FBA Gelen saniyede 2 istek 5

Mevcut limitler için yanıtlardaki x-amzn-RateLimit-Limit başlığını kontrol edin.

Oran Sınırı İşlemesini Uygulama

Yeniden denemeler için üstel geri çekilmeyi kullanın:

const makeRateLimitedRequest = async (method, endpoint, accessToken, body = null, maxRetries = 5) => {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await makeSpApiRequest(method, endpoint, accessToken, body);

      // Oran sınırı başlıklarını kontrol et
      const rateLimit = response.headers.get('x-amzn-RateLimit-Limit');
      const retryAfter = response.headers.get('Retry-After');

      if (retryAfter) {
        console.warn(`Oran sınırı aşıldı. Yeniden dene: ${retryAfter} saniye sonra`);
      }

      return response;
    } catch (error) {
      if (error.message.includes('429') && attempt < maxRetries) {
        // Yeniden dene başlığını çıkar veya üstel geri çekilme kullan
        const retryAfter = error.headers?.get('Retry-After') || Math.pow(2, attempt);
        console.log(`Oran sınırı aşıldı. ${retryAfter}s sonra yeniden deneniyor...`);
        await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      } else if (error.message.includes('503') && attempt < maxRetries) {
        // Hizmet kullanılamıyor - üstel geri çekilme
        const delay = Math.pow(2, attempt) * 1000;
        console.log(`Hizmet kullanılamıyor. ${delay}ms sonra yeniden deneniyor...`);
        await new Promise(resolve => setTimeout(resolve, delay));
      } else {
        throw error;
      }
    }
  }
};

İstek Kuyruklama Uygulaması

Sınırlar dahilinde kalmak için bir kuyruk uygulayın:

class RateLimitedQueue {
  constructor(rateLimit, burstLimit = null) {
    this.rateLimit = rateLimit; // saniye başına istek
    this.burstLimit = burstLimit || rateLimit * 2;
    this.tokens = this.burstLimit;
    this.lastRefill = Date.now();
    this.queue = [];
    this.processing = false;
  }

  async add(requestFn) {
    return new Promise((resolve, reject) => {
      this.queue.push({ requestFn, resolve, reject });
      this.process();
    });
  }

  refillTokens() {
    const now = Date.now();
    const elapsed = (now - this.lastRefill) / 1000;
    const tokensToAdd = elapsed * this.rateLimit;

    this.tokens = Math.min(this.burstLimit, this.tokens + tokensToAdd);
    this.lastRefill = now;
  }

  async process() {
    if (this.processing || this.queue.length === 0) return;

    this.processing = true;

    while (this.queue.length > 0) {
      this.refillTokens();

      if (this.tokens < 1) {
        const waitTime = (1 / this.rateLimit) * 1000;
        await new Promise(r => setTimeout(r, waitTime));
        continue;
      }

      this.tokens--;
      const { requestFn, resolve, reject } = this.queue.shift();

      try {
        const result = await requestFn();
        resolve(result);
      } catch (error) {
        reject(error);
      }
    }

    this.processing = false;
  }
}

// Kullanım - Siparişler API kuyruğu (10 istek/s)
const ordersQueue = new RateLimitedQueue(10, 20);
const orders = await ordersQueue.add(() => getOrders(accessToken, options));

Güvenlik En İyi Uygulamaları

Kimlik Bilgisi Yönetimi

Kimlik bilgilerini asla kaynak kodunuzda sabit kodlamayın. Ortam değişkenlerini veya bir sır yöneticisini kullanın:

// Kötü - asla yapmayın
const AWS_ACCESS_KEY = 'AKIAIOSFODNN7EXAMPLE';
const AWS_SECRET = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY';

// İyi - ortam değişkenlerini kullanın
const AWS_ACCESS_KEY = process.env.AWS_ACCESS_KEY_ID;
const AWS_SECRET = process.env.AWS_SECRET_ACCESS_KEY;

// Daha iyi - AWS Secrets Manager veya benzerini kullanın
const { SecretsManagerClient } = require('@aws-sdk/client-secrets-manager');
const secretsClient = new SecretsManagerClient({ region: 'us-east-1' });

const getCredentials = async () => {
  const response = await secretsClient.send({
    Name: 'prod/sp-api/credentials'
  });
  return JSON.parse(response.SecretString);
};

Belirteç Depolama Gereksinimleri

SP-API, belirteç depolaması için belirli güvenlik önlemleri gerektirir:

  1. Bekleyen verileri şifrele: Saklanan belirteçler için AES-256 şifrelemesi kullanın
  2. Aktarım sırasında şifrele: Her zaman HTTPS/TLS 1.2+ kullanın
  3. Erişim kontrolleri: Belirteç erişimini belirli hizmet hesaplarıyla sınırlayın
  4. Denetim kaydı: Tüm belirteç erişim ve yenileme olaylarını günlüğe kaydedin
  5. Otomatik döndürme: Süresi dolmadan önce belirteçleri yenileyin
const crypto = require('crypto');

class TokenStore {
  constructor(encryptionKey) {
    this.algorithm = 'aes-256-gcm';
    this.key = crypto.createHash('sha256').update(encryptionKey).digest('hex').slice(0, 32);
  }

  encrypt(token) {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv(this.algorithm, Buffer.from(this.key), iv);
    let encrypted = cipher.update(token, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    const authTag = cipher.getAuthTag().toString('hex');

    return {
      iv: iv.toString('hex'),
      encryptedData: encrypted,
      authTag
    };
  }

  decrypt(encryptedData) {
    const decipher = crypto.createDecipheriv(
      this.algorithm,
      Buffer.from(this.key),
      Buffer.from(encryptedData.iv, 'hex')
    );
    decipher.setAuthTag(Buffer.from(encryptedData.authTag, 'hex'));
    let decrypted = decipher.update(encryptedData.encryptedData, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
  }
}

IAM En Az Ayrıcalık

Uygulamanızın yalnızca ihtiyaç duyduğu izinleri verin:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "SPAPIOrdersAccess",
      "Effect": "Allow",
      "Action": "execute-api:Invoke",
      "Resource": "arn:aws:execute-api:*:*:*/prod/*/sellingpartnerapi/orders/*"
    },
    {
      "Sid": "SPAPIInventoryAccess",
      "Effect": "Allow",
      "Action": "execute-api:Invoke",
      "Resource": "arn:aws:execute-api:*:*:*/prod/*/sellingpartnerapi/fba/inventory/*"
    }
  ]
}

Üretimde * joker karakterlerini kullanmaktan kaçının. İzinleri belirli uç noktalara göre kapsamlandırın.

İstek İmzalama Güvenliği

SigV4 uygulamanızı her zaman doğrulayın:

  1. Tüm istekler için HTTPS kullanın
  2. İmzaya gerekli tüm başlıkları ekleyin
  3. Zaman damgalarının AWS sunucularının 5 dakika içinde olduğundan emin olun
  4. AWS kimlik bilgilerini düzenli olarak döndürün
  5. Mümkünse uzun vadeli kimlik bilgileri yerine IAM rolleri kullanın
// İstek zaman damgasını doğrula
const validateTimestamp = (amzDate) => {
  const now = new Date();
  const requestTime = new Date(amzDate);
  const diff = Math.abs(now - requestTime);

  // AWS, 5 dakikadan eski istekleri reddeder
  if (diff > 5 * 60 * 1000) {
    throw new Error('İstek zaman damgası çok eski. Sunucu saatinizi senkronize edin.');
  }
};

SP-API Entegrasyonlarını Apidog ile Test Etme

Neden SP-API Entegrasyonlarını Test Etmeliyiz?

Amazon SP-API entegrasyonları, karmaşık kimlik doğrulama akışları, birden fazla uç nokta ve katı oran sınırları içerir. Test etme size şunlarda yardımcı olur:

SP-API Testi için Apidog Kurulumu

Adım 1: SP-API OpenAPI Spesifikasyonunu İçe Aktar

Apidog, OpenAPI 3.0 spesifikasyonlarını destekler. Amazon'un SP-API spesifikasyonunu içe aktarın:

  1. Amazon deposundan SP-API OpenAPI spesifikasyonunu indirin
  2. Apidog'da yeni bir proje oluşturun
  3. Spesifikasyon dosyasını içe aktarın
  4. Kimlik bilgileri için ortam değişkenlerini yapılandırın

Adım 2: Ortam Değişkenlerini Yapılandırın

Ortama özgü değişkenleri ayarlayın:

Temel URL (Sandbox): https://sandbox.sellingpartnerapi-na.amazon.com
Temel URL (Üretim): https://sellingpartnerapi-na.amazon.com
LWA Erişim Belirteci: {{lwa_access_token}}
AWS Erişim Anahtarı: {{aws_access_key}}
AWS Gizli Anahtarı: {{aws_secret_key}}
Bölge: us-east-1

Adım 3: İstek Öncesi Komut Dosyaları Oluşturun

Apidog'un istek öncesi komut dosyalarıyla SigV4 imzalamayı otomatikleştirin:

// SigV4 imzalama için Apidog istek öncesi komut dosyası
const crypto = require('crypto');

const accessKey = apidog.variables.get('aws_access_key');
const secretKey = apidog.variables.get('aws_secret_key');
const accessToken = apidog.variables.get('lwa_access_token');
const region = apidog.variables.get('region');

const method = apidog.request.method;
const url = new URL(apidog.request.url);
const body = apidog.request.body;

// SigV4 imzasını oluştur
const signer = new SigV4Signer(accessKey, secretKey, region);
const signedHeaders = signer.sign(method, url.href, body, {
  'x-amz-access-token': accessToken
});

// İstek için başlıkları ayarla
apidog.request.headers = {
  ...apidog.request.headers,
  ...signedHeaders.headers
};

Adım 4: Test Senaryoları Oluşturun

Yaygın iş akışları için test senaryoları oluşturun:

// Test: Son 24 Saatten Siparişleri Al
// 1. OAuth kodunu belirteçle değiştir
// 2. GetOrders uç noktasını çağır
// 3. Yanıt yapısını doğrula
// 4. Sipariş kimliklerini çıkar
// 5. Her sipariş için GetOrderItems'ı çağır

const ordersResponse = await apidog.send({
  method: 'GET',
  url: '/orders/v0/orders',
  params: {
    createdAfter: new Date(Date.now() - 86400000).toISOString(),
    marketplaceIds: 'ATVPDKIKX0DER'
  }
});

apidog.assert(ordersResponse.status === 200, 'Sipariş isteği başarısız oldu');
apidog.assert(ordersResponse.data.payload.orders.length > 0, 'Sipariş bulunamadı');

// Sonraki istekler için sipariş kimliklerini sakla
const orderIds = ordersResponse.data.payload.orders.map(o => o.amazon_order_id);
apidog.variables.set('order_ids', JSON.stringify(orderIds));

SP-API Yanıtlarını Taklit Etme

Geliştirme sırasında SP-API yanıtlarını simüle etmek için Apidog'un akıllı taklit özelliğini kullanın:

// GetOrders için taklit yanıt
{
  "payload": {
    "orders": [
      {
        "amazon_order_id": "112-{{randomNumber}}-{{randomNumber}}",
        "order_status": "Unshipped",
        "purchase_date": "{{now}}",
        "order_total": {
          "currency_code": "USD",
          "amount": "{{randomFloat 10 500}}"
        }
      }
    ],
    "next_token": null
  }
}

Bu, ön uç geliştirmenin canlı Amazon uç noktalarına isabet etmeden ilerlemesini sağlar.

Yaygın Sorunları Ayıklama

Sorun: SigV4 İmza Uyuşmazlığı

Doğrulamak için Apidog'un istek denetleyicisini kullanın:

  1. Tüm gerekli başlıklar dahil edilmiş
  2. Başlıklar alfabetik olarak sıralanmış
  3. Kanonik istek AWS beklentileriyle eşleşiyor
  4. Zaman damgası geçerli aralıkta

Sorun: OAuth Belirteç Hataları

Basit bir istekle belirteç geçerliliğini kontrol edin:

const tokenCheck = await apidog.send({
  method: 'GET',
  url: '/orders/v0/orders',
  params: { createdAfter: new Date().toISOString() }
});

if (tokenCheck.status === 401) {
  console.log('Belirteç süresi doldu - yenileme gerekli');
  // Belirteç yenileme akışını tetikle
}

CI/CD'de Testleri Otomatikleştirme

Apidog testlerini CI/CD hattınıza entegre edin:

# GitHub Actions örneği
name: SP-API Entegrasyon Testleri

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Apidog Testlerini Çalıştır
        uses: apidog/test-action@v1
        with:
          project-id: ${{ secrets.APIDOG_PROJECT_ID }}
          api-key: ${{ secrets.APIDOG_API_KEY }}
          environment: sandbox

      - name: Başarısızlık Durumunda Bildirim Yap
        if: failure()
        run: |
          echo "SP-API testleri başarısız oldu - Apidog kontrol panelini kontrol edin"

Pazar Yeri Kimliği Referansı

Yaygın pazar yerleri için bu referansı elinizin altında bulundurun:

Ülke Pazar Yeri Kimliği
Amerika Birleşik Devletleri ATVPDKIKX0DER
Kanada A2EUQ1WTGCTBG2
Meksika A1AM78C64UM0Y8
Birleşik Krallık A1F83G8C2ARO7P
Almanya A1PA6795UKMFR9
Fransa A13V1IB3VIYZZH
İtalya APJ6JRA9NG5V4
İspanya A1RKKUPIHCS9HS
Japonya A1VC38T7YXB528
Avustralya A39IBJ37TRP1C6
Hindistan A21TJRUUN4KGV
Brezilya A2Q3Y263D00KWC

Yaygın Sorunları Giderme

Sorun: 403 Yetkisiz Hatası

Belirtiler: "Yetkisiz" veya "Erişim Reddedildi" hataları alma.

Teşhis:

const error = await response.json();
console.error('Kimlik doğrulama hatası:', error);
// Kontrol edin: InvalidSignature, AccessDenied, ExpiredToken

Çözümler:

  1. AWS kimlik bilgilerinin doğru ve etkin olduğunu doğrulayın
  2. IAM rolü ARN'sinin uygulamaya bağlı olduğunu kontrol edin
  3. OAuth belirtecinin süresinin dolmadığından emin olun
  4. SigV4 imzasının doğru bölgeyi içerdiğini onaylayın
  5. x-amz-access-token başlığının mevcut olduğunu doğrulayın

Sorun: 429 Oran Sınırı Aşıldı

Belirtiler: Sık sık HTTP 429 yanıtları alma.

Çözümler:

  1. Oran sınırlaması ile istek kuyruklama uygulayın
  2. Yeniden denemeler için üstel geri çekilmeyi kullanın
  3. Mümkün olduğunda istekleri toplu işleyin (sayfalama için next_token kullanın)
  4. x-amzn-RateLimit-Limit başlığını proaktif olarak izleyin
  5. Yüksek hacimli kullanım durumları için Satıcı Merkezi aracılığıyla daha yüksek limitler talep edin

Sorun: 404 Bulunamadı

Belirtiler: Geçerli uç noktalar 404 döndürüyor.

Çözümler:

  1. Doğru bölgesel uç noktayı kullandığınızı doğrulayın
  2. Pazar yeri kimliklerinin bölge için geçerli olduğunu kontrol edin
  3. Kaynağın (sipariş, listeleme) mevcut olduğunu onaylayın
  4. Yoldaki API sürümünün doğru olduğundan emin olun (örn., /v0/, /2021-08-01/)

Sorun: 400 Hatalı İstek

Belirtiler: İstek doğrulama hatalarıyla başarısız oluyor.

Yaygın Nedenler:

  1. Geçersiz tarih formatı: ISO 8601 formatını kullanın (2026-03-19T10:30:00Z)
  2. Eksik gerekli parametreler: Gerekli alanlar için API belgelerini kontrol edin
  3. Geçersiz pazar yeri kimliği: Doğru kimlikleri kullanın (örn., ABD için ATVPDKIKX0DER)
  4. Yanlış biçimlendirilmiş JSON: İstek gövdesi sözdizimini doğrulayın

Çözüm:

// Göndermeden önce tarihleri doğrula
const validateIsoDate = (dateString) => {
  const date = new Date(dateString);
  if (isNaN(date.getTime())) {
    throw new Error('Geçersiz ISO 8601 tarih formatı');
  }
  return dateString;
};

Sorun: Raporlar INIT_STATE'de Kalıyor

Belirtiler: Rapor asla DONE durumuna ulaşmıyor.

Çözümler:

  1. Daha uzun bekleyin - bazı raporlar 15-30 dakika sürer
  2. Rapor türünün hesabınız için kullanılabilir olduğunu kontrol edin
  3. Tarih aralığının çok büyük olmadığını doğrulayın (daha küçük aralıkları deneyin)
  4. Rapor durumunu sürekli değil, her 30 saniyede bir yoklayın
  5. Bazı rapor türleri belirli izinler gerektirir

Sorun: Bildirimler Gelmiyor

Belirtiler: Abonelikler oluşturuldu ancak bildirim alınmıyor.

Teşhis:

  1. API aracılığıyla abonelik durumunu kontrol edin
  2. SNS konu politikasının Amazon SES'e izin verdiğini doğrulayın
  3. Uç nokta URL'sinin herkese açık olduğunu onaylayın
  4. Teslimat denemeleri için CloudWatch günlüklerini kontrol edin

Çözümler:

  1. SNS konusunun doğru kaynak politikasına sahip olduğundan emin olun
  2. Geçerli SSL sertifikasıyla HTTPS uç noktasını doğrulayın
  3. Tüm bildirimler için 30 saniye içinde 200 OK döndürün
  4. SubscriptionConfirmation mesajlarını otomatik olarak onaylayın

Üretim Dağıtım Kontrol Listesi

Canlıya geçmeden önce:

İzleme ve Uyarı

Bu metrikleri izleyin:

const metrics = {
  apiCalls: {
    total: 0,
    successful: 0,
    failed: 0,
    rateLimited: 0
  },
  rateLimitUsage: {
    orders: { current: 0, limit: 10 },
    inventory: { current: 0, limit: 2 },
    listings: { current: 0, limit: 10 }
  },
  oauthTokens: {
    active: 0,
    expiring_soon: 0,
    refresh_failures: 0
  },
  notifications: {
    received: 0,
    processed: 0,
    failed: 0
  },
  reports: {
    pending: 0,
    completed: 0,
    failed: 0
  }
};

// Yüksek hata oranında uyarı
const failureRate = metrics.apiCalls.failed / metrics.apiCalls.total;

if (failureRate > 0.05) { // %5'ten fazla hata oranı
  sendAlert('SP-API hata oranı %5 üzerinde');
}

// Oran limitine yaklaşırken uyarı
for (const [endpoint, usage] of Object.entries(metrics.rateLimitUsage)) {
  if (usage.current / usage.limit > 0.8) {
    sendAlert(`${endpoint} oran limiti %80 kapasitede`);
  }
}

Gerçek Dünya Kullanım Alanları

Çoklu Pazar Yeri Envanter Senkronizasyonu

Global bir elektronik satıcısı, 12 pazar yerinde envanteri senkronize etmek için SP-API kullanıyor:

Uygulama akışı:

  1. InventoryLevels olayında SNS bildirimi tetiklenir
  2. Merkezi sistem yeni miktarları hesaplar
  3. Oran sınırlı API çağrıları her pazar yerini günceller
  4. Onay denetim veritabanına kaydedilir

Otomatik Sipariş Gönderimi

Üçüncü taraf bir lojistik sağlayıcı, sipariş işlemeyi otomatikleştirir:

Temel entegrasyon noktaları:

Analitik Kontrol Paneli

Bir satıcı analitik aracı, 500'den fazla satıcı hesabındaki verileri toplar:

SP-API aracılığıyla toplanan veriler:

Sonuç

Amazon SP-API, eski MWS'ye göre geliştirilmiş güvenlik ve performansla Satıcı Merkezi işlevlerine kapsamlı erişim sağlar. Temel çıkarımlar:

button

SSS Bölümü

Amazon SP-API Nedir?

Amazon Satış Ortağı API'si (SP-API), siparişler, envanter, listelemeler ve raporlar dahil olmak üzere Satıcı Merkezi verilerine programlı erişim sağlayan REST tabanlı bir API'dir. Eski MWS sisteminin yerini, OAuth 2.0 ve AWS SigV4 imzalama aracılığıyla geliştirilmiş güvenlikle almıştır.

Amazon SP-API kimlik bilgilerini nasıl alırım?

Uygulamanızı Satıcı Merkezi'nde Uygulamalar ve Hizmetler > Uygulamalar Geliştir altında kaydedin. Bir İstemci Kimliği, İstemci Sırrı ve Uygulama Kimliği alacaksınız. Ayrıca AWS'de bir IAM rolü oluşturmanız ve bunu uygulamanıza bağlamanız gerekir.

Amazon SP-API'yi kullanmak ücretsiz mi?

Evet, SP-API erişimi kayıtlı Amazon satıcıları için ücretsizdir. Ancak, oran sınırları geçerlidir ve uç noktaya göre değişir (saniyede 0,5 ila 100 istek). Daha yüksek limitler, belirli yüksek hacimli kullanım durumları için Amazon'dan onay gerektirir.

SP-API hangi kimlik doğrulamasını kullanır?

SP-API, yetkilendirme için OAuth 2.0'ı, erişim kontrolü için ise AWS IAM rollerini kullanır. Tüm API istekleri, OAuth akışı aracılığıyla elde edilen geçici kimlik bilgileriyle AWS İmza Sürüm 4 (SigV4) imzalama gerektirir.

SP-API oran sınırlarını nasıl hallederim?

Uç nokta başına sınırlar dahilinde kalmak için istek kuyruklama uygulayın. Kullanımı izlemek için x-amzn-RateLimit-Limit başlığını izleyin. HTTP 429 (Çok Fazla İstek) yanıtları alırken üstel geri çekilmeyi kullanın. Farklı uç noktaların farklı limitleri vardır.

Canlı bir satıcı hesabı olmadan SP-API'yi test edebilir miyim?

Evet. Amazon, SP-API geliştirme için bir sanal alan ortamı sağlar. Entegrasyonları canlı satıcı verilerini etkilemeden test etmek için uygulamanızı sanal alan modunda kaydedin. Tüm uç noktaların sanal alanda mevcut olmadığını unutmayın.

Webhook'lar SP-API ile nasıl çalışır?

SP-API, bildirimler için Amazon SNS kullanır. Belirli olay türleri (siparişler, envanter vb.) için bir abonelik oluşturun, bir SNS konusu yapılandırın ve bildirimleri almak için bir HTTPS uç noktası uygulayın. Abonelik mesajlarını otomatik olarak onaylayın.

OAuth belirtecinin süresi dolduğunda ne olur?

LWA erişim belirteçlerinin süresi 1 saat sonra dolar. Süre dolmadan önce yeni bir erişim belirteci almak için yenileme belirtecini kullanın. API çağrıları sırasında kimlik doğrulama hatalarını önlemek için ara yazılımınızda otomatik belirteç yenileme uygulayın.

MWS'den SP-API'ye nasıl geçiş yaparım?

MWS'nin kullanımdan kaldırılması Aralık 2025 için planlanmıştır. Geçiş şunları gerektirir: MWS belirteçlerinden OAuth 2.0'a kimlik doğrulamasını güncelleme, SigV4 imzalamayı uygulama, uç nokta URL'lerini güncelleme ve istek/yanıt ayrıştırmayı XML'den JSON'a değiştirme.

Neden 403 Yetkisiz hataları alıyorum?

Yaygın nedenler şunlardır: süresi dolmuş OAuth belirteci, yanlış IAM rolü yapılandırması, geçersiz SigV4 imzası, eksik x-amz-access-token başlığı veya IAM rolünün uygulamaya bağlı olmaması. Belirli hata kodları için hata yanıtı ayrıntılarını kontrol edin.

API Tasarım-Öncelikli Yaklaşımı Apidog'da Uygulayın

API'leri oluşturmanın ve kullanmanın daha kolay yolunu keşfedin

Amazon SP API Entegrasyonu: Adım Adım Rehber