الطلب الأول
تحقق من الاتصال بمتجرك. أنشئ مفتاح API، واحصل على رمز وصول، ثم أرسل طلبك الأول خطوة بخطوة.
البدء
- أنشئ مفتاحًا
- احصل على رمز
- تحقق من الاتصال
البدء
-
أنشئ مفتاح API
افتح إعدادات API في لوحة إدارة المتجر وأنشئ مفتاحًا.
احفظ المفتاح في مكان آمن، فلن تتمكن من عرضه مجددًا بعد إغلاق النافذة.
أنشئ مفتاح API
SHOPENTLY_SHOP_URL- عنوان HTTPS لمتجرك دون المسار /api/v1. استبدل العنوان في المثال بعنوان متجرك.
https://twoj-sklep.exampleSHOPENTLY_API_KEY- المفتاح الذي أُنشئ في لوحة إدارة المتجر.
المصادقة
تستخدم أمثلة cURL المتغيرات SHOPENTLY_SHOP_URL وSHOPENTLY_API_KEY وSHOPENTLY_ACCESS_TOKEN كقيم محلية توضيحية. اضبطها بشكل خاص على خادم التكامل؛ لا تنشر بيانات اعتماد حقيقية في الشيفرة المصدرية أو صفحات المتصفح أو لقطات الشاشة أو السجلات.
-
جلب · رمز الوصول
POST/api/v1/auth/tokenاستخدم المفتاح للحصول على رمز وصول. سترسل هذا الرمز مع طلباتك التالية.
أمثلة
مثال على الطلب
cURL
: "${SHOPENTLY_SHOP_URL:?}" response=$(curl --disable --globoff --fail-with-body --silent --show-error \ --proto '=https' --connect-timeout 5 --max-time 30 \ --write-out '\n%{http_code}' \ --request POST \ --header "Authorization: ApiKey ${SHOPENTLY_API_KEY:?}" \ --header 'Content-Type: application/json' \ --data-raw '{}' \ --url "${SHOPENTLY_SHOP_URL%/}"/api/v1/auth/token) || exit 1 status=$(printf '%s' "$response" | tail -n 1) case "$status" in 2??) printf '%s\n' "$response" | sed '$d' ;; *) printf 'HTTP %s\n' "$status" >&2; exit 1 ;; esacPHP
<?php $base = rtrim(getenv('SHOPENTLY_SHOP_URL') ?: '', '/'); $origin = parse_url($base); if (!$origin || ($origin['scheme'] ?? '') !== 'https' || empty($origin['host']) || array_intersect(['user', 'pass', 'path', 'query', 'fragment'], array_keys($origin))) { throw new RuntimeException('SHOPENTLY_SHOP_URL must be an HTTPS origin'); } $credential = getenv('SHOPENTLY_API_KEY') ?: ''; if ($credential === '' || preg_match('/\s/', $credential)) { throw new RuntimeException('Invalid credential'); } $curl = curl_init($base . '/api/v1/auth/token'); curl_setopt_array($curl, [ CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_HTTPHEADER => ['Authorization: ApiKey ' . $credential, 'Content-Type: application/json'], CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => false, CURLOPT_PROTOCOLS => CURLPROTO_HTTPS, CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => 30, CURLOPT_POSTFIELDS => '{}', ]); $raw = curl_exec($curl); $status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE); curl_close($curl); if ($raw === false || $status < 200 || $status >= 300) { throw new RuntimeException('Request failed; HTTP ' . $status); } $result = json_decode($raw, true, 512, JSON_THROW_ON_ERROR | JSON_BIGINT_AS_STRING); echo json_encode($result, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT), PHP_EOL;Python
import json import os from urllib.parse import urlsplit import requests base = os.environ["SHOPENTLY_SHOP_URL"].rstrip("/") origin = urlsplit(base) if (origin.scheme != "https" or not origin.hostname or origin.username is not None or origin.path or origin.query or origin.fragment): raise ValueError("SHOPENTLY_SHOP_URL must be an HTTPS origin") credential = os.environ["SHOPENTLY_API_KEY"] if not credential or any(c.isspace() for c in credential): raise ValueError("Invalid credential") response = requests.request( "POST", base + "/api/v1/auth/token", headers={"Authorization": "ApiKey " + credential}, timeout=(5, 30), allow_redirects=False, json={}, ) if not 200 <= response.status_code < 300: raise RuntimeError(f"HTTP {response.status_code}") result = response.json() print(json.dumps(result, ensure_ascii=False, indent=2))مثال على الاستجابة · HTTP 200
JSON { "data": { "access_token": "EXAMPLE_ACCESS_TOKEN", "expires_at": "2026-01-01T12:00:00Z", "expires_in": 900, "rate_limits": { "auth_per_minute": 10, "read_per_minute": 60, "write_per_minute": 10 }, "token_type": "Bearer" }, "meta": { "request_id": "example" } }الاستجابة
data.access_token- رمز الترويسة Authorization: Bearer. اضبط SHOPENTLY_ACCESS_TOKEN قبل تشغيل المثال المنفصل.
data.expires_in- 900 ثانية، أي 15 دقيقة من وقت الإصدار. إرسال الطلبات لا يمدد الصلاحية.
data.expires_at- وقت انتهاء الصلاحية بتوقيت UTC. قد تمنع قيود الوصول الحالية استخدام الرمز قبل ذلك.
data.rate_limits- Engine ≥ 4.143.0. تتضمن كل استجابة للرمز data.rate_limits من سياسة المتجر وقت إصداره. تتشارك جميع المفاتيح هذه الحدود؛ إصدار رمز جديد لا يعيد ضبطها. قد يسري تغيير الخطة قبل انتهاء صلاحية الرمز.
-
تحقق من الاتصال بمتجرك
GET/api/v1/contextأرسل طلبًا باستخدام الرمز. يعرض الرد اللغات والأسواق المتاحة في متجرك.
مثال على الطلب
cURL
: "${SHOPENTLY_SHOP_URL:?}" response=$(curl --disable --globoff --fail-with-body --silent --show-error \ --proto '=https' --connect-timeout 5 --max-time 30 \ --write-out '\n%{http_code}' \ --request GET \ --header "Authorization: Bearer ${SHOPENTLY_ACCESS_TOKEN:?}" \ --url "${SHOPENTLY_SHOP_URL%/}"/api/v1/context) || exit 1 status=$(printf '%s' "$response" | tail -n 1) case "$status" in 2??) printf '%s\n' "$response" | sed '$d' ;; *) printf 'HTTP %s\n' "$status" >&2; exit 1 ;; esacPHP
<?php $base = rtrim(getenv('SHOPENTLY_SHOP_URL') ?: '', '/'); $origin = parse_url($base); if (!$origin || ($origin['scheme'] ?? '') !== 'https' || empty($origin['host']) || array_intersect(['user', 'pass', 'path', 'query', 'fragment'], array_keys($origin))) { throw new RuntimeException('SHOPENTLY_SHOP_URL must be an HTTPS origin'); } $credential = getenv('SHOPENTLY_ACCESS_TOKEN') ?: ''; if ($credential === '' || preg_match('/\s/', $credential)) { throw new RuntimeException('Invalid credential'); } $curl = curl_init($base . '/api/v1/context'); curl_setopt_array($curl, [ CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $credential], CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => false, CURLOPT_PROTOCOLS => CURLPROTO_HTTPS, CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => 30, ]); $raw = curl_exec($curl); $status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE); curl_close($curl); if ($raw === false || $status < 200 || $status >= 300) { throw new RuntimeException('Request failed; HTTP ' . $status); } $result = json_decode($raw, true, 512, JSON_THROW_ON_ERROR | JSON_BIGINT_AS_STRING); echo json_encode($result, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT), PHP_EOL;Python
import json import os from urllib.parse import urlsplit import requests base = os.environ["SHOPENTLY_SHOP_URL"].rstrip("/") origin = urlsplit(base) if (origin.scheme != "https" or not origin.hostname or origin.username is not None 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 any(c.isspace() for c in credential): raise ValueError("Invalid credential") response = requests.request( "GET", base + "/api/v1/context", headers={"Authorization": "Bearer " + credential}, timeout=(5, 30), allow_redirects=False, ) if not 200 <= response.status_code < 300: raise RuntimeError(f"HTTP {response.status_code}") result = response.json() print(json.dumps(result, ensure_ascii=False, indent=2))مثال على الاستجابة · HTTP 200
JSON { "data": { "base_market_id": "example", "default_locale": "en", "global_enabled": false, "languages": [ { "code": "en", "direction": "ltr", "is_default": true, "name": "English", "native_name": "English", "status": "draft" } ], "markets": [ { "code": "PL", "currency": { "code": "PLN", "minor_units": 2 }, "id": "example", "is_default": true, "name": "Poland", "price_list": null, "status": "draft" } ], "multilingual_enabled": false }, "meta": { "locale": "en", "market_code": "PL", "market_id": "example", "request_id": "example" } }الاستجابة
استخدم معرّفات اللغات والأسواق المُعادة في الطلبات التالية.
كيف تتأكد من نجاح الاتصال؟
يؤكد الرد HTTP 200 الذي يحتوي على بيانات متجرك أن الاتصال يعمل.
يحصل البرنامج الكامل على رمز ويقرأ سياق المتجر في تشغيل واحد. تتحقق التعليمات البرمجية الإضافية من الإعدادات وتعالج النقل والأخطاء.
مثال كامل
تشغيل المثال
شغّل المثال الكامل في الطرفية أو باستخدام PHP أو Python.
PHP 8.3 (64-bit, ext-curl, JSON) · Python 3.12 + requests · cURL 8 + jq 1.7.
cURL
#!/bin/sh
# POSIX shell, curl 8+, jq 1.7. Credentials stay in environment variables.
set -eu
: "${SHOPENTLY_SHOP_URL:?}"
base=${SHOPENTLY_SHOP_URL%/}
case "$base" in https://*) ;; *) echo 'Use an HTTPS origin' >&2; exit 1;; esac
authority=${base#https://}
case "$authority" in ''|*/*|*\?*|*\#*|*@*) echo 'Use an HTTPS origin' >&2; exit 1;; esac
work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT HUP INT TERM
chmod 700 "$work"
encode() { printf '%s' "$1" | jq -sRr @uri; }
api() {
method=$1; path=$2; body=${3-}; key=${4-}
scheme=Bearer; credential=${SHOPENTLY_ACCESS_TOKEN-}
if [ "$path" = /api/v1/auth/token ]; then scheme=ApiKey; credential=${SHOPENTLY_API_KEY-}; fi
[ -n "$credential" ] || { echo 'Missing credential' >&2; return 1; }
set -- --disable --globoff --silent --show-error --proto '=https' --connect-timeout 5 --max-time 30 \
--request "$method" --header "Authorization: $scheme $credential" \
--dump-header "$work/headers" --output "$work/body" --write-out '%{http_code}'
if [ -n "$key" ]; then set -- "$@" --header "Idempotency-Key: $key"; fi
if [ -n "$body" ]; then set -- "$@" --header 'Content-Type: application/json' --data-raw "$body"; fi
status=$(curl "$@" --url "$base$path") || return 1
case "$status" in
2??) if [ -s "$work/body" ]; then jq -e . "$work/body"; else printf 'null\n'; fi ;;
*) printf 'HTTP %s\n' "$status" >&2
jq -c '.error | {code, fields}' "$work/body" >&2 2>/dev/null || true
return 1 ;;
esac
}
token=$(api POST /api/v1/auth/token '{}')
SHOPENTLY_ACCESS_TOKEN=$(printf '%s' "$token" | jq -er '.data.access_token')
export SHOPENTLY_ACCESS_TOKEN
api GET /api/v1/context
PHP
<?php
declare(strict_types=1);
// PHP 8.3+, 64-bit, ext-curl. Credentials stay in environment variables.
function env(string $name): string {
$value = getenv($name);
if ($value === false || $value === '' || strpbrk($value, "\r\n") !== false) {
throw new RuntimeException('Invalid environment variable: ' . $name);
}
return $value;
}
$base = rtrim(env('SHOPENTLY_SHOP_URL'), '/');
$origin = parse_url($base);
if (!$origin || ($origin['scheme'] ?? '') !== 'https' || empty($origin['host']) ||
isset($origin['user']) || isset($origin['pass']) || isset($origin['path']) ||
isset($origin['query']) || isset($origin['fragment']) || PHP_INT_SIZE !== 8) {
throw new RuntimeException('Use a 64-bit PHP runtime and an HTTPS origin');
}
class ApiError extends RuntimeException {
public function __construct(public int $status, public array $headers, public array $error) {
parent::__construct('HTTP ' . $status . '; code=' . ($error['code'] ?? '') .
'; request_id=' . ($headers['x-request-id'] ?? ''));
}
}
function api(string $method, string $path, array $query = [], ?array $body = null, ?string $key = null, bool $apiKey = false): ?array {
global $base;
$credential = env($apiKey ? 'SHOPENTLY_API_KEY' : 'SHOPENTLY_ACCESS_TOKEN');
$headers = ['Authorization: ' . ($apiKey ? 'ApiKey ' : 'Bearer ') . $credential];
if ($key !== null) $headers[] = 'Idempotency-Key: ' . $key;
if ($body !== null) $headers[] = 'Content-Type: application/json';
$url = $base . $path . ($query ? '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986) : '');
$responseHeaders = [];
$h = curl_init($url);
curl_setopt_array($h, [
CURLOPT_CUSTOMREQUEST => $method, 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 ($h, string $line) use (&$responseHeaders): int {
if (str_contains($line, ':')) {
[$name, $value] = explode(':', $line, 2);
$responseHeaders[strtolower(trim($name))] = trim($value);
}
return strlen($line);
},
]);
if ($body !== null) {
$json = $apiKey && $body === [] ? '{}' : json_encode($body, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE);
curl_setopt($h, CURLOPT_POSTFIELDS, $json);
}
$raw = curl_exec($h);
$status = curl_getinfo($h, CURLINFO_RESPONSE_CODE);
$error = curl_error($h);
curl_close($h);
if ($raw === false) throw new RuntimeException('Transport error: ' . $error);
if ($status < 200 || $status >= 300) {
$data = json_decode($raw, true);
throw new ApiError($status, $responseHeaders, is_array($data) ? ($data['error'] ?? []) : []);
}
return $raw === '' ? null : json_decode($raw, true, 512, JSON_THROW_ON_ERROR | JSON_BIGINT_AS_STRING);
}
function output(mixed $value): void {
echo json_encode($value, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE), PHP_EOL;
}
$token = api('POST', '/api/v1/auth/token', body: [], apiKey: true)['data'];
putenv('SHOPENTLY_ACCESS_TOKEN=' . $token['access_token']);
output(api('GET', '/api/v1/context'));
Python
"""Run with Python 3.12 and requests. Credentials stay in environment variables."""
import json
import os
import random
import time
from urllib.parse import quote, urlencode, urlsplit
import requests
def env(name):
value = os.environ[name]
if not value or "\r" in value or "\n" in value:
raise ValueError("Invalid environment variable: " + name)
return value
base = env("SHOPENTLY_SHOP_URL").rstrip("/")
origin = urlsplit(base)
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")
class ApiError(RuntimeError):
def __init__(self, response):
self.status = response.status_code
self.request_id = response.headers.get("X-Request-ID", "")
self.retry_after = response.headers.get("Retry-After", "")
try:
self.error = response.json().get("error", {})
except (ValueError, AttributeError):
self.error = {}
super().__init__(f"HTTP {self.status}; code={self.error.get('code', '')}; request_id={self.request_id}")
def api(method, path, *, query=None, body=None, key=None, api_key=False):
credential = env("SHOPENTLY_API_KEY" if api_key else "SHOPENTLY_ACCESS_TOKEN")
headers = {"Authorization": ("ApiKey " if api_key else "Bearer ") + credential}
if key:
headers["Idempotency-Key"] = key
if body is not None:
headers["Content-Type"] = "application/json"
response = requests.request(method, base + path, params=query, headers=headers,
data=json.dumps(body, ensure_ascii=False, allow_nan=False).encode() if body is not None else None,
timeout=(5, 30), allow_redirects=False)
if not 200 <= response.status_code < 300:
raise ApiError(response)
return response.json() if response.content else None
def segment(value):
return quote(value, safe="")
token = api("POST", "/api/v1/auth/token", body={}, api_key=True)["data"]
os.environ["SHOPENTLY_ACCESS_TOKEN"] = token["access_token"]
print(json.dumps(api("GET", "/api/v1/context"), ensure_ascii=False, indent=2))