انتقل إلى المحتوى
ShopentlyLearn

إنشاء — المنتجات

نفّذ «إنشاء» في «المنتجات» باستخدام البيانات الموضحة أدناه.

POST/api/v1/products

المصادقة
Bearer
متاح بدءًا من
STANDARD
الصلاحيات المطلوبة
catalog.product:create
صلاحيات إضافية لحقول محددة
  • عندما لا يكون variant_value_ids فارغًا: catalog.product_variant:create
معرفة المزيد

أمثلة الكود

مثال على الطلب

cURL

: "${SHOPENTLY_SHOP_URL:?}"

curl --disable --globoff --fail-with-body --silent --show-error \
  --proto '=https' --connect-timeout 5 --max-time 30 \
  --request POST \
  --header "Authorization: Bearer ${SHOPENTLY_ACCESS_TOKEN:?}" \
  --header 'Idempotency-Key: example-create_product_api_v1_products_post' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "Example",
  "sku": "example"
}' \
  --url "${SHOPENTLY_SHOP_URL%/}"/api/v1/products

PHP

<?php
declare(strict_types=1);

$baseUrl = rtrim(getenv('SHOPENTLY_SHOP_URL') ?: '', '/');
$origin = parse_url($baseUrl);
if (!$origin || ($origin['scheme'] ?? '') !== 'https' || empty($origin['host']) ||
    isset($origin['user'], $origin['pass']) || isset($origin['user']) || isset($origin['path']) ||
    isset($origin['query']) || isset($origin['fragment'])) {
    throw new RuntimeException('SHOPENTLY_SHOP_URL must be an HTTPS origin');
}
$credential = getenv('SHOPENTLY_ACCESS_TOKEN') ?: '';
if ($credential === '' || strpbrk($credential, "\r\n") !== false) {
    throw new RuntimeException('Invalid credential');
}
$headers = ['Idempotency-Key: example-create_product_api_v1_products_post', 'Content-Type: application/json'];
$headers[] = 'Authorization: Bearer ' . $credential;
$responseHeaders = [];
$handle = curl_init($baseUrl . '/api/v1/products');
curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => false,
    CURLOPT_PROTOCOLS => CURLPROTO_HTTPS,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HEADERFUNCTION => static function ($handle, string $line) use (&$responseHeaders): int {
        if (str_contains($line, ':')) {
            [$name, $value] = explode(':', $line, 2);
            $responseHeaders[strtolower(trim($name))] = trim($value);
        }
        return strlen($line);
    },
]);
curl_setopt($handle, CURLOPT_POSTFIELDS, '{
  "name": "Example",
  "sku": "example"
}');
$raw = curl_exec($handle);
$status = curl_getinfo($handle, CURLINFO_RESPONSE_CODE);
$error = curl_error($handle);
curl_close($handle);
if ($raw === false) {
    throw new RuntimeException('Transport error: ' . $error);
}
if ($status < 200 || $status >= 300) {
    throw new RuntimeException('HTTP ' . $status . '; request_id=' .
        ($responseHeaders['x-request-id'] ?? '') . '; retry_after=' . ($responseHeaders['retry-after'] ?? ''));
}
$result = $raw === '' ? null : json_decode($raw, true, 512, JSON_THROW_ON_ERROR | JSON_BIGINT_AS_STRING);
echo json_encode($result, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;

Python

from contextlib import ExitStack
import json
import os
from urllib.parse import urlsplit

import requests  # python -m pip install requests

base_url = os.environ["SHOPENTLY_SHOP_URL"].rstrip("/")
origin = urlsplit(base_url)
if origin.scheme != "https" or not origin.hostname or origin.username or origin.password or origin.path or origin.query or origin.fragment:
    raise ValueError("SHOPENTLY_SHOP_URL must be an HTTPS origin")
credential = os.environ['SHOPENTLY_ACCESS_TOKEN']
if not credential or "\r" in credential or "\n" in credential:
    raise ValueError("Invalid credential")
headers = {'Idempotency-Key': 'example-create_product_api_v1_products_post'}
headers["Authorization"] = 'Bearer' + " " + credential
body = '{\n  "name": "Example",\n  "sku": "example"\n}'
if body is not None:
    headers["Content-Type"] = "application/json"

with ExitStack() as stack:
    session = stack.enter_context(requests.Session())
    files = None
    if False:
        image = stack.enter_context(open(os.environ["SHOPENTLY_IMAGE_FILE"], "rb"))
        if os.fstat(image.fileno()).st_size > 5242880:
            raise ValueError("Image exceeds 5 MiB")
        files = {"file": ("article.png", image, "image/png")}
    response = session.request(
        'POST', base_url + '/api/v1/products', headers=headers,
        data=body.encode("utf-8") if body is not None else None, files=files,
        timeout=(5, 30), allow_redirects=False,
    )
    if not 200 <= response.status_code < 300:
        raise RuntimeError(f"HTTP {response.status_code}; request_id={response.headers.get('X-Request-ID', '')}; retry_after={response.headers.get('Retry-After', '')}")
    if False:
        if response.headers.get("Content-Type") != "image/webp" or len(response.content) > 5242880:
            raise ValueError("Unexpected image response")
        with open(os.environ["SHOPENTLY_OUTPUT_FILE"], "xb") as output:
            output.write(response.content)
    else:
        result = response.json() if response.content else None
        print(json.dumps(result, ensure_ascii=False, indent=2))

مثال على الاستجابة 201

JSON
{
  "data": {
    "deleted": false,
    "id": "example",
    "version": 1
  },
  "meta": {
    "request_id": "example"
  }
}

آلية العمل

  • يستطيع التكامل قراءة المنتجات غير المحذوفة، بما فيها المسودات، باستثناء المنتجات المحظورة بسبب حد في الخطة.
  • تُستبعد المنتجات المحظورة من القوائم؛ ويعيد الوصول المباشر entitlements.resource_blocked.
  • لذلك يختلف ظهور المنتج في API عن نشره في واجهة المتجر.
  • استخدم معرّفات موجودة للعلامات التجارية والفئات والخصائص والوسائط.
  • تتضمن الأسعار عملة وقائمة أسعار ومعاملة ضريبية وإصدارات تزامن صريحة.
  • أسعار المنتجات والمتغيرات مستقلة؛ استخدم بنية التسعير المدعومة والسلاسل العشرية الدقيقة.

المعاملات

معلمات الاستعلام

localeسلسلة نصية nullاختياري

اللغة المحددة لهذا الطلب.

سلسلة نصية:minLength: 2maxLength: 20
market_idسلسلة نصية nullاختياري

معرّف السوق الذي تعيده نقطة نهاية السياق.

القيود · سلسلة نصية 1
pattern
"^[a-z0-9][a-z0-9_-]{0,62}$"
market_codeسلسلة نصية nullاختياري

رمز السوق الذي تعيده نقطة نهاية السياق.

سلسلة نصية:minLength: 1maxLength: 16

ترويسات الطلب

Idempotency-Keyسلسلة نصيةمطلوب

معرّف فريد لعملية كتابة منطقية واحدة.

minLength: 1maxLength: 128
القيود
pattern
"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$"
مثال: "example-create_product_api_v1_products_post"

محتوى الطلب

application/json · مطلوب

ProductCreate
brand_idسلسلة نصية nullاختياري

معرّف العلامة التجارية.

سلسلة نصية:minLength: 1maxLength: 63
conditionسلسلة نصيةاختياري

حالة المنتج.

القيود
enum
["new", "refurbished", "used", "returned", "display", "damaged"]
القيمة الافتراضية: "new"
descriptionسلسلة نصية nullاختياري

الوصف باللغة المحددة.

سلسلة نصية:maxLength: 100000
feature_value_idsمصفوفة <سلسلة نصية> اختياري

معرّفات قيم الخصائص المحددة.

maxItems: 1000
مصفوفة:minLength: 1maxLength: 63
identifiersProductIdentifiers nullاختياري

رموز تعريف المنتج.

market_idsمصفوفة <سلسلة نصية> اختياري

معرّفات الأسواق المحددة.

maxItems: 1000
مصفوفة:minLength: 1maxLength: 63
media_idsمصفوفة <سلسلة نصية> اختياري

معرّفات ملفات الوسائط الموجودة مسبقًا.

maxItems: 20
مصفوفة:minLength: 1maxLength: 63
meta_descriptionسلسلة نصية nullاختياري

وصف محركات البحث باللغة المحددة.

سلسلة نصية:maxLength: 160
meta_keywordsمصفوفة <سلسلة نصية> nullاختياري

الكلمات المفتاحية لمحركات البحث باللغة المحددة.

مصفوفة:maxItems: 20
مصفوفة / مصفوفة:maxLength: 50
meta_titleسلسلة نصية nullاختياري

عنوان محركات البحث باللغة المحددة.

سلسلة نصية:maxLength: 70
nameسلسلة نصيةمطلوب

اسم المورد في السياق المناسب.

minLength: 1maxLength: 300
مثال: "Example"
pricingProductPrice اختياري

إعدادات الأسعار وإصدارات التحكم في التعديلات المتزامنة.

primary_category_idسلسلة نصية nullاختياري

معرّف الفئة الرئيسية.

سلسلة نصية:minLength: 1maxLength: 63
publishedقيمة منطقيةاختياري

ما إذا كان المورد منشورًا.

القيمة الافتراضية: false
skuسلسلة نصيةمطلوب

رمز وحدة حفظ المخزون.

minLength: 1maxLength: 100
القيود
pattern
"^\\S+$"
مثال: "example"
slugسلسلة نصية nullاختياري

جزء مسار URL باللغة المحددة.

سلسلة نصية:maxLength: 160
tax_category_idسلسلة نصية nullاختياري

معرّف الفئة الضريبية.

سلسلة نصية:minLength: 1maxLength: 63
variant_value_idsمصفوفة <سلسلة نصية> اختياري

معرّفات قيم المتغيرات المحددة.

maxItems: 250
مصفوفة:minLength: 1maxLength: 63
variants_enabledقيمة منطقيةاختياري

ما إذا كان المنتج يستخدم متغيرات.

القيمة الافتراضية: false

الاستجابات

الاستجابة 201

dataMutationData مطلوب

محتوى الاستجابة الناجحة.

الحقول · data
deletedقيمة منطقيةمطلوب

ما إذا تم تنفيذ الحذف.

idسلسلة نصيةمطلوب

معرّف المورد؛ احتفظ به كما أعيد.

versionعدد صحيح nullمطلوب

إصدار المورد المستخدم للتحكم في التعديلات المتزامنة.

metaContextPageMeta ContextMeta PageMeta RequestMeta مطلوب

البيانات الوصفية للاستجابة.

الحقول · meta

ContextPageMeta

localeسلسلة نصيةمطلوب

اللغة المحددة لهذا الطلب.

market_codeسلسلة نصيةمطلوب

رمز السوق الذي تعيده نقطة نهاية السياق.

market_idسلسلة نصيةمطلوب

معرّف السوق الذي تعيده نقطة نهاية السياق.

paginationPagination مطلوب

البيانات الوصفية للترقيم باستخدام المؤشر.

request_idسلسلة نصيةمطلوب

معرّف الطلب؛ في البيانات الوصفية للاستجابة يحدد طلب HTTP.

minLength: 1maxLength: 100

ContextMeta

localeسلسلة نصيةمطلوب

اللغة المحددة لهذا الطلب.

market_codeسلسلة نصيةمطلوب

رمز السوق الذي تعيده نقطة نهاية السياق.

market_idسلسلة نصيةمطلوب

معرّف السوق الذي تعيده نقطة نهاية السياق.

request_idسلسلة نصيةمطلوب

معرّف الطلب؛ في البيانات الوصفية للاستجابة يحدد طلب HTTP.

minLength: 1maxLength: 100

PageMeta

paginationPagination مطلوب

البيانات الوصفية للترقيم باستخدام المؤشر.

request_idسلسلة نصيةمطلوب

معرّف الطلب؛ في البيانات الوصفية للاستجابة يحدد طلب HTTP.

minLength: 1maxLength: 100

RequestMeta

request_idسلسلة نصيةمطلوب

معرّف الطلب؛ في البيانات الوصفية للاستجابة يحدد طلب HTTP.

minLength: 1maxLength: 100
مثال على الاستجابة

حالة HTTP

201
تم إنشاء المورد المخطط
400
طلب غير صالح
401
المصادقة مطلوبة
403
الإذن مرفوض
404
المورد غير موجود
409
تعارض الإصدارات
422
فشل التحقق من البيانات
429
تم تجاوز حد الطلبات
حالات HTTP الأخرى (7)
405
الطريقة غير مسموحة
413
الطلب كبير جدًا
415
تنسيق غير مدعوم
500
خطأ في الخادم
502
خطأ في بوابة API
503
الخدمة غير متاحة
504
انتهت مهلة الانتظار

دليل الأخطاء: ErrorResponse

الترويسات

201

Locationسلسلة نصيةاختياري

عنوان URL نسبي للمورد الذي تم إنشاؤه.

401

WWW-Authenticateسلسلة نصيةاختياري

نظام المصادقة الذي يطلبه الخادم.

405

Allowسلسلة نصيةاختياري

طرق HTTP التي يدعمها هذا المورد.

429, 503

Retry-Afterعدد صحيحاختياري

الحد الأدنى للانتظار قبل إعادة المحاولة، بالثواني.

minimum: 0