Inveon Review Module — API Entegrasyon Kılavuzu

Hazırlayan: Inveon / Phantom
Versiyon: 1.0
Tarih: Nisan 2026
Ortam: UAT


İçindekiler

  1. Genel Bilgiler
  2. Kimlik Doğrulama & Ortak Header'lar
  3. HTTP Status Kodları & Hata Yapısı
  4. Modül Genel Akış
  5. PDP — Ürün Detay Sayfası
  6. Sipariş Detayı — "Ürünü Değerlendir" Butonu
  7. Değerlendirme Oluşturma
  8. Değerlendirmelerim Sayfası
  9. Referanslar

1. Genel Bilgiler

Özellik Değer
Base URL (UAT) https://api.uat.sneaksup.phantom.inveon.info/review/v1
Protokol HTTPS
İçerik Tipi application/json (dosya yükleme hariç)

Not: Tüm tarih/saat değerleri UTC olarak döner (2026-04-28T12:21:21.616303Z).


2. Kimlik Doğrulama & Ortak Header'lar

Her istekte aşağıdaki header'lar gönderilmelidir:

Header Zorunlu Açıklama Örnek
Authorization Bearer token Bearer {BEARER_TOKEN}
Language-Culture Dil/bölge kodu tr-TR, en-US
Content-Type Bazı endpoint'lerde JSON body gönderilen istekler application/json

Örnek:

Authorization: Bearer {BEARER_TOKEN}
Language-Culture: tr-TR

3. HTTP Status Kodları & Hata Yapısı

Status Durum Açıklama
200 OK Başarılı İstek başarıyla işlendi, response body dolu
204 No Content Başarılı İşlem başarılı, dönülecek içerik yok
400 Bad Request İstemci hatası Geçersiz veya eksik parametre / iş kuralı ihlali
401 Unauthorized Kimlik doğrulama hatası Token geçersiz veya eksik
403 Forbidden Yetki hatası Kullanıcının bu işlemi yapma yetkisi yok
404 Not Found Bulunamadı İstenen kaynak mevcut değil
500 Internal Server Error Sunucu hatası Beklenmeyen sunucu hatası

Hata Response Yapısı (400):

{
    "title": null,
    "message": "Review already exists.",
    "messages": [
        "Review already exists."
    ]
}

4. Modül Genel Akış

[Diagram]

5. PDP — Ürün Detay Sayfası

5.1 PDP Akış Diyagramı

[Diagram]

5.2 Ürün Özeti — GET /Review/ContentReviewsSummary

Ürün detay sayfasına girildiğinde ilk yüklenen endpoint. Ortalama puan, yorum sayısı, AI özeti ve soru analizlerini döner.

Endpoint: GET /Review/ContentReviewsSummary

Query Parametreleri:

Parametre Tip Zorunlu Açıklama
ContentId string Ürünün ProductId'si (VariantId değil)

Curl:

curl --location 'https://api.uat.sneaksup.phantom.inveon.info/review/v1/Review/ContentReviewsSummary?ContentId=11596' \
--header 'Authorization: Bearer {BEARER_TOKEN}' \
--header 'Language-Culture: tr-TR'

Response — 200 OK:

{
    "id": "11596",
    "aiCommentSummary": "Genel olarak, ürünün yüksek kalitesi ve zarif tasarımı...",
    "avgScore": 0,
    "avgPoint": 3.47,
    "reviewCount": 159,
    "commentCount": 148,
    "reviewStarPoints": [
        { "item1": 1, "item2": 10 },
        { "item1": 2, "item2": 46 },
        { "item1": 3, "item2": 28 },
        { "item1": 4, "item2": 26 },
        { "item1": 5, "item2": 33 }
    ],
    "questionAnalyses": [
        {
            "questionId": "08de0019-5b4c-4c0b-8dbc-d75a295ff59f",
            "questionText": "Ürün Üzerinize Nasıl Oldu?",
            "questionCode": "size_perception",
            "questionUnit": null,
            "questionMediaUrl": "",
            "questionShowOnContentSummary": true,
            "questionType": 3,
            "totalAnswers": 92,
            "answerStats": [
                { "answer": "Tam Oldu", "count": 18, "percentage": 19.6 },
                { "answer": "Çok Bol",  "count": 18, "percentage": 19.6 },
                { "answer": "Çok Dar",  "count": 20, "percentage": 21.7 },
                { "answer": "Biraz Bol","count": 20, "percentage": 21.7 },
                { "answer": "Biraz Dar","count": 16, "percentage": 17.4 }
            ],
            "optionStats": [
                { "optionId": "08de0019-5b6a-4e35-8dad-30eca496d37a", "weight": 0,   "answer": "Çok Dar",   "count": 20, "percentage": 21.7 },
                { "optionId": "08de0019-5b6b-40a6-8252-2f06781c16e7", "weight": 25,  "answer": "Biraz Dar", "count": 16, "percentage": 17.4 },
                { "optionId": "08de0019-5b6b-40f2-8d5a-d82c4e7cfe72", "weight": 50,  "answer": "Tam Oldu",  "count": 18, "percentage": 19.6 },
                { "optionId": "08de0019-5b6b-411c-85e0-e8d4c1194d61", "weight": 75,  "answer": "Biraz Bol", "count": 20, "percentage": 21.7 },
                { "optionId": "08de0019-5b6b-415a-8f3e-03fc2f6d978b", "weight": 100, "answer": "Çok Bol",   "count": 18, "percentage": 19.6 }
            ],
            "mostCommonAnswer": "Çok Dar",
            "mostCommonAnswerPercentage": 21.7,
            "mostCommonOptionAnswer": "Çok Dar",
            "mostCommonOptionAnswerPercentage": 21.7,
            "optionWeightedAverage": 50,
            "generatedInsight": "Kullanıcıların %22 kadarı 2 beden büyük alınmasını öneriyor."
        }
    ],
    "hasMediaReviews": false
}

Response Alanları:

Alan Tip Açıklama
id string ContentId (ProductId)
aiCommentSummary string|null AI tarafından üretilen yorum özeti. Boş veya null ise bu section gösterilmez. Belirli bir yorum sayısına ulaşılmadan üretilmez.
avgPoint decimal Ürünün 5 üzerinden ortalama puanı
reviewCount int Toplam değerlendirme (yıldız) sayısı
commentCount int Yorum metni içeren değerlendirme sayısı
reviewStarPoints array Her yıldız için verilen değerlendirme sayısı. item1 = yıldız değeri (1–5), item2 = o yıldızı veren kullanıcı sayısı
questionAnalyses array Sadece showOnContentSummary: true olan sorular gelir. Her biri için cevap dağılımı ve generatedInsight içerir
questionAnalyses[].generatedInsight string|null AI tarafından üretilen içgörü cümlesi. Boşsa gösterilmez
hasMediaReviews bool Ürüne ait fotoğraf/video içeren yorum olup olmadığı
avgScore decimal|null Yalnızca Inveon admin paneli tarafından kullanılır. Entegrasyonda kullanılmasına gerek yoktur.

5.3 Yorum Listesi — GET /Review/ContentReviews

Kullanıcı yorumları görüntülemek istediğinde sayfalı yorum listesini döner.

Endpoint: GET /Review/ContentReviews

Query Parametreleri:

Parametre Tip Zorunlu Açıklama Örnek
ContentId string Ürünün ProductId'si 11596
Page int Sayfa numarası (1'den başlar) 1
PageSize int Sayfa başına yorum sayısı 10
SortField string Sıralama alanı submittedAt
SortOrder string Sıralama yönü: asc veya desc desc

Curl:

curl --location 'https://api.uat.sneaksup.phantom.inveon.info/review/v1/Review/ContentReviews?ContentId=11596&Page=1&PageSize=10&SortField=submittedAt&SortOrder=desc' \
--header 'Authorization: Bearer {BEARER_TOKEN}' \
--header 'Language-Culture: tr-TR'

Response — 200 OK:

{
    "page": {
        "hasNext": true,
        "hasPrevious": false,
        "totalCount": 159,
        "totalPageCount": 16,
        "pageNumber": 1,
        "pageSize": 10
    },
    "items": [
        {
            "id": "3f8e3533-4250-11f1-8c69-deb967359f00",
            "contentId": "11596",
            "contentName": "{\"productId\": 11596, \"variantId\": 111028, \"modelNumber\": \"IM0542-100\"}",
            "contentDetail": {
                "productId": 11596,
                "modelNumber": "IM0542-100",
                "variantId": 111028
            },
            "comment": "Eh işte, ortalama bir ürün.",
            "point": 2,
            "pointAsString": "2",
            "approved": true,
            "rejected": false,
            "rejectReason": null,
            "waitingForApproval": false,
            "reviewerName": "Misafir Kullanıcı",
            "reviewerId": "60434",
            "maskReviewerInfo": false,
            "orderNumber": "TSTSNK928612",
            "purchaseNumber": "TSTSNK928612",
            "likeCount": 5,
            "dislikeCount": 0,
            "isCurrentUserLiked": false,
            "isCurrentUserDisliked": false,
            "isCurrentUserReported": false,
            "contentOption": "47",
            "source": 0,
            "submittedAt": "2025-10-08T15:46:25",
            "reviewFiles": [
                {
                    "id": "35ea348b-3d04-4e40-85ab-1af4c59247f2",
                    "contentType": "image/png",
                    "contentLength": 13272,
                    "fileName": "bc5c73a8-3c54-40b3-999a-ce133786a6ce.webp",
                    "fileUrl": "https://img-phantomsneaksup-test.sm.mncdn.com//media/review/bc5c73a8-3c54-40b3-999a-ce133786a6ce.webp",
                    "externalUrl": null
                }
            ],
            "questionAnswers": [
                {
                    "questionId": "08ddec89-b456-4d8a-8f83-07c0e7fc64c5",
                    "questionName": "Satın Alınan Beden",
                    "questionCode": "size",
                    "questionType": 1,
                    "answer": "47",
                    "selectedOptions": [],
                    "totalQuestionOptionCount": 0
                },
                {
                    "questionId": "08de0019-5b4c-4c0b-8dbc-d75a295ff59f",
                    "questionName": "Ürün Üzerinize Nasıl Oldu?",
                    "questionCode": "size_perception",
                    "questionType": 3,
                    "answer": "Çok Dar",
                    "selectedOptions": [
                        {
                            "optionId": "08de0019-5b6a-4e35-8dad-30eca496d37a",
                            "optionName": "Çok Dar"
                        }
                    ],
                    "totalQuestionOptionCount": 5
                }
            ]
        }
    ]
}

Önemli Notlar:

Alan Açıklama
page.hasNext true ise sonraki sayfa için tekrar istek atılabilir
reviewerName Kullanıcı anonimlik seçtiyse maskelenmiş gelir (M****** K********). Herhangi bir string manipülasyonu yapılmamalıdır, maskeleme sunucu tarafında yapılır
source 0 = Website/App, 1 = Trendyol. Trendyol kaynaklı yorumlarda (source: 1) "trendyol.com'dan alınmıştır" ifadesinin gösterilmesi yasal zorunluluktur
isCurrentUserLiked true ise kullanıcı bu yorumu zaten beğenmiş → "Beğen" butonu pasif olmalı
isCurrentUserDisliked true ise kullanıcı bu yorumu zaten beğenmemiş → "Beğenme" butonu pasif olmalı
isCurrentUserReported true ise kullanıcı bu yorumu zaten şikayet etmiş → "Şikayet" butonu pasif olmalı
contentName Yorumun ait olduğu ürünü tanımlayan JSON string. productId, modelNumber (Variant.ErpCode), variantId içerir
contentDetail contentName ile aynı bilgileri ayrıştırılmış nesne olarak içerir: productId, modelNumber (Variant.ErpCode), variantId
parentReviewId Şu an için kullanılmamaktadır (null gelir). Gelecekte yorum yanıtlama özelliği için ayrılmış alandır.
reviewFiles Yorum görselleri. fileUrl ile direkt CDN URL döner
contentOption Kullanıcının sipariş verdiği ürün seçeneği (ör: ayakkabı bedeni "47")
questionAnswers[].answer Soruya verilen cevabın metin karşılığı. Tüm soru tiplerinde dolu gelir
questionAnswers[].selectedOptions Seçim içeren sorularda (Select, MultiSelect, Bool, Rating) seçilen option(lar) gelir. Text ve Number tipindeki sorularda boş dizi ([]) olarak gelir

Kısıtlamalar:


5.4 Like / Dislike / Nötr — PATCH /Review/Like

Endpoint: PATCH /Review/Like

İşlem like değeri
Beğen (Like) true
Beğenme (Dislike) false
Geri al / Nötr null

Request Body:

{
    "like": true,
    "id": "{reviewId}",
    "userId": "{customerId}"
}
Alan Tip Zorunlu Açıklama
like bool|null true=like, false=dislike, null=nötr
id string (uuid) Yorumun id'si
userId string İşlemi yapan kullanıcının customerId'si

Curl — Like:

curl --location --request PATCH 'https://api.uat.sneaksup.phantom.inveon.info/review/v1/Review/Like' \
--header 'Authorization: Bearer {BEARER_TOKEN}' \
--header 'Language-Culture: tr-TR' \
--header 'Content-Type: application/json' \
--data '{
    "like": true,
    "id": "3f8e3533-4250-11f1-8c69-deb967359f00",
    "userId": "60381"
}'

Response — 200 OK:

true

5.5 Şikayet — PATCH /Review/Report

Endpoint: PATCH /Review/Report

Request Body:

{
    "reason": "Uygunsuz içerik",
    "id": "{reviewId}",
    "userId": "{customerId}"
}
Alan Tip Zorunlu Açıklama
reason string Şikayet nedeni
id string (uuid) Yorumun id'si
userId string İşlemi yapan kullanıcının customerId'si

Curl:

curl --location --request PATCH 'https://api.uat.sneaksup.phantom.inveon.info/review/v1/Review/Report' \
--header 'Authorization: Bearer {BEARER_TOKEN}' \
--header 'Language-Culture: tr-TR' \
--header 'Content-Type: application/json' \
--data '{
    "reason": "Uygunsuz içerik",
    "id": "3f8e3533-4250-11f1-8c69-deb967359f00",
    "userId": "60381"
}'

Response — 200 OK:

true

6. Sipariş Detayı — "Ürünü Değerlendir" Butonu

6.1 Buton Gösterim Akışı

[Diagram]

6.2 Geçerli Sipariş Statüleri — GET /Review/GetValidOrderItemStatusesForCreatingReview

"Ürünü Değerlendir" butonunun gösterilip gösterilmeyeceğini belirlemek için kullanılır. Response olarak yorum yapılabilir statü id listesi döner.

Endpoint: GET /Review/GetValidOrderItemStatusesForCreatingReview

Curl:

curl --location 'https://api.uat.sneaksup.phantom.inveon.info/review/v1/Review/GetValidOrderItemStatusesForCreatingReview' \
--header 'Authorization: Bearer {BEARER_TOKEN}' \
--header 'Language-Culture: tr-TR'

Response — 200 OK:

[9, 21]

Response dinamik olabilir ve zaman içinde değişebilir. Bu listeyi hard-code etmeyin, her oturumda veya uygulama başlangıcında çekip cache'leyin.

OrderItem statüsü bu listede yer almıyorsa "Ürünü Değerlendir" butonu gösterilmez.


6.3 Kullanıcı Yorum Kontrolü — GET /Review/UserReviews

Kullanıcının belirli bir siparişteki ürün için daha önce yorum yapıp yapmadığını kontrol eder.

Endpoint: GET /Review/UserReviews

Query Parametreleri (Kontrol için):

Parametre Tip Zorunlu Açıklama Örnek
reviewerId string Kullanıcının customerId'si 60381
ContentName string (JSON, URL-encoded) Ürün bilgileri (modelNumber = Variant.ErpCode) {"productId":11596,"modelNumber":"IM0542-100","variantId":111008}
PurchaseNumber string Sipariş numarası UATSNKS16160

ContentName değeri JSON string olup URL-encode edilmesi gerekir.

Curl:

curl --location --globoff 'https://api.uat.sneaksup.phantom.inveon.info/review/v1/Review/UserReviews?reviewerId=60381&ContentName={"productId"%3A11596%2C"modelNumber"%3A"IM0542-100"%2C"variantId"%3A111008}&PurchaseNumber=UATSNKS16160-1' \
--header 'Authorization: Bearer {BEARER_TOKEN}' \
--header 'Language-Culture: tr-TR'

Response — Yorum Yok — items: [] (Buton Gösterilir):

{
    "page": {
        "hasNext": false,
        "hasPrevious": false,
        "totalCount": 0,
        "totalPageCount": 0,
        "pageNumber": 0,
        "pageSize": 0
    },
    "items": []
}

Response — Yorum Var — items dolu (Buton Gizlenir):

{
    "page": {
        "hasNext": false,
        "hasPrevious": false,
        "totalCount": 1,
        "totalPageCount": 0,
        "pageNumber": 0,
        "pageSize": 0
    },
    "items": [
        {
            "id": "08dea520-a869-4805-805e-6f3b5dd6002a",
            "contentId": "11596",
            "contentName": "{\"productId\":11596,\"modelNumber\":\"IM0542-100\",\"variantId\":111008}",
            "contentDetail": {
                "productId": 11596,
                "modelNumber": "IM0542-100",
                "variantId": 111008
            },
            "comment": "Mükemmel ama koltuk kadar rahat değil 🤣",
            "point": 4,
            "pointAsString": "4",
            "approved": false,
            "rejected": false,
            "rejectReason": null,
            "waitingForApproval": true,
            "reviewerName": "Oğuzhan Durmaz",
            "reviewerId": "60381",
            "maskReviewerInfo": false,
            "orderNumber": "UATSNKS16160-1",
            "purchaseNumber": "UATSNKS16160-1",
            "parentReviewId": null,
            "avgScore": 8.0,
            "likeCount": 0,
            "dislikeCount": 0,
            "isCurrentUserLiked": false,
            "isCurrentUserDisliked": false,
            "isCurrentUserReported": false,
            "contentOption": "44",
            "source": 0,
            "submittedAt": "2026-04-28T12:21:21.616303",
            "reviewFiles": [
                {
                    "id": "5a098a08-fc79-417d-91f6-280056cb83e4",
                    "contentType": "image/png",
                    "contentLength": 133528,
                    "fileName": "6538ca00-a60e-468b-bc2a-216655ab3f59.webp",
                    "fileUrl": "https://img-phantomsneaksup-test.sm.mncdn.com//media/review/6538ca00-a60e-468b-bc2a-216655ab3f59.webp",
                    "externalUrl": null,
                    "reviewId": "08dea520-a869-4805-805e-6f3b5dd6002a"
                }
            ],
            "questionAnswers": [
                {
                    "questionId": "08ddec89-b456-4d8a-8f83-07c0e7fc64c5",
                    "questionName": "Satın Alınan Beden",
                    "questionCode": "size",
                    "questionType": 1,
                    "answer": "44",
                    "selectedOptions": [],
                    "totalQuestionOptionCount": 0
                },
                {
                    "questionId": "08dea51d-0a80-4d42-87ac-8436f83e4666",
                    "questionName": "Bizi Çevrenizdekilere Tavsiye Eder Misiniz?",
                    "questionCode": "recommendation",
                    "questionType": 5,
                    "answer": "Evet",
                    "selectedOptions": [
                        {
                            "optionId": "08dea51d-0a8d-42e2-8a5e-b03db21b77b7",
                            "optionName": "Evet"
                        }
                    ],
                    "totalQuestionOptionCount": 2
                },
                {
                    "questionId": "08de0019-b558-405b-8993-294fe190db61",
                    "questionName": "Hangi Süreçlerden Memnun Kaldınız?",
                    "questionCode": "processes_satisfaction",
                    "questionType": 4,
                    "answer": "Teslimat, Kalite",
                    "selectedOptions": [
                        { "optionId": "08de0019-b562-47ef-8732-4073b6664295", "optionName": "Teslimat" },
                        { "optionId": "08de0019-b562-4730-8a9b-51ad15a60e19", "optionName": "Kalite" }
                    ],
                    "totalQuestionOptionCount": 3
                },
                {
                    "questionId": "08dea51a-9672-43b9-89d2-74974d8e77f3",
                    "questionName": "Ayağınızı Sıktı Mı?",
                    "questionCode": "feet-fit",
                    "questionType": 3,
                    "answer": "Bi'tık sıktı.",
                    "selectedOptions": [
                        { "optionId": "08dea51a-9742-4a20-83c8-ed9ecb235ade", "optionName": "Bi'tık sıktı." }
                    ],
                    "totalQuestionOptionCount": 5
                },
                {
                    "questionId": "08de0019-8a05-4a31-8b88-beaed50e55ec",
                    "questionName": "Boyunuz",
                    "questionCode": "height",
                    "questionType": 2,
                    "answer": "184",
                    "selectedOptions": [],
                    "totalQuestionOptionCount": 0
                }
            ]
        }
    ]
}

Karar Mantığı: items.length > 0 ise kullanıcı bu ürünü bu sipariş için zaten değerlendirmiş → buton gizlenir. items boşsa buton gösterilir.


7. Değerlendirme Oluşturma

7.1 Değerlendirme Oluşturma Akışı

[Diagram]

7.2 Dinamik Sorular — GET /Question/GetByCategory

Değerlendirme formunda kullanıcıya gösterilecek kategori bazlı dinamik soruları döner.

Endpoint: GET /Question/GetByCategory

Query Parametreleri:

Parametre Tip Zorunlu Açıklama
CategoryIds int[] Ürünün bağlı olduğu kategori id'leri (birden fazla gönderilebilir)

Curl:

curl --location 'https://api.uat.sneaksup.phantom.inveon.info/review/v1/Question/GetByCategory?CategoryIds=1&CategoryIds=5&CategoryIds=11&CategoryIds=59' \
--header 'Authorization: Bearer {BEARER_TOKEN}' \
--header 'Language-Culture: tr-TR'

Response — Soru Yok ([] boş):

[]

Boş gelirse bu kategoriye özel soru tanımlı değil → sadece statik alanlarla (puan, yorum metni, fotoğraf) form gösterilir.

Response — Sorular Dolu:

[
    {
        "id": "08ddec89-b456-4d8a-8f83-07c0e7fc64c5",
        "name": "Satın Alınan Beden",
        "isRequired": true,
        "isReadOnly": true,
        "defaultValue": null,
        "minValue": null,
        "maxValue": null,
        "showOnContentSummary": false,
        "code": "size",
        "unit": null,
        "type": 1,
        "mediaUrl": null,
        "options": []
    },
    {
        "id": "08de0019-8a05-4a31-8b88-beaed50e55ec",
        "name": "Boyunuz",
        "isRequired": false,
        "isReadOnly": false,
        "defaultValue": null,
        "minValue": 110,
        "maxValue": 250,
        "showOnContentSummary": false,
        "code": "height",
        "unit": "cm",
        "type": 2,
        "mediaUrl": null,
        "options": []
    },
    {
        "id": "08de0019-b558-405b-8993-294fe190db61",
        "name": "Hangi Süreçlerden Memnun Kaldınız?",
        "isRequired": false,
        "isReadOnly": false,
        "defaultValue": null,
        "minValue": null,
        "maxValue": null,
        "showOnContentSummary": false,
        "code": "processes_satisfaction",
        "unit": null,
        "type": 4,
        "mediaUrl": null,
        "options": [
            { "id": "08de0019-b562-47a4-8695-182b79d4fb90", "name": "İletişim",  "displayOrder": 1,   "weight": 0, "isDefault": false },
            { "id": "08de0019-b562-47ef-8732-4073b6664295", "name": "Teslimat",  "displayOrder": 2,   "weight": 0, "isDefault": false },
            { "id": "08de0019-b562-4730-8a9b-51ad15a60e19", "name": "Kalite",    "displayOrder": 255, "weight": 0, "isDefault": false }
        ]
    },
    {
        "id": "08dea51a-9672-43b9-89d2-74974d8e77f3",
        "name": "Ayağınızı Sıktı Mı?",
        "isRequired": true,
        "isReadOnly": false,
        "defaultValue": null,
        "minValue": null,
        "maxValue": null,
        "showOnContentSummary": true,
        "code": "feet-fit",
        "unit": null,
        "type": 3,
        "mediaUrl": null,
        "options": [
            { "id": "08dea51a-9718-4701-8757-f856acf73898", "name": "Aşırı sıktı, kalıbı çok küçük.", "displayOrder": 0, "weight": 0,   "isDefault": false },
            { "id": "08dea51a-9742-4a20-83c8-ed9ecb235ade", "name": "Bi'tık sıktı.",                  "displayOrder": 1, "weight": 25,  "isDefault": false },
            { "id": "08dea51a-9742-4ab5-8624-3d16d0261107", "name": "Hiç sıkmadı, ideal.",            "displayOrder": 2, "weight": 50,  "isDefault": true  },
            { "id": "08dea51a-9742-4afd-8561-400ab2e0f471", "name": "Bi'tık bol oldu.",               "displayOrder": 3, "weight": 75,  "isDefault": false },
            { "id": "08dea51a-9742-4b45-8e92-026b57b4275d", "name": "Aşırı büyük, kalıbı çok bol.",  "displayOrder": 4, "weight": 100, "isDefault": false }
        ]
    },
    {
        "id": "08dea51d-0a80-4d42-87ac-8436f83e4666",
        "name": "Bizi Çevrenizdekilere Tavsiye Eder Misiniz?",
        "isRequired": true,
        "isReadOnly": false,
        "defaultValue": null,
        "minValue": null,
        "maxValue": null,
        "showOnContentSummary": false,
        "code": "recommendation",
        "unit": null,
        "type": 5,
        "mediaUrl": null,
        "options": [
            { "id": "08dea51d-0a8d-42e2-8a5e-b03db21b77b7", "name": "Evet", "displayOrder": 1,   "weight": 100, "isDefault": true  },
            { "id": "08dea51d-0a8d-41ae-86af-3969062ee819", "name": "Hayır","displayOrder": 255, "weight": 0,   "isDefault": false }
        ]
    }
]

Soru Alanları:

Alan Açıklama
type Soru tipi — bkz. QuestionType Enum
isRequired true ise cevap zorunludur
isReadOnly true ise kullanıcı bu soruyu değiştiremez, sadece görür
code Siparişten otomatik doldurulacak alan adı (aşağıya bkz.)
unit Varsa giriş birimi ("cm" gibi), UI'da gösterilebilir
defaultValue Text/Number tipi sorular için başlangıç değeri
options[].isDefault Select/MultiSelect/Bool/Rating'de önceden seçili option
minValue / maxValue Number tipinde: min/max değer. Text tipinde: min/max karakter sayısı

⚠️ Özel Durum — isReadOnly: true AND isRequired: true:

Bu kombinasyondaki sorular kullanıcı tarafından doldurulmaz, entegre olan sistem tarafından otomatik doldurulur. code alanı, sipariş detayı API'sindeki (get-order-with-all) ilgili orderItem property adına karşılık gelir.

Örnek: Eğer sipariş detayında "size": "47" varsa ve sorunun code değeri "size" ise → bu sorunun cevabı "47" olarak otomatik gönderilmelidir.

Soru Tipine Göre Cevap Gönderme:

QuestionType Cevap Alanı Örnek
Text (1) answer "answer": "Çok güzel"
Number (2) answer "answer": "184"
Select (3) answer + optionIds "answer": "{optionId}", "optionIds": ["{optionId}"]
MultiSelect (4) answer + optionIds "optionIds": ["{id1}", "{id2}"]
Bool (5) answer + optionIds "answer": "{optionId}", "optionIds": ["{optionId}"]
Rating (6) answer + optionIds "answer": "{optionId}", "optionIds": ["{optionId}"]

7.3 Medya Yükleme — POST /ReviewFile/Create

Kullanıcı yoruma fotoğraf veya video eklemek istediğinde önce bu endpoint çağrılır.

Endpoint: POST /ReviewFile/Create
Content-Type: multipart/form-data

Form Alanı Tip Zorunlu Açıklama
Media file Yüklenecek görsel veya video dosyası

Curl:

curl --location 'https://api.uat.sneaksup.phantom.inveon.info/review/v1/ReviewFile/Create' \
--header 'Authorization: Bearer {BEARER_TOKEN}' \
--header 'Language-Culture: tr-TR' \
--form 'Media=@"/path/to/image.png"'

Response — 200 OK:

{
    "id": "5a098a08-fc79-417d-91f6-280056cb83e4",
    "contentType": "image/png",
    "contentLength": 133528,
    "fileName": "6538ca00-a60e-468b-bc2a-216655ab3f59.webp",
    "fileUrl": "https://img-phantomsneaksup-test.sm.mncdn.com//media/review/6538ca00-a60e-468b-bc2a-216655ab3f59.webp",
    "externalUrl": null,
    "reviewId": "00000000-0000-0000-0000-000000000000",
    "createdAt": "2026-04-28T12:10:52.175045Z",
    "updatedAt": "2026-04-28T12:10:52.175045Z",
    "deletedAt": null,
    "deleted": false
}

Kritik: Response'daki id alanı bir sonraki adımda POST /Review/Create isteğinin reviewFileIds dizisine eklenerek dosyanın yorumla ilişkilendirilmesi sağlanır. Bu id değeri saklanmalıdır.

Dosya yükleme sonrası sunucu görseli webp formatına dönüştürebilir (fileName alanında görülebilir).


7.4 Değerlendirme Gönderme — POST /Review/Create

Tüm veriler toplandıktan sonra değerlendirme bu endpoint ile gönderilir.

Endpoint: POST /Review/Create

Request Body:

{
    "comment": "Mükemmel ama koltuk kadar rahat değil 🤣",
    "point": 4,
    "contentId": "11596",
    "contentName": "{\"productId\":11596,\"modelNumber\":\"IM0542-100\",\"variantId\":111008}",
    "contentOption": "44",
    "reviewerId": "60381",
    "reviewerName": "Ad Soyad",
    "maskReviewerInfo": false,
    "purchaseNumber": "UATSNKS16160-1",
    "orderItemStatus": 9,
    "reviewFileIds": [
        "5a098a08-fc79-417d-91f6-280056cb83e4"
    ],
    "questionAnswers": [
        {
            "questionId": "08ddec89-b456-4d8a-8f83-07c0e7fc64c5",
            "answer": "44"
        },
        {
            "questionId": "08de0019-8a05-4a31-8b88-beaed50e55ec",
            "answer": "184"
        },
        {
            "questionId": "08de0019-b558-405b-8993-294fe190db61",
            "answer": "08de0019-b562-47ef-8732-4073b6664295,08de0019-b562-4730-8a9b-51ad15a60e19",
            "optionIds": [
                "08de0019-b562-47ef-8732-4073b6664295",
                "08de0019-b562-4730-8a9b-51ad15a60e19"
            ]
        },
        {
            "questionId": "08dea51a-9672-43b9-89d2-74974d8e77f3",
            "answer": "08dea51a-9742-4a20-83c8-ed9ecb235ade",
            "optionIds": [
                "08dea51a-9742-4a20-83c8-ed9ecb235ade"
            ]
        },
        {
            "questionId": "08dea51d-0a80-4d42-87ac-8436f83e4666",
            "answer": "08dea51d-0a8d-42e2-8a5e-b03db21b77b7",
            "optionIds": [
                "08dea51d-0a8d-42e2-8a5e-b03db21b77b7"
            ]
        }
    ]
}

Request Alanları:

Alan Tip Zorunlu Açıklama
comment string Kullanıcının yorum metni
point int Yıldız puanı (1–5)
contentId string ProductId (VariantId değil)
contentName string (JSON) {"productId":..., "modelNumber":"...", "variantId":...} formatında JSON string. modelNumber = Variant.ErpCode
contentOption string Sipariş edilen ürün seçeneği (ör: beden "44")
reviewerId string Kullanıcının customerId'si
reviewerName string Kullanıcının adı soyadı
maskReviewerInfo bool true → ad/soyad diğer kullanıcılardan gizlenir (anonim)
purchaseNumber string Sipariş numarası. Aynı ürün birden fazla siparişle alınmış olabilir
orderItemStatus int Yorum anındaki OrderItemStatus değeri
reviewFileIds string[] POST /ReviewFile/Create'ten dönen id'ler. Boş dizi gönderilebilir
questionAnswers array Dinamik soruların cevapları. Bkz. soru tipine göre cevap tablosu

Curl:

curl --location 'https://api.uat.sneaksup.phantom.inveon.info/review/v1/Review/Create' \
--header 'Authorization: Bearer {BEARER_TOKEN}' \
--header 'Language-Culture: tr-TR' \
--header 'Content-Type: application/json' \
--data '{
    "comment": "Mükemmel ama koltuk kadar rahat değil 🤣",
    "point": 4,
    "contentId": "11596",
    "contentName": "{\"productId\":11596,\"modelNumber\":\"IM0542-100\",\"variantId\":111008}",
    "contentOption": "44",
    "reviewerId": "60381",
    "reviewerName": "Ad Soyad",
    "maskReviewerInfo": false,
    "purchaseNumber": "UATSNKS16160-1",
    "orderItemStatus": 9,
    "reviewFileIds": ["5a098a08-fc79-417d-91f6-280056cb83e4"],
    "questionAnswers": [
        {
            "questionId": "08ddec89-b456-4d8a-8f83-07c0e7fc64c5",
            "answer": "44"
        },
        {
            "questionId": "08de0019-8a05-4a31-8b88-beaed50e55ec",
            "answer": "184"
        },
        {
            "questionId": "08de0019-b558-405b-8993-294fe190db61",
            "answer": "08de0019-b562-47ef-8732-4073b6664295,08de0019-b562-4730-8a9b-51ad15a60e19",
            "optionIds": [
                "08de0019-b562-47ef-8732-4073b6664295",
                "08de0019-b562-4730-8a9b-51ad15a60e19"
            ]
        },
        {
            "questionId": "08dea51a-9672-43b9-89d2-74974d8e77f3",
            "answer": "08dea51a-9742-4a20-83c8-ed9ecb235ade",
            "optionIds": [
                "08dea51a-9742-4a20-83c8-ed9ecb235ade"
            ]
        },
        {
            "questionId": "08dea51d-0a80-4d42-87ac-8436f83e4666",
            "answer": "08dea51d-0a8d-42e2-8a5e-b03db21b77b7",
            "optionIds": [
                "08dea51d-0a8d-42e2-8a5e-b03db21b77b7"
            ]
        }
    ]
}'

Response — 400 Bad Request (Daha önce yorum yapılmış):

{
    "title": null,
    "message": "Review already exists.",
    "messages": ["Review already exists."]
}

Response — 200 OK (Başarılı):

{
    "id": "08dea520-a869-4805-805e-6f3b5dd6002a",
    "contentId": "11596",
    "contentName": "{\"productId\":11596,\"modelNumber\":\"IM0542-100\",\"variantId\":111008}",
    "contentDetail": {
        "productId": 11596,
        "modelNumber": "IM0542-100",
        "variantId": 111008
    },
    "comment": "Mükemmel ama koltuk kadar rahat değil 🤣",
    "point": 4,
    "pointAsString": "4",
    "approved": false,
    "waitingForApproval": true,
    "rejected": false,
    "rejectReason": null,
    "reviewerName": "Ad Soyad",
    "reviewerId": "60381",
    "maskReviewerInfo": false,
    "purchaseNumber": "UATSNKS16160-1",
    "source": 0,
    "reviewFiles": [],
    "questionAnswers": [],
    "submittedAt": "2026-04-28T12:21:21.616303Z",
    "createdAt": "2026-04-28T12:21:21.616303Z",
    "updatedAt": "2026-04-28T12:21:21.616303Z"
}

Not: Başarılı oluşturulan yorum approved: false, waitingForApproval: true olarak döner. Yorum moderasyon sürecine girer ve onaylandıktan sonra PDP'de görünür hale gelir.


8. Değerlendirmelerim Sayfası

GET /Review/UserReviews endpoint'i filtre parametreleriyle kullanılarak kullanıcının yorumları statüye göre listelenir.

Endpoint: GET /Review/UserReviews

Sayfa Query Parametreleri
Onay Bekleyen Yorumlarım ?reviewerId={id}&waitingForApproval=true
Onaylanmış Yorumlarım ?reviewerId={id}&approved=true
Reddedilmiş Yorumlarım ?reviewerId={id}&rejected=true

Curl — Onay Bekleyenler:

curl --location 'https://api.uat.sneaksup.phantom.inveon.info/review/v1/Review/UserReviews?reviewerId=60381&waitingForApproval=true' \
--header 'Authorization: Bearer {BEARER_TOKEN}' \
--header 'Language-Culture: tr-TR'

Curl — Onaylanmışlar:

curl --location 'https://api.uat.sneaksup.phantom.inveon.info/review/v1/Review/UserReviews?reviewerId=60381&approved=true' \
--header 'Authorization: Bearer {BEARER_TOKEN}' \
--header 'Language-Culture: tr-TR'

Curl — Reddedilenler:

curl --location 'https://api.uat.sneaksup.phantom.inveon.info/review/v1/Review/UserReviews?reviewerId=60381&rejected=true' \
--header 'Authorization: Bearer {BEARER_TOKEN}' \
--header 'Language-Culture: tr-TR'

Response yapısı GET /Review/ContentReviews ile aynıdır (sayfalı, page + items). Reddedilen yorumlarda rejectReason alanı dolabilir.


9. Referanslar

OrderItemStatus Enum

Değer Ad Açıklama
0 Test Test
1 New Yeni sipariş
2 Pending Beklemede
3 Processing İşlemde
4 ProcurementPrep Tedarik hazırlığı
5 Procurement Tedarik
6 NotProcured Tedarik edilemedi
7 Procured Tedarik edildi
8 Delivery Kargoda
9 Delivered Teslim edildi ✅ Yorum yapılabilir
10 DeliveredToStore Mağazaya teslim edildi
11 Cancelled İptal
12 PartialCancelled Kısmi iptal
13 Returned İade
14 PendingReturn İade bekliyor
15 DeniedReturn İade reddedildi
16 PendingReturnRefund İade iadesi bekliyor
17 ReturnRefunded İade iadesi yapıldı
18 DeniedReturnRefund İade iadesi reddedildi
19 PartialReturned Kısmi iade
20 ShippedToStore Mağazaya gönderildi
21 DeliveredToCustomerFromStore Mağazadan teslim alındı ✅ Yorum yapılabilir

✅ ile işaretlenenler mevcut konfigürasyonda yorum yapılabilir statülerdir. Bu liste GET /Review/GetValidOrderItemStatusesForCreatingReview endpoint'inden dinamik olarak alınmalıdır.


QuestionType Enum

Değer Ad UI Bileşeni Cevap Gönderme
1 Text Text input answer alanı (string)
2 Number Numeric input answer alanı (sayı string'i)
3 Select Dropdown / Radio button answer + optionIds (tek seçenek)
4 MultiSelect Checkbox grubu answer + optionIds (birden fazla seçenek)
5 Bool Evet/Hayır answer + optionIds (tek seçenek)
6 Rating Yıldız değerlendirmesi answer + optionIds (tek seçenek)

ReviewSource Enum

Değer Ad Açıklama
0 Website Website veya app üzerinden gönderilmiş yorum
1 Trendyol Trendyol'dan aktarılmış yorum

Yasal Zorunluluk: source: 1 (Trendyol) olan yorumlarda kullanıcı arayüzünde "trendyol.com'dan alınmıştır" veya benzeri bir ifadenin gösterilmesi zorunludur.