跳至內容
ShopentlyLearn

取得 · 庫存 — 庫存

讀取「庫存」的資料。結果取決於此操作的參數。

GET/api/v1/inventory/stock/{stock_id}

身份驗證
Bearer
最低方案
STANDARD
所需權限
inventory.stock:read

程式碼範例

請求示例

cURL

: "${SHOPENTLY_SHOP_URL:?}"

curl --disable --globoff --fail-with-body --silent --show-error \
  --proto '=https' --connect-timeout 5 --max-time 30 \
  --request GET \
  --header "Authorization: Bearer ${SHOPENTLY_ACCESS_TOKEN:?}" \
  --url "${SHOPENTLY_SHOP_URL%/}"/api/v1/inventory/stock/stock_v1_WyJleGFtcGxlIiwicHJvZHVjdCIsImV4YW1wbGUiXQ

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 = [];
$headers[] = 'Authorization: Bearer ' . $credential;
$responseHeaders = [];
$handle = curl_init($baseUrl . '/api/v1/inventory/stock/stock_v1_WyJleGFtcGxlIiwicHJvZHVjdCIsImV4YW1wbGUiXQ');
curl_setopt_array($handle, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    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);
    },
]);
$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 = {}
headers["Authorization"] = 'Bearer' + " " + credential
body = None
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(
        'GET', base_url + '/api/v1/inventory/stock/stock_v1_WyJleGFtcGxlIiwicHJvZHVjdCIsImV4YW1wbGUiXQ', 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))

回應示例 200

JSON
{
  "data": {
    "active": true,
    "allocations": [
      {
        "location_code": "example",
        "location_id": "example",
        "location_name": "example",
        "on_hand": 10
      }
    ],
    "available": 5,
    "id": "stock_v1_WyJleGFtcGxlIiwicHJvZHVjdCIsImV4YW1wbGUiXQ",
    "manual_reserved": 2,
    "on_hand": 10,
    "reserved": 3,
    "sellable_limit": 10,
    "target_id": "example",
    "target_type": "product",
    "total_reserved": 5,
    "updated_at": "2026-01-01T12:00:00Z",
    "version": 1,
    "warehouse_id": "example"
  },
  "meta": {
    "request_id": "example"
  }
}

工作原理

  • 庫存記錄區分實物 on_hand 數量、訂單預留、手動預留和可售數量。
  • 請使用回傳的庫存記錄識別碼和版本;產品庫存與變體庫存是不同目標。
  • sellable_limit 為 -1 表示無限制,0 表示不可銷售。
  • 無限可售量在 available 中以 null 表示。
  • 不要將 null 當作零。
  • 庫存調整、銷售上限和手動預留具有獨立操作及權限。

參數

路徑參數

stock_id字串必填

庫存記錄識別碼。

minLength: 1maxLength: 256
示例: "stock_v1_WyJleGFtcGxlIiwicHJvZHVjdCIsImV4YW1wbGUiXQ"

此操作不接受 JSON 請求本文。

回應

回應 200

dataStockDetailData 必填

成功回應的資料。

欄位 · data
active布林值必填

資源是否處於活動狀態。

allocations陣列 <AllocationData > 必填

分配給倉庫庫位的數量。

欄位 · allocations
available整數 null必填

可售數量;null 表示數量不限。

id字串必填

資源識別碼;請保留回傳的原值。

manual_reserved整數必填

手動預留數量。

on_hand整數必填

實物庫存數量。

reserved整數必填

訂單預留數量。

sellable_limit整數必填

銷售上限:-1 表示不限,0 表示不可銷售。

target_id字串必填

操作影響的產品或變體識別碼。

target_type字串必填

操作針對產品還是變體。

約束
enum
["product", "variant"]
total_reserved整數必填

總預留數量。

updated_at字串必填

最近更新時間。

format: "date-time"
version整數必填

用於並行控制的資源版本。

warehouse_id字串必填

倉庫識別碼。

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 狀態

200
請求成功 架構
400
無效請求
401
需要身分驗證
403
權限不足
404
找不到資源
409
版本衝突
422
驗證失敗
429
超出請求限制
其他 HTTP 狀態 (7)
405
不允許的方法
413
請求過大
415
不支援的格式
500
伺服器錯誤
502
API 閘道錯誤
503
服務無法使用
504
閘道逾時

錯誤目錄: ErrorResponse

請求標頭與回應標頭

401

WWW-Authenticate字串選填

伺服器要求的身份驗證方案。

405

Allow字串選填

此資源支援的 HTTP 方法。

429, 503

Retry-After整數選填

重試前最少等待的秒數。

minimum: 0