Ürün Oluşturma
Mağazaya yeni ürün ekler. Ürün taslak olarak oluşur, satışa çıkması Milagron onay sürecinden sonra gerçekleşir.
Gerekli yetki:
product:write
Endpoint
POST /integration/product/sellers/{sellerId}/products
Production
https://api.milagron.com/integration/product/sellers/{sellerId}/products
Stage
Yakında
ID tabanlı referanslar: Marka, kategori ve özellik (attribute) alanlarının tamamı
isim değil ID ile gönderilir. Geçerli ID'leri
Katalog & ID Keşfi uçlarından alın.
Tek kategori ID'si. Ürün, kategori ağacının yaprak seviyesine açılır ve istekte
yalnızca
categoryId gönderilir; alt ve ana kategori sunucu tarafında türetilir.
Ağacın tamamı tek çağrıda gelir: GET .../categories.
Özellikler kategoriye bağlıdır. Bir üründe kullanılabilecek özellikler, seçilen
categoryId için tanımlanmış eşlemeyle sınırlıdır. İstek gövdesini kurgulamadan önce
Kategori Özellikleri
(GET .../categories/{categoryId}/attributes) ucunu çağırın.
İstek Gövdesi
Üst Düzey Alanlar
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
title | string | Evet | Ürün başlığı (en fazla 255 karakter). |
description | string | Evet | Ürün açıklaması (HTML desteklenir). |
brandId | integer | Evet | Marka ID'si. GET .../brands ile alınır; satıcıya tanımlı olmalıdır. |
categoryId | integer | Evet | Tek kategori alanı. Kategori ağacının yaprak seviyesi ("leaf": true). Alt ve ana kategori sunucu tarafında ağaçtan türetilir. Ürünün özellikleri ve KDV oranları buna bağlıdır. Eski ad productTypeId hâlâ kabul edilir. |
taxRate | integer | Evet | KDV oranı. Yaprak kategorinin taxRates listesindeki değerlerden biri olmalıdır. |
deliveryOptions | object | Evet | minDeliveryDays ve maxDeliveryDays (gün, 0 ≤ min ≤ max ≤ 365). |
images | array | Evet | Görsel URL listesi (en az 1, en fazla 50). "https://..." veya { "url": "https://..." } biçiminde. |
variants | array | Evet | Varyant listesi (en az 1, en fazla 100). Ürünün özellikleri bu listeden türetilir; aşağıya bakın. |
sizeChart | object | Hayır | Beden tablosu (ör. { "type": "html", "content": "<table>..." }). |
Varyant Alanları
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
barcode | string | Evet | Barkod (en fazla 100 karakter). Sistem genelinde benzersiz olmalıdır. |
stockCode | string | Evet | SKU (en fazla 100 karakter). Sistem genelinde benzersiz olmalıdır. |
stock | integer | Evet | Stok adedi (≥ 0). |
price.salePrice | number | Evet | Satış fiyatı (> 0). |
price.listPrice | number | Hayır | Liste (indirim öncesi) fiyatı. 0, boş veya satış fiyatına eşitse indirimsiz kabul edilir. |
attributes | array | Koşullu | Varyantın özellik değerleri: { "attributeId": x, "attributeValueId": y }. Ürünün kullandığı özellikler bu alandan türetilir; tüm varyantlar aynı özellik kümesini bildirmelidir. Tek varyantlı üründe boş bırakılır veya hiç gönderilmez. |
Ürün seviyesinde ayrı bir
attributes listesi gönderilmez. Ürünün hangi
özellikleri kullandığı varyantlardan çıkarılır. Seçenek sırası (varyant adı "Siyah / S"
ve vitrindeki seçenek sırası) kategori özellik sırasından
gelir; istekteki JSON sırası sonucu etkilemez.
Örnek İstek
{
"title": "Pamuklu Basic Tişört",
"description": "<p>%100 pamuk, rahat kesim.</p>",
"brandId": 5,
"categoryId": 12,
"taxRate": 18,
"deliveryOptions": { "minDeliveryDays": 1, "maxDeliveryDays": 5 },
"images": [
"https://cdn.ornek.com/tisort-1.jpg",
"https://cdn.ornek.com/tisort-2.jpg"
],
"variants": [
{
"barcode": "8691234567890",
"stockCode": "TSRT-SYH-S",
"stock": 25,
"price": { "salePrice": 299.90, "listPrice": 449.90 },
"attributes": [
{ "attributeId": 3, "attributeValueId": 15 },
{ "attributeId": 7, "attributeValueId": 41 }
]
},
{
"barcode": "8691234567891",
"stockCode": "TSRT-SYH-M",
"stock": 30,
"price": { "salePrice": 299.90, "listPrice": 449.90 },
"attributes": [
{ "attributeId": 3, "attributeValueId": 15 },
{ "attributeId": 7, "attributeValueId": 42 }
]
}
]
}
Yanıt (201)
{
"contentId": 4567,
"productMainId": "9876543210123",
"status": "notOnSale",
"title": "Pamuklu Basic Tişört",
"brand": { "id": 5, "name": "Marka Adı" },
"mainCategory": { "id": 7, "name": "Giyim" },
"subCategory": { "id": 37, "name": "Tişört" },
"category": { "id": 12, "name": "Basic Tişört", "leaf": true },
"taxRate": 18,
"variants": [
{ "name": "Siyah / S", "barcode": "8691234567890", "stockCode": "TSRT-SYH-S" },
{ "name": "Siyah / M", "barcode": "8691234567891", "stockCode": "TSRT-SYH-M" }
]
}
| Alan | Açıklama |
|---|---|
contentId | Milagron sistemindeki ürün kaydı ID'si. |
productMainId | Ürün ana kimliği. Ürün Listesi ucunda productMainId filtresi ile sorgulanabilir. |
status | Yeni ürün her zaman taslaktır ve notOnSale döner. Onay sürecinden sonra satışa alınır. |
category | Ürünün açıldığı yaprak kategori, yani istekteki categoryId. Üst seviyeler mainCategory ve subCategory alanlarında döner. |
variants[].name | Özellik değerlerinden üretilen varyant adı, örneğin "Siyah / S". Özellik kullanılmayan ürünlerde tek varyant oluşur ve adı Default Title olur. |
İşlem Garantisi
Ürün oluşturma ya hep ya hiç ilkesiyle çalışır.
201 yanıtı, ürünün
eksiksiz oluşturulduğu anlamına gelir. Herhangi bir adım başarısız olursa o ana kadar
yapılan işlemler geri alınır ve hata yanıtı döner, yarım ürün oluşmaz. Hata yanıtı alan
istekler güvenle yeniden denenebilir.
Doğrulama Kuralları
categoryId, kategori ağacının yaprak seviyesinden olmalıdır ("leaf": true); ara seviye ID'leri kabul edilmez.taxRate, yaprak kategorinin izin verdiği oranlardan biri olmalıdır (kategori ağacındakitaxRates).- Aynı özellik değer kombinasyonu birden fazla varyantta kullanılamaz.
barcodevestockCode, hem istek içinde hem sistem genelinde (mevcut ve onay bekleyen ürünler dahil) benzersiz olmalıdır.- Markanın komisyon oranı tanımlı olmalıdır.
Özellik Kuralları
Aşağıdaki kurallar GET .../categories/{categoryId}/attributes yanıtına göre uygulanır ve Milagron panelindeki ürün ekleme akışıyla birebir aynıdır.
- Ürünün kullandığı özellikler varyantlardan türetilir; tüm varyantlar aynı
attributeIdkümesini bildirmelidir. - Her varyant, bildirdiği her özellik için geçerli bir
attributeValueIdvermelidir; değer ilgili özelliğe ait olmalıdır. - Kullanılan her
attributeId, seçilen yaprak kategoriye atanmış vevariant: trueolmalıdır. required: trueolan özelliklerin tamamı kullanılmalıdır.multiple: falseolan bir özellikte tüm varyantlar aynıattributeValueId'yi kullanmalıdır.- En fazla 3 özellik kullanılabilir.
- Kategorinin zorunlu özelliği yoksa varyant
attributesalanı boş bırakılabilir. Bu durumda yalnızca tek varyant gönderilebilir. variantless: trueolan kategorilerde özellik gönderilemez; ürün her zaman tek varyantlıdır.- Kategori için hiç özellik tanımlanmamışsa (boş
attributesyanıtı vevariantless: false) ürün oluşturulamaz.
Tek Varyantlı Ürün Örneği
Kategorinin zorunlu özelliği yoksa özellik göndermeden tek varyantlı ürün oluşturulabilir:
{
"title": "Seramik Vazo",
"description": "<p>El yapımı seramik vazo.</p>",
"brandId": 5,
"categoryId": 31,
"taxRate": 20,
"deliveryOptions": { "minDeliveryDays": 1, "maxDeliveryDays": 3 },
"images": ["https://cdn.ornek.com/vazo-1.jpg"],
"variants": [
{
"barcode": "8691234567900",
"stockCode": "VZO-001",
"stock": 12,
"price": { "salePrice": 499.90, "listPrice": 649.90 }
}
]
}
Bu ürün tek varyantlı, yani seçeneksiz oluşur.
Hata Yanıtları
| HTTP | Kod | Durum |
|---|---|---|
| 400 | BadRequest | Geçersiz JSON gövdesi. |
| 401 / 403 | Unauthorized / Forbidden | Kimlik doğrulama, yetki veya satıcı eşleşme hatası. |
| 404 | NotFound | Satıcı bulunamadı. |
| 409 | Conflict | Barkod veya SKU zaten kayıtlı. |
| 422 | ValidationError | Alan veya ID doğrulama hatası. Mesaj hangi alanın hatalı olduğunu belirtir. |
| 429 | TooManyRequests | Rate limit veya günlük varyant oluşturma limiti. Daha sonra tekrar deneyin. |
| 500 / 502 | InternalError / UpstreamError | Sunucu tarafı hata. Ürün oluşmaz; istek güvenle yeniden denenebilir. |
Kullanım Örnekleri
curl -u "API_KEY:API_SECRET" \
-X POST "https://api.milagron.com/integration/product/sellers/123/products" \
-H "Content-Type: application/json" \
-d '{
"title": "Pamuklu Basic Tişört",
"description": "<p>%100 pamuk, rahat kesim.</p>",
"brandId": 5,
"categoryId": 12,
"taxRate": 18,
"deliveryOptions": {
"minDeliveryDays": 1,
"maxDeliveryDays": 5
},
"images": [
"https://cdn.ornek.com/tisort-1.jpg"
],
"variants": [
{
"barcode": "8691234567890",
"stockCode": "TSRT-SYH-S",
"stock": 25,
"price": {
"salePrice": 299.9,
"listPrice": 449.9
},
"attributes": [
{
"attributeId": 3,
"attributeValueId": 15
},
{
"attributeId": 7,
"attributeValueId": 41
}
]
}
]
}'<?php
$ch = curl_init('https://api.milagron.com/integration/product/sellers/123/products');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => 'API_KEY:API_SECRET',
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'title' => 'Pamuklu Basic Tişört',
'description' => '<p>%100 pamuk, rahat kesim.</p>',
'brandId' => 5,
'categoryId' => 12,
'taxRate' => 18,
'deliveryOptions' => [
'minDeliveryDays' => 1,
'maxDeliveryDays' => 5
],
'images' => [
'https://cdn.ornek.com/tisort-1.jpg'
],
'variants' => [
[
'barcode' => '8691234567890',
'stockCode' => 'TSRT-SYH-S',
'stock' => 25,
'price' => [
'salePrice' => 299.9,
'listPrice' => 449.9
],
'attributes' => [
[
'attributeId' => 3,
'attributeValueId' => 15
],
[
'attributeId' => 7,
'attributeValueId' => 41
]
]
]
]
]),
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);const auth = Buffer.from('API_KEY:API_SECRET').toString('base64');
const res = await fetch('https://api.milagron.com/integration/product/sellers/123/products', {
method: 'POST',
headers: {
'Authorization': `Basic ${auth}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'Pamuklu Basic Tişört',
description: '<p>%100 pamuk, rahat kesim.</p>',
brandId: 5,
categoryId: 12,
taxRate: 18,
deliveryOptions: {
minDeliveryDays: 1,
maxDeliveryDays: 5
},
images: [
'https://cdn.ornek.com/tisort-1.jpg'
],
variants: [
{
barcode: '8691234567890',
stockCode: 'TSRT-SYH-S',
stock: 25,
price: {
salePrice: 299.9,
listPrice: 449.9
},
attributes: [
{
attributeId: 3,
attributeValueId: 15
},
{
attributeId: 7,
attributeValueId: 41
}
]
}
]
})
});
const data = await res.json();import requests
response = requests.post(
'https://api.milagron.com/integration/product/sellers/123/products',
auth=('API_KEY', 'API_SECRET'),
json={
'title': 'Pamuklu Basic Tişört',
'description': '<p>%100 pamuk, rahat kesim.</p>',
'brandId': 5,
'categoryId': 12,
'taxRate': 18,
'deliveryOptions': {
'minDeliveryDays': 1,
'maxDeliveryDays': 5
},
'images': [
'https://cdn.ornek.com/tisort-1.jpg'
],
'variants': [
{
'barcode': '8691234567890',
'stockCode': 'TSRT-SYH-S',
'stock': 25,
'price': {
'salePrice': 299.9,
'listPrice': 449.9
},
'attributes': [
{
'attributeId': 3,
'attributeValueId': 15
},
{
'attributeId': 7,
'attributeValueId': 41
}
]
}
]
}
)
response.raise_for_status()
data = response.json()package main
import (
"bytes"
"encoding/json"
"net/http"
)
func main() {
payload, _ := json.Marshal(map[string]interface{}{
"title": "Pamuklu Basic Tişört",
"description": "<p>%100 pamuk, rahat kesim.</p>",
"brandId": 5,
"categoryId": 12,
"taxRate": 18,
"deliveryOptions": map[string]interface{}{
"minDeliveryDays": 1,
"maxDeliveryDays": 5,
},
"images": []interface{}{
"https://cdn.ornek.com/tisort-1.jpg",
},
"variants": []interface{}{
map[string]interface{}{
"barcode": "8691234567890",
"stockCode": "TSRT-SYH-S",
"stock": 25,
"price": map[string]interface{}{
"salePrice": 299.9,
"listPrice": 449.9,
},
"attributes": []interface{}{
map[string]interface{}{
"attributeId": 3,
"attributeValueId": 15,
},
map[string]interface{}{
"attributeId": 7,
"attributeValueId": 41,
},
},
},
},
})
req, _ := http.NewRequest("POST", "https://api.milagron.com/integration/product/sellers/123/products", bytes.NewBuffer(payload))
req.SetBasicAuth("API_KEY", "API_SECRET")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}import java.net.URI;
import java.net.http.*;
import java.util.Base64;
HttpClient client = HttpClient.newHttpClient();
String auth = Base64.getEncoder()
.encodeToString("API_KEY:API_SECRET".getBytes());
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.milagron.com/integration/product/sellers/123/products"))
.header("Authorization", "Basic " + auth)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString("{\"title\":\"Pamuklu Basic Tişört\",\"description\":\"<p>%100 pamuk, rahat kesim.</p>\",\"brandId\":5,\"categoryId\":12,\"taxRate\":18,\"deliveryOptions\":{\"minDeliveryDays\":1,\"maxDeliveryDays\":5},\"images\":[\"https://cdn.ornek.com/tisort-1.jpg\"],\"variants\":[{\"barcode\":\"8691234567890\",\"stockCode\":\"TSRT-SYH-S\",\"stock\":25,\"price\":{\"salePrice\":299.9,\"listPrice\":449.9},\"attributes\":[{\"attributeId\":3,\"attributeValueId\":15},{\"attributeId\":7,\"attributeValueId\":41}]}]}"))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());require 'net/http'
require 'uri'
require 'json'
uri = URI('https://api.milagron.com/integration/product/sellers/123/products')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri)
request.basic_auth('API_KEY', 'API_SECRET')
request['Content-Type'] = 'application/json'
request.body = {
title: 'Pamuklu Basic Tişört',
description: '<p>%100 pamuk, rahat kesim.</p>',
brandId: 5,
categoryId: 12,
taxRate: 18,
deliveryOptions: {
minDeliveryDays: 1,
maxDeliveryDays: 5
},
images: [
'https://cdn.ornek.com/tisort-1.jpg'
],
variants: [
{
barcode: '8691234567890',
stockCode: 'TSRT-SYH-S',
stock: 25,
price: {
salePrice: 299.9,
listPrice: 449.9
},
attributes: [
{
attributeId: 3,
attributeValueId: 15
},
{
attributeId: 7,
attributeValueId: 41
}
]
}
]
}.to_json
response = http.request(request)
data = JSON.parse(response.body)using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
var client = new HttpClient();
var auth = Convert.ToBase64String(
Encoding.UTF8.GetBytes("API_KEY:API_SECRET"));
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", auth);
var content = new StringContent(
"{\"title\":\"Pamuklu Basic Tişört\",\"description\":\"<p>%100 pamuk, rahat kesim.</p>\",\"brandId\":5,\"categoryId\":12,\"taxRate\":18,\"deliveryOptions\":{\"minDeliveryDays\":1,\"maxDeliveryDays\":5},\"images\":[\"https://cdn.ornek.com/tisort-1.jpg\"],\"variants\":[{\"barcode\":\"8691234567890\",\"stockCode\":\"TSRT-SYH-S\",\"stock\":25,\"price\":{\"salePrice\":299.9,\"listPrice\":449.9},\"attributes\":[{\"attributeId\":3,\"attributeValueId\":15},{\"attributeId\":7,\"attributeValueId\":41}]}]}",
Encoding.UTF8,
"application/json");
var response = await client.PostAsync("https://api.milagron.com/integration/product/sellers/123/products", content);
var data = await response.Content.ReadAsStringAsync();Notlar
- Ürün taslak olarak oluşur; satışa çıkışını Milagron onay süreci belirler.
- Doğrulama kuralları Milagron panelindeki ürün ekleme ekranıyla aynıdır; API'den ve panelden oluşturulan ürünler aynı onay sürecine girer.
- Görseller verilen URL'lerden indirilir; URL'ler herkese açık erişilebilir olmalıdır.
- Stok ve fiyat güncellemeleri için Stok-Fiyat Güncelleme ucunu kullanın.
- Stage ortamında tüm doğrulamalar çalışır; ürün oluşturulmaz,
_simulatedişaretli yanıt döner.