کاردکس و انبارگردانی
مخاطب: برنامهنویس نرمافزار حسابداری یا انبارداری که میخواهد ورود و خروج کالا را با کاردکس سلر ۳۶۰ هماهنگ کند، مانده و ارزش موجودی را بخواند یا نتیجهی شمارش انبار را ثبت کند.
📖 مقدمه
Section titled “📖 مقدمه”کاردکس دفتر ورود و خروج کالای متعلق به شما است: کالایی که در انبار خودتان است بهعلاوهی کالای شما در انبار دیجیکالا. هر تغییر تعداد یک ردیف تغییرناپذیر است و ماندهی هر کد کالا جمع همین ردیفهاست. فروشهای دیجیکالا، مرجوعیهای مشتری و رسیدهای سفارش خرید خودکار در آن ثبت میشوند؛ خرید، موجودی اول دوره، مرجوعی به تامینکننده و ضایعات را خودتان ثبت میکنید. با انبارگردانی تعداد شمارششده را با ماندهی کاردکس مقایسه میکنید و اختلافها بهصورت حرکت اصلاحی ثبت میشوند.
با مسیرهای این صفحه میتوانید:
| کار | مسیر | در دسترس |
|---|---|---|
| خواندن دفتر ورود و خروج | GET /v1/kardex/movements |
فعال |
| ثبت حرکت دستی | POST /v1/kardex/movements |
فعال |
| مانده و ارزش هر کد کالا | GET /v1/kardex/balances |
فعال |
| فهرست انبارگردانیها | GET /v1/stock-counts |
فعال |
| شروع انبارگردانی | POST /v1/stock-counts |
فعال |
| یک انبارگردانی با اقلام | GET /v1/stock-counts/{count_id} |
فعال |
| ثبت تعداد شمارششده | PATCH /v1/stock-counts/{count_id}/lines |
فعال |
| نهایی کردن انبارگردانی | POST /v1/stock-counts/{count_id}/finalize |
فعال |
هیچکدام از این مسیرها چیزی در دیجیکالا نمینویسند. کاردکس با «موجودی در انبار فروشنده» در دیجیکالا یکی نیست؛ برای آن عدد صفحهی موجودی را ببینید.
⚙️ پیشنیازها
Section titled “⚙️ پیشنیازها”دسترسی (Scope)
Section titled “دسترسی (Scope)”| دسترسی | برچسب در پنل | برای |
|---|---|---|
kardex:read |
«خواندن کاردکس و انبارگردانی» | خواندن حرکتها، ماندهها و انبارگردانیها |
kardex:write |
«ثبت در کاردکس و انبارگردانی» | ثبت حرکت دستی، شروع، ثبت شمارش و نهایی کردن انبارگردانی |
روشن بودن کاردکس
Section titled “روشن بودن کاردکس”کاردکس بهطور پیشفرض خاموش است. تا وقتی آن را در تنظیمات پنل روشن نکنید، مسیرهای این صفحه با کد 409 و خطای kardex_disabled پاسخ میدهند. روش ارزشگذاری (valuation_method) را هم در همان تنظیمات انتخاب میکنید.
فعال بودن ماژول
Section titled “فعال بودن ماژول”ماژول «API و وبهوک» باید برای پنل فعال باشد؛ در غیر این صورت پاسخ 403 با خطای module_inactive برمیگردد. چون کاردکس فقط در سلر ۳۶۰ ثبت میشود، ثبت در آن برای پنلی که اشتراک آن به پایان رسیده است هم ممکن است.
آدرس پایه
Section titled “آدرس پایه”https://api.seller360.ir🧮 مدل کاردکس
Section titled “🧮 مدل کاردکس”کلید: کد کالا
Section titled “کلید: کد کالا”کاردکس بر اساس کد فروشنده (supplier_code) است، نه تنوع: همهی تنوعهایی که یک کد فروشنده دارند یک ردیف کاردکس دارند، چون یک کالای فیزیکیاند. تنوعی که کد فروشنده ندارد در کاردکس نمیآید.
فیلدهای حرکت (KardexMovement)
Section titled “فیلدهای حرکت (KardexMovement)”| فیلد | معنی |
|---|---|
id |
شناسهی حرکت. |
supplier_code |
کد فروشنده. |
title |
نام کالا. |
movement_type |
نوع حرکت (جدول بعد). |
direction |
in ورودی یا out خروجی؛ از نوع حرکت میآید. |
quantity |
همیشه مثبت. |
signed_quantity |
مثبت برای ورودی و منفی برای خروجی. |
unit_cost |
قیمت هر واحد ورودی به ریال. |
occurred_at |
روز حرکت. |
source |
از کجا ثبت شده است (جدول بعد). |
reference |
مرجع بیرونی، مثلا po:204 برای سفارش خرید ۲۰۴. |
note |
توضیح. |
created_at |
زمان ثبت. |
balance_after |
ماندهی کد کالا پس از همین حرکت؛ فقط وقتی با supplier_code فیلتر کنید. |
انواع حرکت
Section titled “انواع حرکت”movement_type |
برچسب در پنل | جهت | ثبت |
|---|---|---|---|
opening |
«موجودی اول دوره» | ورودی | دستی |
purchase |
«خرید / رسید» | ورودی | دستی، یا خودکار از رسید سفارش خرید |
customer_return |
«مرجوعی مشتری» | ورودی | دستی، یا خودکار از مرجوعیهای دیجیکالا |
count_increase |
«اصلاح انبارگردانی +» | ورودی | فقط خودکار، با نهایی کردن انبارگردانی |
sale |
«فروش» | خروجی | فقط خودکار |
supplier_return |
«مرجوعی به تامینکننده» | خروجی | دستی |
wastage |
«ضایعات» | خروجی | دستی |
count_decrease |
«اصلاح انبارگردانی −» | خروجی | فقط خودکار، با نهایی کردن انبارگردانی |
منبع حرکت
Section titled “منبع حرکت”source |
برچسب در پنل |
|---|---|
manual |
«دستی»؛ هر حرکتی که با API ثبت کنید همین منبع را دارد. |
stockinput |
«ورودی انبار» |
sale |
«فروش دیجیکالا» |
count |
«انبارگردانی» |
shop |
«فروشگاههای من» |
purchase_order |
«سفارش خرید» |
مانده و ارزش (KardexBalance)
Section titled “مانده و ارزش (KardexBalance)”| فیلد | معنی |
|---|---|
supplier_code، title |
کد کالا و نام آن. |
quantity |
ماندهی فعلی. |
value |
ارزش مانده به ریال. |
average_cost |
قیمت تمامشدهی هر واحد به ریال. |
valuation_method |
weighted_avg «میانگین موزون»، fifo «اولینورودی-اولینخروجی (FIFO)» یا none «بدون ارزشگذاری (فقط تعداد)». |
انبارگردانی (StockCount)
Section titled “انبارگردانی (StockCount)”| فیلد | معنی |
|---|---|
id، title، note |
شناسه، عنوان و یادداشت. |
counted_on |
روز شمارش. |
status |
draft «پیشنویس» یا finalized «نهاییشده». |
created_at، finalized_at |
زمان شروع و نهایی شدن. |
lines |
اقلام؛ فقط در پاسخ یک انبارگردانی. |
lines[].system_qty |
ماندهی کاردکس هنگام شروع انبارگردانی. |
lines[].counted_qty |
تعداد شمارششده؛ null یعنی هنوز شمرده نشده است. |
lines[].variance |
counted_qty منهای system_qty. |
🔄 چرخهی انبارگردانی
Section titled “🔄 چرخهی انبارگردانی”- شروع:
POST /v1/stock-countsیک انبارگردانی پیشنویس میسازد و ماندهی فعلی هر کد را درsystem_qtyثبت میکند. - شمارش: تعداد شمردهشده را با
PATCH .../linesثبت کنید؛ میتوانید چند بار و بخشبهبخش بفرستید. - نهایی کردن:
POST .../finalizeبرای هر کد شمردهشدهای که باsystem_qtyفرق دارد یک حرکتcount_increaseیاcount_decreaseثبت میکند. کدهای شمردهنشده دست نمیخورند. - پس از آن: انبارگردانی نهاییشده تغییر نمیکند.
🔢 تازگی
Section titled “🔢 تازگی”- حرکتهای دستی و انبارگردانی: فوریاند و در همان پاسخ دیده میشوند.
- حرکتهای خودکار: فروش و مرجوعی دیجیکالا پس از دریافت سفارشها از دیجیکالا، و رسید سفارش خرید در لحظهی ثبت دریافت، به کاردکس اضافه میشوند. هر ردیف خودکار فقط یک بار ثبت میشود.
⚠️ هشدارها
Section titled “⚠️ هشدارها”📡 مسیرها
Section titled “📡 مسیرها”GET /v1/kardex/movements — دفتر ورود و خروج فعال
Section titled “GET /v1/kardex/movements — دفتر ورود و خروج ”حرکتها به ترتیب تاریخ.
GET /v1/kardex/movements?supplier_code=5144&from=2026-10-23 HTTP/1.1Host: api.seller360.irAuthorization: Bearer s360_live_...| پارامتر | نوع | اجباری | توضیح |
|---|---|---|---|
page، size |
عدد | خیر | صفحهبندی؛ پیشفرض ۵۰، بیشینه ۵۰۰. |
supplier_code |
متن | خیر | فقط این کد؛ با این فیلتر هر ردیف balance_after هم دارد. |
movement_type |
یکی از انواع حرکت | خیر | فقط این نوع. |
source |
یکی از منبعها | خیر | فقط این منبع. |
from، to |
تاریخ | خیر | اولین و آخرین روز حرکت، شامل همان روز. |
{ "status": "ok", "data": [ { "id": 77120, "supplier_code": "5144", "title": "محافظ ولتاژ پارت الکتریک مدل PE5144", "movement_type": "purchase", "direction": "in", "quantity": 40, "signed_quantity": 40, "unit_cost": 18500000, "occurred_at": "2026-11-10", "source": "purchase_order", "reference": "po:204", "note": null, "created_at": "2026-11-10T16:22:05+03:30", "balance_after": 118 }, { "id": 77134, "supplier_code": "5144", "title": "محافظ ولتاژ پارت الکتریک مدل PE5144", "movement_type": "sale", "direction": "out", "quantity": 2, "signed_quantity": -2, "unit_cost": null, "occurred_at": "2026-11-11", "source": "sale", "reference": "352418806", "note": null, "created_at": "2026-11-11T18:03:51+03:30", "balance_after": 116 } ], "pager": { "page": 1, "item_per_page": 50, "total_pages": 1, "total_rows": 2 }}POST /v1/kardex/movements — ثبت حرکت دستی فعال
Section titled “POST /v1/kardex/movements — ثبت حرکت دستی ”POST /v1/kardex/movements HTTP/1.1Host: api.seller360.irAuthorization: Bearer s360_live_...Idempotency-Key: wastage-5144-1405-08-22Content-Type: application/json
{ "supplier_code": "5144", "movement_type": "wastage", "quantity": 2, "occurred_at": "2026-11-12", "note": "شکستگی در انبار"}| فیلد بدنه | نوع | اجباری | توضیح |
|---|---|---|---|
supplier_code |
متن | بله | کد کالا؛ ۱ تا ۱۰۰ نویسه. |
movement_type |
opening، purchase، customer_return، supplier_return، wastage |
بله | فقط انواع دستی. |
quantity |
عدد | بله | ۱ تا ۱٬۰۰۰٬۰۰۰. |
occurred_at |
تاریخ | بله | روز حرکت. |
unit_cost |
عدد یا null |
خیر | قیمت هر واحد ورودی به ریال؛ برای ارزشگذاری حرکتهای ورودی لازم است. |
reference |
متن | خیر | مرجع بیرونی، مثلا شمارهی فاکتور؛ تا ۱۲۰ نویسه. |
note |
متن | خیر | تا ۳۰۰ نویسه. |
پاسخ موفق: کد 201 با حرکت ثبتشده و source: "manual".
خطاهای این مسیر
| کد HTTP | خطا | معنی | تکرار بیخطر است؟ |
|---|---|---|---|
400 |
invalid_parameter |
فیلدی نادرست است یا جا افتاده است. | خیر؛ بدنه را اصلاح کنید. |
409 |
kardex_disabled |
کاردکس در تنظیمات پنل روشن نیست. | خیر؛ ابتدا کاردکس را روشن کنید. |
422 |
movement_type_not_allowed |
این نوع حرکت فقط خودکار ثبت میشود. | خیر. |
409 |
idempotency_mismatch |
این کلید یکتا قبلا با بدنهی دیگری استفاده شده است. | خیر؛ کلید تازه بسازید. |
409 |
idempotency_in_progress |
درخواستی با همین کلید در حال انجام است. | بله، چند ثانیه بعد. |
GET /v1/kardex/balances — مانده و ارزش هر کد فعال
Section titled “GET /v1/kardex/balances — مانده و ارزش هر کد ”بیشترین ارزش اول. کدهایی که مانده و ارزش صفر دارند نمیآیند.
| پارامتر | نوع | اجباری | توضیح |
|---|---|---|---|
page، size |
عدد | خیر | صفحهبندی. |
supplier_code |
متن | خیر | فقط این کد. |
{ "status": "ok", "data": [ { "supplier_code": "5144", "title": "محافظ ولتاژ پارت الکتریک مدل PE5144", "quantity": 116, "value": 2129600000, "average_cost": 18358621, "valuation_method": "weighted_avg" } ], "pager": { "page": 1, "item_per_page": 50, "total_pages": 3, "total_rows": 112 }}GET /v1/stock-counts — انبارگردانیها فعال
Section titled “GET /v1/stock-counts — انبارگردانیها ”تازهترین اول و بدون اقلام. پارامترها: page، size و status (draft یا finalized).
POST /v1/stock-counts — شروع انبارگردانی فعال
Section titled “POST /v1/stock-counts — شروع انبارگردانی ”POST /v1/stock-counts HTTP/1.1Host: api.seller360.irAuthorization: Bearer s360_live_...Idempotency-Key: count-1405-08-30Content-Type: application/json
{ "title": "انبارگردانی پایان آبان", "counted_on": "2026-11-21" }| فیلد بدنه | نوع | اجباری | توضیح |
|---|---|---|---|
counted_on |
تاریخ | بله | روز شمارش. |
title |
متن | خیر | تا ۲۰۰ نویسه. |
note |
متن | خیر | تا ۳۰۰ نویسه. |
پاسخ موفق: کد 201 با انبارگردانی و همهی اقلام آن.
GET /v1/stock-counts/{count_id} — یک انبارگردانی فعال
Section titled “GET /v1/stock-counts/{count_id} — یک انبارگردانی ”{ "status": "ok", "data": { "id": 12, "title": "انبارگردانی پایان آبان", "counted_on": "2026-11-21", "status": "draft", "note": null, "created_at": "2026-11-21T08:10:44+03:30", "finalized_at": null, "lines": [ { "supplier_code": "5144", "title": "محافظ ولتاژ پارت الکتریک مدل PE5144", "system_qty": 44, "counted_qty": 41, "variance": -3, "note": null }, { "supplier_code": "6100", "title": "محافظ ولتاژ پارت الکتریک مدل PE6100", "system_qty": 20, "counted_qty": null, "variance": null, "note": null } ] }}PATCH /v1/stock-counts/{count_id}/lines — ثبت تعداد شمارششده فعال
Section titled “PATCH /v1/stock-counts/{count_id}/lines — ثبت تعداد شمارششده ”فقط در انبارگردانی پیشنویس. کدی که فرستاده نشود تغییر نمیکند و counted_qty: null شمارش آن کد را پاک میکند.
{ "lines": [ { "supplier_code": "5144", "counted_qty": 41 }, { "supplier_code": "6100", "counted_qty": 20, "note": "قفسهی B" } ]}| فیلد بدنه | نوع | اجباری | توضیح |
|---|---|---|---|
lines[].supplier_code |
متن | بله | کد کالا. |
lines[].counted_qty |
عدد یا null |
بله | صفر یا بیشتر؛ null برای پاک کردن. |
lines[].note |
متن | خیر | تا ۲۰۰ نویسه. |
پاسخ موفق: کد 200 با انبارگردانی. اگر انبارگردانی نهایی شده باشد، کد 409 و خطای stock_count_finalized برمیگردد.
POST /v1/stock-counts/{count_id}/finalize — نهایی کردن فعال
Section titled “POST /v1/stock-counts/{count_id}/finalize — نهایی کردن ”بدنه ندارد.
{ "status": "ok", "data": { "stock_count": { "id": 12, "status": "finalized", "finalized_at": "2026-11-21T17:40:02+03:30" }, "increase_lines": 3, "decrease_lines": 5 }}خطاهای مسیرهای انبارگردانی
| کد HTTP | خطا | معنی | تکرار بیخطر است؟ |
|---|---|---|---|
404 |
not_found |
این انبارگردانی در این پنل نیست. | خیر. |
409 |
stock_count_finalized |
انبارگردانی نهایی شده است و تغییر نمیکند. | خیر؛ برای شمارش تازه، انبارگردانی تازهای بسازید. |
409 |
kardex_disabled |
کاردکس در تنظیمات پنل روشن نیست. | خیر. |
409 |
idempotency_in_progress |
درخواستی با همین کلید در حال انجام است. | بله، چند ثانیه بعد. |
🔔 رویدادهای وبهوک
Section titled “🔔 رویدادهای وبهوک”کاردکس رویداد وبهوک جداگانه ندارد. رسیدن کالای سفارش خرید با رویدادهای صفحهی پیشنهاد خرید و سفارش خرید و تغییر موجودی دیجیکالا با رویدادهای صفحهی موجودی اعلام میشوند.
💻 نمونهکد: ثبت ضایعات
Section titled “💻 نمونهکد: ثبت ضایعات”curl -X POST https://api.seller360.ir/v1/kardex/movements \ -H "Authorization: Bearer $S360_API_KEY" \ -H "Idempotency-Key: wastage-5144-1405-08-22" \ -H "Content-Type: application/json" \ -d '{"supplier_code": "5144", "movement_type": "wastage", "quantity": 2, "occurred_at": "2026-11-12"}'$ch = curl_init("https://api.seller360.ir/v1/kardex/movements");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer " . getenv("S360_API_KEY"), "Idempotency-Key: wastage-5144-1405-08-22", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "supplier_code" => "5144", "movement_type" => "wastage", "quantity" => 2, "occurred_at" => "2026-11-12", ]), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 20,]);$res = json_decode(curl_exec($ch), true);if (($res["error"]["code"] ?? null) === "kardex_disabled") { // کاردکس را در تنظیمات پنل روشن کنید}import os, requests
res = requests.post( "https://api.seller360.ir/v1/kardex/movements", headers={ "Authorization": f"Bearer {os.environ['S360_API_KEY']}", "Idempotency-Key": "wastage-5144-1405-08-22", }, json={"supplier_code": "5144", "movement_type": "wastage", "quantity": 2, "occurred_at": "2026-11-12"}, timeout=20,).json()if res["status"] == "error" and res["error"]["code"] == "kardex_disabled": ... # کاردکس را در تنظیمات پنل روشن کنیدconst res = await fetch('https://api.seller360.ir/v1/kardex/movements', { method: 'POST', headers: { Authorization: `Bearer ${process.env.S360_API_KEY}`, 'Idempotency-Key': 'wastage-5144-1405-08-22', 'Content-Type': 'application/json', }, body: JSON.stringify({ supplier_code: '5144', movement_type: 'wastage', quantity: 2, occurred_at: '2026-11-12', }),})const body = await res.json()if (body.error?.code === 'kardex_disabled') { // کاردکس را در تنظیمات پنل روشن کنید}using var http = new HttpClient();var req = new HttpRequestMessage(HttpMethod.Post, "https://api.seller360.ir/v1/kardex/movements");req.Headers.Add("Authorization", $"Bearer {Environment.GetEnvironmentVariable("S360_API_KEY")}");req.Headers.Add("Idempotency-Key", "wastage-5144-1405-08-22");req.Content = JsonContent.Create(new { supplier_code = "5144", movement_type = "wastage", quantity = 2, occurred_at = "2026-11-12",});var res = await http.SendAsync(req);var body = await res.Content.ReadFromJsonAsync<JsonElement>();