{
  "info": {
    "name": "EI API v1",
    "_postman_id": "6d0f5b0c-3f2a-4d1e-9a52-7b1a5e2c8e10",
    "description": "کالکشن کامل API تیپینتا (نسخه‌ی ۱) با همه‌ی مسیرها و حالت‌های متداول، نمونه پاسخ‌ها و تست‌های ساده.\n\nشروع سریع:\n۱) متغیرهای کالکشن (mobile، password، apiKey) را پر کنید. baseUrl پیش‌فرض https://api.tpinta.com است.\n۲) هر درخواستی را اجرا کنید؛ توکن به‌طور خودکار گرفته و تمدید می‌شود. («دریافت توکن» را هم می‌توانید دستی اجرا کنید.)\n۳) «فهرست» شماره‌های اقتصادی را اجرا کنید تا economicId خودکار تنظیم شود، سپس «ارسال تکی ← ۱» را بزنید. taxId و clientRef هم خودکار ذخیره می‌شوند.\n\nهشدارها:\n• رمز و کلید API را در کالکشن‌هایی که به اشتراک می‌گذارید یا همگام‌سازی ابری می‌شوند نگذارید.\n• هر صورتحساب ثبت‌شده از اعتبار شما کم می‌شود؛ برای آزمایش از شماره اقتصادی «آزمایشی» استفاده کنید.\n• کل کالکشن را با Runner اجرا نکنید: ارسال‌ها هزینه دارند و سقف نرخ‌ها (مثلاً ۱۰ ارسال گروهی در دقیقه) رعایت نمی‌شود. درخواست‌ها را جداگانه و به ترتیب اجرا کنید.\n\nمستندات کامل: {{baseUrl}}/docs",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{token}}",
        "type": "string"
      }
    ]
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// دریافت و تمدید خودکار توکن: اگر توکن ندارید یا نزدیک انقضاست، قبل از هر درخواست (جز «دریافت توکن») توکن جدید می‌گیرد.",
          "// فقط وقتی mobile و password و apiKey پر باشند کار می‌کند. توکن تا پایان اعتبارش دوباره استفاده می‌شود (سقف دریافت توکن: ۲۰ بار در ۱۰ دقیقه).",
          "(function () {",
          "  if (pm.request.url.getPath().endsWith('/v1/auth/token')) return;",
          "  const v = k => pm.collectionVariables.get(k);",
          "  const exp = Number(v('tokenExpiresAt') || 0);",
          "  if (v('token') && Date.now() < exp - 60000) return;",
          "  if (!v('mobile') || !v('password') || !v('apiKey')) return;",
          "  pm.sendRequest({",
          "    url: pm.variables.replaceIn('{{baseUrl}}') + '/v1/auth/token',",
          "    method: 'POST',",
          "    header: { 'Content-Type': 'application/json' },",
          "    body: { mode: 'raw', raw: JSON.stringify({ mobile: v('mobile'), password: v('password'), apiKey: v('apiKey') }) }",
          "  }, (err, res) => {",
          "    if (err) { console.error('دریافت خودکار توکن ناموفق بود', err); return; }",
          "    const j = res.json();",
          "    if (res.code === 200 && j.success) {",
          "      pm.collectionVariables.set('token', j.data.accessToken);",
          "      pm.collectionVariables.set('tokenExpiresAt', String(Date.now() + (j.data.expiresIn || 3600) * 1000));",
          "    } else { console.warn('دریافت خودکار توکن:', res.code, res.text()); }",
          "  });",
          "})();"
        ]
      }
    }
  ],
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://api.tpinta.com",
      "description": "آدرس سرور API؛ برای سرور آزمایشی عوض کنید"
    },
    {
      "key": "mobile",
      "value": "",
      "description": "موبایل ثبت‌شده در پنل"
    },
    {
      "key": "password",
      "value": "",
      "description": "رمز پنل (به‌اشتراک نگذارید)"
    },
    {
      "key": "apiKey",
      "value": "",
      "description": "کلید API ساخته‌شده در پنل (ei_...)"
    },
    {
      "key": "token",
      "value": "",
      "description": "توکن Bearer؛ خودکار پر می‌شود"
    },
    {
      "key": "tokenExpiresAt",
      "value": "",
      "description": "زمان انقضای توکن (میلی‌ثانیه)؛ خودکار پر می‌شود"
    },
    {
      "key": "economicId",
      "value": "12",
      "description": "شناسه‌ی شماره اقتصادی (id در «فهرست»، نه خود کد اقتصادی)؛ با اجرای «فهرست» خودکار تنظیم می‌شود"
    },
    {
      "key": "clientRef",
      "value": "",
      "description": "شناسه‌ی یکتای آخرین ارسال تکی؛ خودکار ساخته می‌شود"
    },
    {
      "key": "clientRef1",
      "value": "",
      "description": "clientRef اول در ارسال گروهی؛ خودکار"
    },
    {
      "key": "clientRef2",
      "value": "",
      "description": "clientRef دوم در ارسال گروهی؛ خودکار"
    },
    {
      "key": "clientRef3",
      "value": "",
      "description": "clientRef سوم در ارسال گروهی؛ خودکار"
    },
    {
      "key": "taxId",
      "value": "",
      "description": "شماره مالیاتی آخرین ارسال موفق؛ خودکار پر می‌شود"
    },
    {
      "key": "referenceTaxId",
      "value": "",
      "description": "شماره مالیاتی صورتحساب مرجع برای اصلاحی/ابطالی/برگشت؛ بعد از هر ارسال موفق خودکار پر می‌شود"
    }
  ],
  "item": [
    {
      "name": "۱) احراز هویت",
      "item": [
        {
          "name": "دریافت توکن",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/auth/token",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "auth",
                "token"
              ]
            },
            "description": "با موبایل پنل، رمز پنل و کلید API توکن می‌گیرید. توکن خودکار در متغیر token ذخیره می‌شود و تا پایان اعتبارش (پیش‌فرض ۶۰ دقیقه) قابل استفاده است.\nبدون نیاز به توکن. سقف نرخ: ۲۰ درخواست در ۱۰ دقیقه برای هر IP. ۵ بار تلاش ناموفق برای یک کلید در ۱۵ دقیقه، آن کلید را موقتاً مسدود می‌کند.\nنیازی نیست هر بار این درخواست را اجرا کنید؛ پیش‌اسکریپت کالکشن در صورت نیاز خودش توکن می‌گیرد.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"mobile\": \"{{mobile}}\",\n  \"password\": \"{{password}}\",\n  \"apiKey\": \"{{apiKey}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "auth": {
              "type": "noauth"
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "// توکن و زمان انقضا را در متغیرهای کالکشن ذخیره می‌کند تا درخواست‌های بعدی خودکار از آن استفاده کنند",
                  "const j = pm.response.json();",
                  "pm.test('کد پاسخ 200', () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200 && j.success) {",
                  "  pm.collectionVariables.set('token', j.data.accessToken);",
                  "  pm.collectionVariables.set('tokenExpiresAt', String(Date.now() + (j.data.expiresIn || 3600) * 1000));",
                  "}"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"accessToken\": \"CfDJ8...\",\n    \"tokenType\": \"Bearer\",\n    \"expiresIn\": 3600\n  }\n}"
            },
            {
              "name": "400 قالب نادرست",
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invalid_request\",\n    \"message\": \"موبایل، رمز یا کلید API در قالب درست نیست.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "401 اطلاعات اشتباه",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invalid_credentials\",\n    \"message\": \"اطلاعات ورود یا کلید API نامعتبر است.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "429 تلاش ناموفق زیاد",
              "status": "Too Many Requests",
              "code": 429,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Retry-After",
                  "value": "600"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"too_many_attempts\",\n    \"message\": \"تلاش ناموفق بیش از حد مجاز بوده است؛ بعداً دوباره تلاش کنید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        },
        {
          "name": "اطلاعات حساب",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/me",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "me"
              ]
            },
            "description": "برای آزمایش اتصال و اطمینان از سالم‌بودن توکن. بدنه ندارد. سقف نرخ: ۱۲۰ درخواست در دقیقه برای هر توکن."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200', () => pm.expect([200]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"displayName\": \"شرکت نمونه\",\n    \"mobile\": \"09120000000\"\n  }\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "429 بیش از سقف نرخ",
              "status": "Too Many Requests",
              "code": 429,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Retry-After",
                  "value": "30"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"rate_limited\",\n    \"message\": \"تعداد درخواست‌ها بیش از حد مجاز است؛ کمی بعد دوباره تلاش کنید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        }
      ],
      "description": "دریافت توکن و آزمایش اتصال."
    },
    {
      "name": "۲) شماره اقتصادی",
      "item": [
        {
          "name": "فهرست",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/economic-ids",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "economic-ids"
              ]
            },
            "description": "همه‌ی شماره‌های اقتصادی حساب شما. کلید خصوصی و گواهی هرگز برگردانده نمی‌شوند؛ فقط hasPrivateKey و hasCertificate.\nنکته: در ارسال صورتحساب، economicId همان فیلد id همین فهرست است، نه خود کد اقتصادی. بعد از اجرا، id اولین شماره به‌طور خودکار در متغیر economicId ذخیره می‌شود.\nسقف نرخ: ۱۲۰ درخواست در دقیقه."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200', () => pm.expect([200]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                  "const items = (j.data && j.data.items) || [];",
                  "if (items.length) { pm.collectionVariables.set('economicId', String(items[0].id)); }"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": 12,\n        \"code\": \"10101234567\",\n        \"type\": 1,\n        \"name\": \"شرکت نمونه\",\n        \"branch\": null,\n        \"nationalId\": \"10101234567\",\n        \"memoryId\": \"A1B2C3\",\n        \"isTest\": true,\n        \"signingMode\": 1,\n        \"active\": true,\n        \"createdAt\": \"2026-10-20T08:15:00Z\",\n        \"hasPrivateKey\": true,\n        \"hasCertificate\": true,\n        \"hasInvoices\": false\n      }\n    ]\n  }\n}"
            },
            {
              "name": "200 هنوز شماره‌ای ثبت نشده",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"items\": []\n  }\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "429 بیش از سقف نرخ",
              "status": "Too Many Requests",
              "code": 429,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Retry-After",
                  "value": "30"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"rate_limited\",\n    \"message\": \"تعداد درخواست‌ها بیش از حد مجاز است؛ کمی بعد دوباره تلاش کنید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        },
        {
          "name": "ثبت؛ با گواهی امضا (آزمایشی)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/economic-ids",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "economic-ids"
              ]
            },
            "description": "ثبت شماره اقتصادی جدید با کلید خصوصی و گواهی. کلید باید با گواهی جفت باشد؛ گواهی در محیط عملیاتی نباید منقضی باشد.\ntype: 1 حقوقی · 2 حقیقی · 3 مشارکت مدنی · 4 اتباع غیرایرانی. طول code: ۱۱ رقم برای حقوقی و مشارکت مدنی، ۱۴ رقم برای حقیقی و اتباع. memoryId: ۶ نویسه‌ی حروف بزرگ انگلیسی یا عدد.\nکلید خصوصی: RSA حداقل ۲۰۴۸ بیت، بدون رمز، PEM یا Base64.\nسقف نرخ: ۳۰ درخواست نوشتنی در ۱۰ دقیقه. حجم بدنه حداکثر حدود ۶۰ کیلوبایت.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": 1,\n  \"name\": \"شرکت نمونه\",\n  \"branch\": \"شعبه مرکزی\",\n  \"code\": \"10101234567\",\n  \"nationalId\": \"10101234567\",\n  \"memoryId\": \"A1B2C3\",\n  \"isTest\": true,\n  \"signingMode\": 1,\n  \"privateKey\": \"-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----\",\n  \"certificate\": \"-----BEGIN CERTIFICATE-----\\n...\\n-----END CERTIFICATE-----\",\n  \"active\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 201/400/409/422', () => pm.expect([201, 400, 409, 422]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                  "if (pm.response.code === 201 && j.success) { pm.collectionVariables.set('economicId', String(j.data.id)); }"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "201 ثبت شد",
              "status": "Created",
              "code": 201,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": 12\n  }\n}"
            },
            {
              "name": "400 طول شماره اقتصادی",
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"validation_failed\",\n    \"message\": \"شماره اقتصادی شخص حقوقی باید دقیقاً ۱۱ رقم باشد.\",\n    \"field\": \"code\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "409 شماره تکراری در همین محیط",
              "status": "Conflict",
              "code": 409,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"conflict\",\n    \"message\": \"این شماره اقتصادی در همین محیط قبلاً ثبت شده است.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "429 بیش از سقف نرخ",
              "status": "Too Many Requests",
              "code": 429,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Retry-After",
                  "value": "30"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"rate_limited\",\n    \"message\": \"تعداد درخواست‌ها بیش از حد مجاز است؛ کمی بعد دوباره تلاش کنید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        },
        {
          "name": "ثبت؛ بدون گواهی (فقط کلید خصوصی)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/economic-ids",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "economic-ids"
              ]
            },
            "description": "signingMode = 2: فقط کلید خصوصی لازم است (certificate لازم نیست)، به شرط اینکه کلید عمومی متناظر را در کارپوشه‌ی سامانه مودیان ثبت کرده باشید.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": 2,\n  \"name\": \"نام شخص حقیقی\",\n  \"code\": \"12345678901234\",\n  \"nationalId\": \"0012345678\",\n  \"memoryId\": \"B2C3D4\",\n  \"isTest\": true,\n  \"signingMode\": 2,\n  \"privateKey\": \"-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 201/400/409/422', () => pm.expect([201, 400, 409, 422]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                  "if (pm.response.code === 201 && j.success) { pm.collectionVariables.set('economicId', String(j.data.id)); }"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "201 ثبت شد",
              "status": "Created",
              "code": 201,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": 13\n  }\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "429 بیش از سقف نرخ",
              "status": "Too Many Requests",
              "code": 429,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Retry-After",
                  "value": "30"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"rate_limited\",\n    \"message\": \"تعداد درخواست‌ها بیش از حد مجاز است؛ کمی بعد دوباره تلاش کنید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        },
        {
          "name": "ویرایش جزئی؛ نام و شعبه",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/economic-ids/{{economicId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "economic-ids",
                "{{economicId}}"
              ]
            },
            "description": "ویرایش جزئی است: فقط فیلدهایی را بفرستید که می‌خواهید تغییر کنند.\nحذف شماره اقتصادی از طریق API ممکن نیست و فقط از پنل انجام می‌شود. اگر با شماره صورتحساب ثبت شده باشد، تغییر code و محیط (isTest) رد می‌شود (422).\nسقف نرخ: ۳۰ درخواست نوشتنی در ۱۰ دقیقه.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"شرکت نمونه (نام جدید)\",\n  \"branch\": \"شعبه مرکزی\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200/400/404/422', () => pm.expect([200, 400, 404, 422]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": 12\n  }\n}"
            },
            {
              "name": "404 یافت نشد",
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"not_found\",\n    \"message\": \"شماره اقتصادی یافت نشد.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "422 تغییر کد/محیط پس از ثبت صورتحساب",
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"rule_violation\",\n    \"message\": \"با این شماره اقتصادی صورتحساب ثبت شده و تغییر کد یا محیط ممکن نیست.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "429 بیش از سقف نرخ",
              "status": "Too Many Requests",
              "code": 429,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Retry-After",
                  "value": "30"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"rate_limited\",\n    \"message\": \"تعداد درخواست‌ها بیش از حد مجاز است؛ کمی بعد دوباره تلاش کنید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        },
        {
          "name": "ویرایش؛ پاک‌کردن نام شعبه",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/economic-ids/{{economicId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "economic-ids",
                "{{economicId}}"
              ]
            },
            "description": "برای پاک‌کردن نام شعبه رشته‌ی خالی بفرستید.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"branch\": \"\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200/400/404/422', () => pm.expect([200, 400, 404, 422]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": 12\n  }\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        },
        {
          "name": "ویرایش؛ تغییر کلید و گواهی",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/economic-ids/{{economicId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "economic-ids",
                "{{economicId}}"
              ]
            },
            "description": "برای تغییر کلید یا گواهی، هر دو را با هم بفرستید تا تطبیق آن‌ها بررسی شود.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"privateKey\": \"-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----\",\n  \"certificate\": \"-----BEGIN CERTIFICATE-----\\n...\\n-----END CERTIFICATE-----\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200/400/404/422', () => pm.expect([200, 400, 404, 422]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": 12\n  }\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        },
        {
          "name": "غیرفعال‌سازی",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/economic-ids/{{economicId}}/active",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "economic-ids",
                "{{economicId}}",
                "active"
              ]
            },
            "description": "شماره‌ی غیرفعال در ارسال صورتحساب قابل انتخاب نیست. فیلد active الزامی است. سقف نرخ: ۳۰ درخواست نوشتنی در ۱۰ دقیقه.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"active\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200/400/404', () => pm.expect([200, 400, 404]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": 12,\n    \"active\": false\n  }\n}"
            },
            {
              "name": "400 فیلد active ارسال نشده",
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"validation_failed\",\n    \"message\": \"فیلد active (true یا false) الزامی است.\",\n    \"field\": \"active\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "404 یافت نشد",
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"not_found\",\n    \"message\": \"شماره اقتصادی یافت نشد.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        },
        {
          "name": "فعال‌سازی",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/economic-ids/{{economicId}}/active",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "economic-ids",
                "{{economicId}}",
                "active"
              ]
            },
            "description": "فعال‌کردن دوباره‌ی شماره اقتصادی.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"active\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200/400/404', () => pm.expect([200, 400, 404]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"id\": 12,\n    \"active\": true\n  }\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        }
      ],
      "description": "مدیریت شماره‌های اقتصادی. حذف فقط از پنل ممکن است."
    },
    {
      "name": "۳) مالی",
      "item": [
        {
          "name": "مانده اعتبار",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/credit/balance",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "credit",
                "balance"
              ]
            },
            "description": "فقط‌خواندنی؛ شارژ حساب از طریق پنل انجام می‌شود. balance با همان واحد پنل، invoiceFee هزینه‌ی هر صورتحساب و remainingInvoices تعداد صورتحساب قابل ارسال با مانده‌ی فعلی (در صورت نبود هزینه‌ی تعریف‌شده null) است.\nقبل از ارسال گروهی بزرگ مانده را بررسی کنید. سقف نرخ: ۱۲۰ درخواست در دقیقه."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200', () => pm.expect([200]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"balance\": 1500000,\n    \"invoiceFee\": 3000,\n    \"remainingInvoices\": 500\n  }\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "429 بیش از سقف نرخ",
              "status": "Too Many Requests",
              "code": 429,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Retry-After",
                  "value": "30"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"rate_limited\",\n    \"message\": \"تعداد درخواست‌ها بیش از حد مجاز است؛ کمی بعد دوباره تلاش کنید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        }
      ],
      "description": "مانده‌ی اعتبار."
    },
    {
      "name": "۴) صورتحساب",
      "item": [
        {
          "name": "۴-۱) ارسال تکی",
          "item": [
            {
              "name": "۱ فروش نوع اول؛ تسویه نقدی",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "ساده‌ترین حالت: موضوع اصلی، الگوی فروش، نوع اول، خریدار حقوقی، تسویه نقدی (setm=1).\nپاسخ 201 یعنی «ثبت و در صف ارسال قرار گرفت»؛ تأیید سامانه مودیان بعداً و خودکار انجام می‌شود و وضعیت نهایی را باید استعلام بگیرید.\nمبالغ ردیف (prdis، adis، vam، tsstam) را اگر نفرستید سرور با همان فرمول پنل حساب می‌کند.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.\nسقف نرخ: ۶۰ درخواست در دقیقه برای هر توکن. بدنه حداکثر ۱ مگابایت و ۵۰۰ ردیف.\nهشدار: هر صورتحساب ثبت‌شده از اعتبار حساب کم می‌شود؛ برای آزمایش از شماره اقتصادی «آزمایشی» استفاده کنید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 1,\n  \"pattern\": 1,\n  \"type\": 1,\n  \"buyerType\": 2,\n  \"buyer\": {\n    \"tinb\": \"10101234567\"\n  },\n  \"headerExtra\": {\n    \"setm\": 1\n  },\n  \"items\": [\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه\",\n      \"am\": 2,\n      \"fee\": 1000000,\n      \"vra\": 10\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/201/400/402/404/409/422', () => pm.expect([200, 201, 400, 402, 404, 409, 422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (j.success && j.data && j.data.taxId) {",
                      "  pm.collectionVariables.set('taxId', j.data.taxId);",
                      "  pm.collectionVariables.set('referenceTaxId', j.data.taxId);   // برای اصلاحی/ابطالی/برگشت",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "201 ثبت و در صف",
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"queued\",\n    \"duplicate\": false\n  }\n}"
                },
                {
                  "name": "400 فیلد نامعتبر",
                  "status": "Bad Request",
                  "code": 400,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"validation_failed\",\n    \"message\": \"pattern (الگوی صورتحساب) الزامی است.\",\n    \"field\": \"pattern\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "402 اعتبار کافی نیست",
                  "status": "Payment Required",
                  "code": 402,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"insufficient_credit\",\n    \"message\": \"اعتبار حساب برای ثبت این صورتحساب کافی نیست.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "422 اعتبارسنجی ناموفق (چیزی ثبت نشد)",
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invoice_invalid\",\n    \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n    \"details\": [\n      \"ردیف 1: شناسه کالا/خدمت «1234567890123» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "404 شماره اقتصادی یافت نشد",
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"not_found\",\n    \"message\": \"شماره اقتصادی یافت نشد.\",\n    \"field\": \"economicId\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "429 بیش از سقف نرخ",
                  "status": "Too Many Requests",
                  "code": 429,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    },
                    {
                      "key": "Retry-After",
                      "value": "30"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"rate_limited\",\n    \"message\": \"تعداد درخواست‌ها بیش از حد مجاز است؛ کمی بعد دوباره تلاش کنید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "۲ فروش نوع اول؛ تسویه نسیه",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "setm=2: تسویه نسیه. در این حالت مبلغ پرداختی صفر است و ارسال payment لازم نیست.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 1,\n  \"pattern\": 1,\n  \"type\": 1,\n  \"buyerType\": 2,\n  \"buyer\": {\n    \"tinb\": \"10101234567\"\n  },\n  \"headerExtra\": {\n    \"setm\": 2\n  },\n  \"items\": [\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه\",\n      \"am\": 2,\n      \"fee\": 1000000,\n      \"vra\": 10\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/201/400/402/404/409/422', () => pm.expect([200, 201, 400, 402, 404, 409, 422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (j.success && j.data && j.data.taxId) {",
                      "  pm.collectionVariables.set('taxId', j.data.taxId);",
                      "  pm.collectionVariables.set('referenceTaxId', j.data.taxId);   // برای اصلاحی/ابطالی/برگشت",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "201 ثبت و در صف",
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"queued\",\n    \"duplicate\": false\n  }\n}"
                },
                {
                  "name": "422 اعتبارسنجی ناموفق (چیزی ثبت نشد)",
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invoice_invalid\",\n    \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n    \"details\": [\n      \"ردیف 1: شناسه کالا/خدمت «1234567890123» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "۳ فروش نوع اول؛ نقدی/نسیه",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "setm=3: تسویه‌ی ترکیبی. هر دو مبلغ cap (نقدی) و insp (نسیه) باید بیشتر از صفر باشند و مجموعشان با مبلغ بعد از تخفیف برابر شود. در این نمونه مبلغ بعد از تخفیف = ۲×۱٬۰۰۰٬۰۰۰ = ۲٬۰۰۰٬۰۰۰ ریال است.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 1,\n  \"pattern\": 1,\n  \"type\": 1,\n  \"buyerType\": 2,\n  \"buyer\": {\n    \"tinb\": \"10101234567\"\n  },\n  \"headerExtra\": {\n    \"setm\": 3,\n    \"cap\": 1200000,\n    \"insp\": 800000\n  },\n  \"items\": [\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه\",\n      \"am\": 2,\n      \"fee\": 1000000,\n      \"vra\": 10\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/201/400/402/404/409/422', () => pm.expect([200, 201, 400, 402, 404, 409, 422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (j.success && j.data && j.data.taxId) {",
                      "  pm.collectionVariables.set('taxId', j.data.taxId);",
                      "  pm.collectionVariables.set('referenceTaxId', j.data.taxId);   // برای اصلاحی/ابطالی/برگشت",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "201 ثبت و در صف",
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"queued\",\n    \"duplicate\": false\n  }\n}"
                },
                {
                  "name": "422 اعتبارسنجی ناموفق (چیزی ثبت نشد)",
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invoice_invalid\",\n    \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n    \"details\": [\n      \"ردیف 1: شناسه کالا/خدمت «1234567890123» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "۴ فروش نوع اول؛ همراه اطلاعات پرداخت",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "payment اختیاری است. اگر ثبت می‌کنید pmt (روش پرداخت ۱ تا ۸) و pv (مبلغ پرداختی) هر دو لازم‌اند. pdt (زمان پرداخت) میلی‌ثانیه‌ی یونیکس و ۱۳ رقمی است.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 1,\n  \"pattern\": 1,\n  \"type\": 1,\n  \"buyerType\": 2,\n  \"buyer\": {\n    \"tinb\": \"10101234567\"\n  },\n  \"headerExtra\": {\n    \"setm\": 1\n  },\n  \"items\": [\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه\",\n      \"am\": 2,\n      \"fee\": 1000000,\n      \"vra\": 10\n    }\n  ],\n  \"payment\": {\n    \"pmt\": 4,\n    \"pv\": 2200000,\n    \"pdt\": 1761809400000\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/201/400/402/404/409/422', () => pm.expect([200, 201, 400, 402, 404, 409, 422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (j.success && j.data && j.data.taxId) {",
                      "  pm.collectionVariables.set('taxId', j.data.taxId);",
                      "  pm.collectionVariables.set('referenceTaxId', j.data.taxId);   // برای اصلاحی/ابطالی/برگشت",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "201 ثبت و در صف",
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"queued\",\n    \"duplicate\": false\n  }\n}"
                },
                {
                  "name": "422 اعتبارسنجی ناموفق (چیزی ثبت نشد)",
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invoice_invalid\",\n    \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n    \"details\": [\n      \"ردیف 1: شناسه کالا/خدمت «1234567890123» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "۵ فروش نوع دوم",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "نوع دوم: تسویه نقدی فرض می‌شود و setm/cap/insp و ثبت اطلاعات پرداخت لازم نیست. در نوع دوم و سوم فقط الگوهای فروش، طلا و جواهر، فرآورده‌های نفتی و خدمات بیمه‌ای مجازند.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 1,\n  \"pattern\": 1,\n  \"type\": 2,\n  \"buyerType\": 2,\n  \"buyer\": {\n    \"tinb\": \"10101234567\"\n  },\n  \"headerExtra\": {},\n  \"items\": [\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه\",\n      \"am\": 2,\n      \"fee\": 1000000,\n      \"vra\": 10\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/201/400/402/404/409/422', () => pm.expect([200, 201, 400, 402, 404, 409, 422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (j.success && j.data && j.data.taxId) {",
                      "  pm.collectionVariables.set('taxId', j.data.taxId);",
                      "  pm.collectionVariables.set('referenceTaxId', j.data.taxId);   // برای اصلاحی/ابطالی/برگشت",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "201 ثبت و در صف",
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"queued\",\n    \"duplicate\": false\n  }\n}"
                },
                {
                  "name": "422 اعتبارسنجی ناموفق (چیزی ثبت نشد)",
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invoice_invalid\",\n    \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n    \"details\": [\n      \"ردیف 1: شناسه کالا/خدمت «1234567890123» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "۶ فروش نوع سوم؛ اطلاعات پایانه‌ی پرداخت",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "نوع سوم: ثبت اطلاعات پایانه‌ی پرداخت الزامی است: iinn (شماره سوئیچ، ۹ رقم)، acn (شماره پذیرنده، ۱۴ رقم)، trmn (شماره پایانه، ۸ رقم)، trn (شماره پیگیری، حداکثر ۱۴ رقم)، pcn (شماره کارت پرداخت‌کننده، ۱۶ رقم)، pid (شماره/شناسه ملی پرداخت‌کننده، حداکثر ۱۲ رقم)، pmt و pv.\nمقادیر نمونه فرضی‌اند.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 1,\n  \"pattern\": 1,\n  \"type\": 3,\n  \"buyerType\": 2,\n  \"buyer\": {\n    \"tinb\": \"10101234567\"\n  },\n  \"headerExtra\": {},\n  \"items\": [\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه\",\n      \"am\": 2,\n      \"fee\": 1000000,\n      \"vra\": 10\n    }\n  ],\n  \"payment\": {\n    \"iinn\": \"123456789\",\n    \"acn\": \"12345678901234\",\n    \"trmn\": \"12345678\",\n    \"trn\": \"1234567890\",\n    \"pcn\": \"6037991234567890\",\n    \"pid\": \"0012345678\",\n    \"pmt\": 4,\n    \"pv\": 2200000\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/201/400/402/404/409/422', () => pm.expect([200, 201, 400, 402, 404, 409, 422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (j.success && j.data && j.data.taxId) {",
                      "  pm.collectionVariables.set('taxId', j.data.taxId);",
                      "  pm.collectionVariables.set('referenceTaxId', j.data.taxId);   // برای اصلاحی/ابطالی/برگشت",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "201 ثبت و در صف",
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"queued\",\n    \"duplicate\": false\n  }\n}"
                },
                {
                  "name": "422 اعتبارسنجی ناموفق (چیزی ثبت نشد)",
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invoice_invalid\",\n    \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n    \"details\": [\n      \"ردیف 1: شناسه کالا/خدمت «1234567890123» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "۷ خریدار حقیقی (شناسه + کد پستی)",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "وقتی خریدار شماره اقتصادی ندارد، شناسه/کد ملی (bid) و کد پستی (bpc) او را بفرستید. اطلاعات لازم به الگو و نوع خریدار بستگی دارد و پیام خطا دقیق می‌گوید.\nbuyerType: 1 حقیقی · 2 حقوقی · 3 مشارکت مدنی · 4 اتباع غیرایرانی.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 1,\n  \"pattern\": 1,\n  \"type\": 1,\n  \"buyerType\": 1,\n  \"buyer\": {\n    \"bid\": \"0012345678\",\n    \"bpc\": \"1234567890\"\n  },\n  \"headerExtra\": {\n    \"setm\": 1\n  },\n  \"items\": [\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه\",\n      \"am\": 2,\n      \"fee\": 1000000,\n      \"vra\": 10\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/201/400/402/404/409/422', () => pm.expect([200, 201, 400, 402, 404, 409, 422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (j.success && j.data && j.data.taxId) {",
                      "  pm.collectionVariables.set('taxId', j.data.taxId);",
                      "  pm.collectionVariables.set('referenceTaxId', j.data.taxId);   // برای اصلاحی/ابطالی/برگشت",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "201 ثبت و در صف",
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"queued\",\n    \"duplicate\": false\n  }\n}"
                },
                {
                  "name": "422 اعتبارسنجی ناموفق (چیزی ثبت نشد)",
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invoice_invalid\",\n    \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n    \"details\": [\n      \"ردیف 1: شناسه کالا/خدمت «1234567890123» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "۸ زمان صدور مشخص، تخفیف و چند ردیف",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "issuedAt: زمان صدور به‌صورت ISO 8601 (خالی = همین الان؛ زمان آینده پذیرفته نمی‌شود). dis تخفیف ردیف (ریال)، پیش‌فرض ۰. حداکثر ۵۰۰ ردیف.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 1,\n  \"pattern\": 1,\n  \"type\": 1,\n  \"buyerType\": 2,\n  \"buyer\": {\n    \"tinb\": \"10101234567\"\n  },\n  \"headerExtra\": {\n    \"setm\": 1\n  },\n  \"items\": [\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه\",\n      \"am\": 2,\n      \"fee\": 1000000,\n      \"dis\": 100000,\n      \"vra\": 10\n    },\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه (ردیف دوم)\",\n      \"am\": 1,\n      \"fee\": 500000,\n      \"vra\": 10\n    }\n  ],\n  \"issuedAt\": \"2026-10-27T09:30:00+03:30\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/201/400/402/404/409/422', () => pm.expect([200, 201, 400, 402, 404, 409, 422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (j.success && j.data && j.data.taxId) {",
                      "  pm.collectionVariables.set('taxId', j.data.taxId);",
                      "  pm.collectionVariables.set('referenceTaxId', j.data.taxId);   // برای اصلاحی/ابطالی/برگشت",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "201 ثبت و در صف",
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"queued\",\n    \"duplicate\": false\n  }\n}"
                },
                {
                  "name": "422 اعتبارسنجی ناموفق (چیزی ثبت نشد)",
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invoice_invalid\",\n    \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n    \"details\": [\n      \"ردیف 1: شناسه کالا/خدمت «1234567890123» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "۹ ارسال خارج از مهلت (ماده ۹)",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "article9=true: ارسال خارج از مهلت طبق ماده ۹ قانون پایانه‌های فروشگاهی.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 1,\n  \"pattern\": 1,\n  \"type\": 1,\n  \"buyerType\": 2,\n  \"buyer\": {\n    \"tinb\": \"10101234567\"\n  },\n  \"headerExtra\": {\n    \"setm\": 1\n  },\n  \"items\": [\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه\",\n      \"am\": 2,\n      \"fee\": 1000000,\n      \"vra\": 10\n    }\n  ],\n  \"issuedAt\": \"2026-10-01T09:30:00+03:30\",\n  \"article9\": true\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/201/400/402/404/409/422', () => pm.expect([200, 201, 400, 402, 404, 409, 422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (j.success && j.data && j.data.taxId) {",
                      "  pm.collectionVariables.set('taxId', j.data.taxId);",
                      "  pm.collectionVariables.set('referenceTaxId', j.data.taxId);   // برای اصلاحی/ابطالی/برگشت",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "201 ثبت و در صف",
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"queued\",\n    \"duplicate\": false\n  }\n}"
                },
                {
                  "name": "422 اعتبارسنجی ناموفق (چیزی ثبت نشد)",
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invoice_invalid\",\n    \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n    \"details\": [\n      \"ردیف 1: شناسه کالا/خدمت «1234567890123» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "۱۰ تأیید هشدار «مبلغ غیرعادی»",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "اگر مبلغ نسبت به سابقه‌ی همین شماره اقتصادی یا سقف تعیین‌شده در پنل غیرعادی باشد، پاسخ 409 amount_warning می‌گیرید. اگر مبلغ درست است، همان درخواست را با ackAmountWarning=true دوباره بفرستید. این نمونه مبلغ زیاد دارد.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 1,\n  \"pattern\": 1,\n  \"type\": 1,\n  \"buyerType\": 2,\n  \"buyer\": {\n    \"tinb\": \"10101234567\"\n  },\n  \"headerExtra\": {\n    \"setm\": 1\n  },\n  \"items\": [\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه\",\n      \"am\": 1,\n      \"fee\": 900000000,\n      \"vra\": 10\n    }\n  ],\n  \"ackAmountWarning\": true\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/201/400/402/404/409/422', () => pm.expect([200, 201, 400, 402, 404, 409, 422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (j.success && j.data && j.data.taxId) {",
                      "  pm.collectionVariables.set('taxId', j.data.taxId);",
                      "  pm.collectionVariables.set('referenceTaxId', j.data.taxId);   // برای اصلاحی/ابطالی/برگشت",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "409 مبلغ غیرعادی (بدون ackAmountWarning)",
                  "status": "Conflict",
                  "code": 409,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"amount_warning\",\n    \"message\": \"مبلغ صورتحساب غیرعادی است. اگر مبلغ درست است، همان درخواست را با ackAmountWarning=true دوباره بفرستید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "201 ثبت و در صف",
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"queued\",\n    \"duplicate\": false\n  }\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "۱۱ تکرار با همان clientRef (ارسال تکراری)",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "بدنه‌ی این درخواست دقیقاً مثل «۱ فروش نوع اول؛ تسویه نقدی» است و clientRef را عوض نمی‌کند. اول «۱» را اجرا کنید و بعد این را: صورتحساب تازه‌ای ساخته نمی‌شود و پاسخ 200 با duplicate=true و هدر Idempotent-Replayed می‌گیرید.\nاگر همان clientRef با محتوای دیگر بیاید 409 idempotency_conflict، و اگر درخواست قبلی هنوز در جریان باشد 409 request_in_progress (هدر Retry-After) می‌گیرید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 1,\n  \"pattern\": 1,\n  \"type\": 1,\n  \"buyerType\": 2,\n  \"buyer\": {\n    \"tinb\": \"10101234567\"\n  },\n  \"headerExtra\": {\n    \"setm\": 1\n  },\n  \"items\": [\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه\",\n      \"am\": 2,\n      \"fee\": 1000000,\n      \"vra\": 10\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/409', () => pm.expect([200, 409]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (pm.response.code === 200) { pm.test('duplicate = true', () => pm.expect(j.data.duplicate).to.eql(true)); }"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "200 تکراری (همان clientRef و همان محتوا)",
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    },
                    {
                      "key": "Idempotent-Replayed",
                      "value": "true"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"processing\",\n    \"message\": null,\n    \"referenceNumber\": null,\n    \"duplicate\": true\n  }\n}"
                },
                {
                  "name": "409 همان clientRef با محتوای دیگر",
                  "status": "Conflict",
                  "code": 409,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"idempotency_conflict\",\n    \"message\": \"این clientRef قبلاً با محتوای دیگری استفاده شده است. برای صورتحساب جدید clientRef تازه بفرستید.\",\n    \"field\": \"clientRef\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "409 درخواست قبلی در جریان است",
                  "status": "Conflict",
                  "code": 409,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    },
                    {
                      "key": "Retry-After",
                      "value": "5"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"request_in_progress\",\n    \"message\": \"درخواست قبلی با همین clientRef هنوز در حال پردازش است.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "۱۲ نمونه‌ی خطا؛ اعتبارسنجی ناموفق",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "عمداً شناسه‌ی کالا/خدمت نامعتبر می‌فرستد تا پاسخ 422 invoice_invalid را ببینید: هیچ‌چیز ثبت نمی‌شود، اعتباری کم نمی‌شود و همه‌ی خطاها یک‌جا در error.details می‌آید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 1,\n  \"pattern\": 1,\n  \"type\": 1,\n  \"buyerType\": 2,\n  \"buyer\": {\n    \"tinb\": \"10101234567\"\n  },\n  \"headerExtra\": {\n    \"setm\": 1\n  },\n  \"items\": [\n    {\n      \"sstid\": \"0000000000000\",\n      \"sstt\": \"کالای نامعتبر\",\n      \"am\": 1,\n      \"fee\": 1000,\n      \"vra\": 10\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 422', () => pm.expect([422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "pm.test('فهرست خطاها', () => pm.expect(j.error.details).to.be.an('array'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "422 اعتبارسنجی ناموفق (چیزی ثبت نشد)",
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invoice_invalid\",\n    \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n    \"details\": [\n      \"ردیف 1: شناسه کالا/خدمت «1234567890123» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            }
          ],
          "description": "ارسال صورتحساب. هر ارسال یک clientRef یکتا دارد؛ پیش‌اسکریپت آن را خودکار می‌سازد. برای الگوهای دیگر (فروش ارز، طلا و جواهر، بارنامه و ...) فیلدهای مخصوص الگو را در headerExtra، items یا transportedGoods بفرستید؛ پیام خطا دقیق می‌گوید چه چیزی لازم است."
        },
        {
          "name": "۴-۲) اصلاحی، ابطالی و برگشت از فروش",
          "item": [
            {
              "name": "اصلاحی (subject = 2)",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "اصلاح اطلاعات یک صورتحساب ارسال‌شده. صورتحساب ارسال‌شده مستقیم ویرایش نمی‌شود؛ سند جدید ثبت می‌شود.\nreferenceTaxId شماره‌ی مالیاتی صورتحساب مرجع است (بعد از هر ارسال موفق خودکار در متغیر referenceTaxId ذخیره می‌شود). مرجع باید با موفقیت ثبت شده و متعلق به حساب شما باشد.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 2,\n  \"pattern\": 1,\n  \"type\": 1,\n  \"buyerType\": 2,\n  \"buyer\": {\n    \"tinb\": \"10101234567\"\n  },\n  \"headerExtra\": {\n    \"setm\": 1\n  },\n  \"items\": [\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه\",\n      \"am\": 2,\n      \"fee\": 1000000,\n      \"vra\": 10\n    }\n  ],\n  \"referenceTaxId\": \"{{referenceTaxId}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/201/400/402/404/409/422', () => pm.expect([200, 201, 400, 402, 404, 409, 422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (j.success && j.data && j.data.taxId) {",
                      "  pm.collectionVariables.set('taxId', j.data.taxId);",
                      "  pm.collectionVariables.set('referenceTaxId', j.data.taxId);   // برای اصلاحی/ابطالی/برگشت",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "201 ثبت و در صف",
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"queued\",\n    \"duplicate\": false\n  }\n}"
                },
                {
                  "name": "422 اعتبارسنجی ناموفق (چیزی ثبت نشد)",
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invoice_invalid\",\n    \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n    \"details\": [\n      \"ردیف 1: شناسه کالا/خدمت «1234567890123» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "ابطالی (subject = 3)",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "برگشت کامل کل صورتحساب. الگو، نوع، خریدار و اقلام از صورتحساب مرجع گرفته می‌شود و فقط clientRef و economicId و referenceTaxId لازم است.\nreferenceTaxId شماره‌ی مالیاتی صورتحساب مرجع است (بعد از هر ارسال موفق خودکار در متغیر referenceTaxId ذخیره می‌شود). مرجع باید با موفقیت ثبت شده و متعلق به حساب شما باشد.\n",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 3,\n  \"referenceTaxId\": \"{{referenceTaxId}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/201/400/402/404/409/422', () => pm.expect([200, 201, 400, 402, 404, 409, 422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (j.success && j.data && j.data.taxId) {",
                      "  pm.collectionVariables.set('taxId', j.data.taxId);",
                      "  pm.collectionVariables.set('referenceTaxId', j.data.taxId);   // برای اصلاحی/ابطالی/برگشت",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "201 ثبت و در صف",
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"queued\",\n    \"duplicate\": false\n  }\n}"
                },
                {
                  "name": "422 اعتبارسنجی ناموفق (چیزی ثبت نشد)",
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invoice_invalid\",\n    \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n    \"details\": [\n      \"ردیف 1: شناسه کالا/خدمت «1234567890123» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "برگشت از فروش (subject = 4)",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices"
                  ]
                },
                "description": "«مانده‌ی فروش پس از برگشت» را ثبت می‌کنید، نه تعداد برگشتی را. مثلاً اگر ۴ عدد از ۱۰ عدد برگشت خورد، am = ۶ بفرستید. اگر کل صورتحساب برگشت می‌خورد، به‌جای این از «ابطالی» استفاده کنید.\nreferenceTaxId شماره‌ی مالیاتی صورتحساب مرجع است (بعد از هر ارسال موفق خودکار در متغیر referenceTaxId ذخیره می‌شود). مرجع باید با موفقیت ثبت شده و متعلق به حساب شما باشد.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRef\": \"{{clientRef}}\",\n  \"economicId\": {{economicId}},\n  \"subject\": 4,\n  \"pattern\": 1,\n  \"type\": 1,\n  \"buyerType\": 2,\n  \"buyer\": {\n    \"tinb\": \"10101234567\"\n  },\n  \"headerExtra\": {\n    \"setm\": 1\n  },\n  \"items\": [\n    {\n      \"sstid\": \"1234567890123\",\n      \"sstt\": \"خدمات نمونه\",\n      \"am\": 1,\n      \"fee\": 1000000,\n      \"vra\": 10\n    }\n  ],\n  \"referenceTaxId\": \"{{referenceTaxId}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "// clientRef یکتا برای هر ارسال (۸ تا ۶۴ نویسه؛ حروف انگلیسی، عدد و . _ : -)",
                      "pm.collectionVariables.set('clientRef', 'PM-' + Date.now() + '-' + Math.floor(Math.random() * 10000));"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/201/400/402/404/409/422', () => pm.expect([200, 201, 400, 402, 404, 409, 422]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (j.success && j.data && j.data.taxId) {",
                      "  pm.collectionVariables.set('taxId', j.data.taxId);",
                      "  pm.collectionVariables.set('referenceTaxId', j.data.taxId);   // برای اصلاحی/ابطالی/برگشت",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "201 ثبت و در صف",
                  "status": "Created",
                  "code": 201,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"status\": \"queued\",\n    \"duplicate\": false\n  }\n}"
                },
                {
                  "name": "422 اعتبارسنجی ناموفق (چیزی ثبت نشد)",
                  "status": "Unprocessable Entity",
                  "code": 422,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"invoice_invalid\",\n    \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n    \"details\": [\n      \"ردیف 1: شناسه کالا/خدمت «1234567890123» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            }
          ],
          "description": "اصلاحی، ابطالی و برگشت از فروش همگی با همان مسیر POST /v1/invoices و با موضوع (subject) و referenceTaxId ثبت می‌شوند. ابتدا یک صورتحساب اصلی ثبت کنید تا referenceTaxId پر شود."
        },
        {
          "name": "۴-۴) ارسال گروهی",
          "item": [
            {
              "name": "دسته‌ی ۲ تایی (همه معتبر)",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices/batch",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices",
                    "batch"
                  ]
                },
                "description": "حداکثر ۵۰ صورتحساب در هر درخواست (بدنه تا ۵ مگابایت). هر مورد دقیقاً مثل ارسال تکی پردازش می‌شود (همان اعتبارسنجی، clientRef و محاسبه‌ی مبالغ) و شکست یک مورد بقیه را متوقف نمی‌کند.\nکد 200 یعنی «درخواست پردازش شد»، نه «همه ثبت شدند»؛ موفقیت هر مورد را در results[i].ok بررسی کنید. فهرست خالی یا بیش از ۵۰ مورد، کل درخواست را با 400 رد می‌کند.\nسقف نرخ: ۱۰ درخواست در دقیقه برای هر توکن. timeout سمت خودتان را حداقل ۶۰ ثانیه بگذارید.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.\nهشدار: هر صورتحساب ثبت‌شده از اعتبار حساب کم می‌شود؛ برای آزمایش از شماره اقتصادی «آزمایشی» استفاده کنید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"invoices\": [\n    {\n      \"clientRef\": \"{{clientRef1}}\",\n      \"economicId\": {{economicId}},\n      \"subject\": 1,\n      \"pattern\": 1,\n      \"type\": 1,\n      \"buyerType\": 2,\n      \"buyer\": {\n        \"tinb\": \"10101234567\"\n      },\n      \"headerExtra\": {\n        \"setm\": 1\n      },\n      \"items\": [\n        {\n          \"sstid\": \"1234567890123\",\n          \"sstt\": \"خدمات نمونه\",\n          \"am\": 1,\n          \"fee\": 1000000,\n          \"vra\": 10\n        }\n      ]\n    },\n    {\n      \"clientRef\": \"{{clientRef2}}\",\n      \"economicId\": {{economicId}},\n      \"subject\": 1,\n      \"pattern\": 1,\n      \"type\": 1,\n      \"buyerType\": 2,\n      \"buyer\": {\n        \"tinb\": \"10101234567\"\n      },\n      \"headerExtra\": {\n        \"setm\": 1\n      },\n      \"items\": [\n        {\n          \"sstid\": \"1234567890123\",\n          \"sstt\": \"خدمات نمونه\",\n          \"am\": 1,\n          \"fee\": 500000,\n          \"vra\": 10\n        }\n      ]\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "const ts = Date.now();",
                      "pm.collectionVariables.set('clientRef1', 'PM-B1-' + ts);",
                      "pm.collectionVariables.set('clientRef2', 'PM-B2-' + ts);",
                      "pm.collectionVariables.set('clientRef3', 'PM-B3-' + ts);"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/400', () => pm.expect([200, 400]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));",
                      "if (pm.response.code === 200) {",
                      "  pm.test('summary و results', () => { pm.expect(j.data.summary).to.have.property('total'); pm.expect(j.data.results).to.be.an('array'); });",
                      "  const first = j.data.results.find(r => r.ok && r.taxId);",
                      "  if (first) { pm.collectionVariables.set('taxId', first.taxId); pm.collectionVariables.set('referenceTaxId', first.taxId); }",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "200 همه ثبت شد",
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"summary\": {\n      \"total\": 2,\n      \"accepted\": 2,\n      \"replayed\": 0,\n      \"failed\": 0\n    },\n    \"results\": [\n      {\n        \"index\": 0,\n        \"clientRef\": \"PM-B1-1761800000000\",\n        \"ok\": true,\n        \"taxId\": \"A12B34C0000000123456XY\",\n        \"status\": \"queued\",\n        \"duplicate\": false\n      },\n      {\n        \"index\": 1,\n        \"clientRef\": \"PM-B2-1761800000000\",\n        \"ok\": true,\n        \"taxId\": \"A12B34C0000000123457XZ\",\n        \"status\": \"queued\",\n        \"duplicate\": false\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "400 فهرست خالی یا بیش از ۵۰ مورد",
                  "status": "Bad Request",
                  "code": 400,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"validation_failed\",\n    \"message\": \"تعداد صورتحساب‌ها باید بین ۱ تا ۵۰ باشد.\",\n    \"field\": \"invoices\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "429 بیش از سقف نرخ",
                  "status": "Too Many Requests",
                  "code": 429,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    },
                    {
                      "key": "Retry-After",
                      "value": "30"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"rate_limited\",\n    \"message\": \"تعداد درخواست‌ها بیش از حد مجاز است؛ کمی بعد دوباره تلاش کنید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "دسته‌ی دارای مورد ناموفق و clientRef تکراری",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices/batch",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices",
                    "batch"
                  ]
                },
                "description": "نمونه‌ی نتیجه‌ی ترکیبی: مورد اول معتبر، مورد دوم شناسه‌ی کالای نامعتبر و مورد سوم clientRef تکراری در همین درخواست دارد. شکست مورد دوم و سوم مانع ثبت مورد اول نمی‌شود.\nدر error.field مسیر کامل فیلد می‌آید (مثل invoices[2].clientRef). اگر وسط دسته اعتبار تمام شود، موارد بعدی با 402 insufficient_credit رد می‌شوند.\nمقدار sstid نمونه است؛ شناسه‌ی واقعی کالا/خدمت خودتان را (۱۳ رقم، موجود در فهرست رسمی) بگذارید.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"invoices\": [\n    {\n      \"clientRef\": \"{{clientRef1}}\",\n      \"economicId\": {{economicId}},\n      \"subject\": 1,\n      \"pattern\": 1,\n      \"type\": 1,\n      \"buyerType\": 2,\n      \"buyer\": {\n        \"tinb\": \"10101234567\"\n      },\n      \"headerExtra\": {\n        \"setm\": 1\n      },\n      \"items\": [\n        {\n          \"sstid\": \"1234567890123\",\n          \"sstt\": \"خدمات نمونه\",\n          \"am\": 1,\n          \"fee\": 1000000,\n          \"vra\": 10\n        }\n      ]\n    },\n    {\n      \"clientRef\": \"{{clientRef2}}\",\n      \"economicId\": {{economicId}},\n      \"subject\": 1,\n      \"pattern\": 1,\n      \"type\": 1,\n      \"buyerType\": 2,\n      \"buyer\": {\n        \"tinb\": \"10101234567\"\n      },\n      \"headerExtra\": {\n        \"setm\": 1\n      },\n      \"items\": [\n        {\n          \"sstid\": \"0000000000000\",\n          \"sstt\": \"کالای نامعتبر\",\n          \"am\": 1,\n          \"fee\": 1000,\n          \"vra\": 10\n        }\n      ]\n    },\n    {\n      \"clientRef\": \"{{clientRef1}}\",\n      \"economicId\": {{economicId}},\n      \"subject\": 1,\n      \"pattern\": 1,\n      \"type\": 1,\n      \"buyerType\": 2,\n      \"buyer\": {\n        \"tinb\": \"10101234567\"\n      },\n      \"headerExtra\": {\n        \"setm\": 1\n      },\n      \"items\": [\n        {\n          \"sstid\": \"1234567890123\",\n          \"sstt\": \"خدمات نمونه\",\n          \"am\": 1,\n          \"fee\": 750000,\n          \"vra\": 10\n        }\n      ]\n    }\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "const ts = Date.now();",
                      "pm.collectionVariables.set('clientRef1', 'PM-B1-' + ts);",
                      "pm.collectionVariables.set('clientRef2', 'PM-B2-' + ts);",
                      "pm.collectionVariables.set('clientRef3', 'PM-B3-' + ts);"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/400', () => pm.expect([200, 400]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "200 نتیجه‌ی ترکیبی",
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"summary\": {\n      \"total\": 3,\n      \"accepted\": 1,\n      \"replayed\": 0,\n      \"failed\": 2\n    },\n    \"results\": [\n      {\n        \"index\": 0,\n        \"clientRef\": \"PM-B1-1761800000000\",\n        \"ok\": true,\n        \"taxId\": \"A12B34C0000000123456XY\",\n        \"status\": \"queued\",\n        \"duplicate\": false\n      },\n      {\n        \"index\": 1,\n        \"clientRef\": \"PM-B2-1761800000000\",\n        \"ok\": false,\n        \"error\": {\n          \"code\": \"invoice_invalid\",\n          \"message\": \"اعتبارسنجی صورتحساب ناموفق بود (1 خطا). صورتحسابی ثبت نشد.\",\n          \"details\": [\n            \"ردیف 1: شناسه کالا/خدمت «0000000000000» در فهرست شناسه‌های کالا و خدمات یافت نشد.\"\n          ]\n        }\n      },\n      {\n        \"index\": 2,\n        \"clientRef\": \"PM-B1-1761800000000\",\n        \"ok\": false,\n        \"error\": {\n          \"code\": \"validation_failed\",\n          \"message\": \"این clientRef در همین درخواست تکراری است؛ برای هر صورتحساب clientRef جداگانه بفرستید.\",\n          \"field\": \"invoices[2].clientRef\"\n        }\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            }
          ],
          "description": "ارسال چند صورتحساب در یک درخواست. بعد از ارسال، وضعیت نهایی را با «استعلام گروهی» بگیرید."
        },
        {
          "name": "۴-۳) استعلام وضعیت",
          "item": [
            {
              "name": "استعلام با شماره مالیاتی",
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices/{{taxId}}",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices",
                    "{{taxId}}"
                  ]
                },
                "description": "وضعیت یک صورتحساب با taxId (۲۲ نویسه). فقط صورتحساب‌های خود حساب قابل استعلام است. taxId بعد از هر ارسال موفق خودکار در متغیر taxId ذخیره می‌شود.\nوضعیت‌ها: queued (در صف) · processing (در حال ارسال/پیگیری) · success (تأیید سامانه مودیان، referenceNumber شماره‌ی پیگیری) · failed (علت در message). وضعیت از دیتابیس خوانده می‌شود و ارسال خودکار آن را به‌روز می‌کند؛ هر ۱۰ تا ۳۰ ثانیه یک‌بار استعلام کنید، نه پشت‌سرهم.\nسقف نرخ: ۱۲۰ درخواست در دقیقه."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/400/404', () => pm.expect([200, 400, 404]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "200 در صف",
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"status\": \"queued\",\n    \"message\": null,\n    \"referenceNumber\": null\n  }\n}"
                },
                {
                  "name": "200 موفق",
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"status\": \"success\",\n    \"message\": null,\n    \"referenceNumber\": \"1234567890123456\"\n  }\n}"
                },
                {
                  "name": "200 ناموفق",
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"status\": \"failed\",\n    \"message\": \"متن خطا از سامانه‌ی مودیان\",\n    \"referenceNumber\": null\n  }\n}"
                },
                {
                  "name": "400 قالب نادرست",
                  "status": "Bad Request",
                  "code": 400,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"validation_failed\",\n    \"message\": \"شماره مالیاتی باید ۲۲ نویسه‌ی حرف و عدد انگلیسی باشد.\",\n    \"field\": \"taxId\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "404 یافت نشد",
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"not_found\",\n    \"message\": \"صورتحساب یافت نشد.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "استعلام با clientRef",
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices/by-ref/{{clientRef}}",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices",
                    "by-ref",
                    "{{clientRef}}"
                  ]
                },
                "description": "برای وقتی که پاسخ ارسال به دست شما نرسیده (قطعی شبکه یا timeout) و taxId را ندارید.\nstatus علاوه بر مقدارهای بالا می‌تواند pending باشد: این clientRef رزرو شده ولی صورتحساب هنوز ثبت نشده است؛ حدود یک دقیقه بعد همان درخواست را با همان clientRef و همان بدنه دوباره بفرستید.\nوضعیت‌ها: queued (در صف) · processing (در حال ارسال/پیگیری) · success (تأیید سامانه مودیان، referenceNumber شماره‌ی پیگیری) · failed (علت در message). وضعیت از دیتابیس خوانده می‌شود و ارسال خودکار آن را به‌روز می‌کند؛ هر ۱۰ تا ۳۰ ثانیه یک‌بار استعلام کنید، نه پشت‌سرهم.\n"
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/400/404', () => pm.expect([200, 400, 404]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "200 در صف",
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"taxId\": \"A12B34C0000000123456XY\",\n    \"status\": \"queued\",\n    \"message\": null,\n    \"referenceNumber\": null\n  }\n}"
                },
                {
                  "name": "200 pending (هنوز ثبت نشده)",
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"clientRef\": \"PM-1761800000000-4821\",\n    \"taxId\": null,\n    \"status\": \"pending\",\n    \"message\": null,\n    \"referenceNumber\": null\n  }\n}"
                },
                {
                  "name": "404 چنین clientRef ی ثبت نشده",
                  "status": "Not Found",
                  "code": 404,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"not_found\",\n    \"message\": \"درخواستی با این clientRef پیدا نشد.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "استعلام گروهی با clientRef",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices/status",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices",
                    "status"
                  ]
                },
                "description": "وضعیت حداکثر ۱۰۰ مورد را یک‌جا می‌گیرید. هر درخواست دقیقاً یکی از clientRefs یا taxIds را دارد. متد POST است فقط چون فهرست در بدنه می‌آید؛ چیزی تغییر نمی‌کند.\nfound=false بدون error یعنی چنین مورد ثبت‌شده‌ای برای حساب شما نیست (خطا نیست)؛ با error یعنی قالب آن مورد نادرست بوده.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientRefs\": [\n    \"{{clientRef1}}\",\n    \"{{clientRef2}}\",\n    \"INV-NOT-EXISTS-1\",\n    \"x\"\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/400', () => pm.expect([200, 400]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "200 موفق",
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"total\": 4,\n    \"results\": [\n      {\n        \"index\": 0,\n        \"clientRef\": \"PM-B1-1761800000000\",\n        \"taxId\": \"A12B34C0000000123456XY\",\n        \"found\": true,\n        \"status\": \"success\",\n        \"message\": null,\n        \"referenceNumber\": \"1234567890\"\n      },\n      {\n        \"index\": 1,\n        \"clientRef\": \"PM-B2-1761800000000\",\n        \"taxId\": \"A12B34C0000000123457XZ\",\n        \"found\": true,\n        \"status\": \"queued\",\n        \"message\": null,\n        \"referenceNumber\": null\n      },\n      {\n        \"index\": 2,\n        \"clientRef\": \"INV-NOT-EXISTS-1\",\n        \"taxId\": null,\n        \"found\": false\n      },\n      {\n        \"index\": 3,\n        \"clientRef\": \"x\",\n        \"taxId\": null,\n        \"found\": false,\n        \"error\": {\n          \"code\": \"validation_failed\",\n          \"message\": \"clientRef باید ۸ تا ۶۴ نویسه و فقط شامل حروف انگلیسی، عدد و نویسه‌های . _ : - باشد.\"\n        }\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "400 هر دو فهرست پر یا خالی / بیش از ۱۰۰ مورد",
                  "status": "Bad Request",
                  "code": 400,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"validation_failed\",\n    \"message\": \"فقط یکی از taxIds یا clientRefs را بفرستید.\",\n    \"field\": \"clientRefs\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            },
            {
              "name": "استعلام گروهی با taxId",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/invoices/status",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "v1",
                    "invoices",
                    "status"
                  ]
                },
                "description": "همان استعلام گروهی، این بار با فهرست شماره‌های مالیاتی. در پاسخ فیلد taxId همان مقدار ورودی است.",
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"taxIds\": [\n    \"{{taxId}}\"\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('کد پاسخ 200/400', () => pm.expect([200, 400]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "200 موفق",
                  "status": "OK",
                  "code": 200,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": true,\n  \"data\": {\n    \"total\": 1,\n    \"results\": [\n      {\n        \"index\": 0,\n        \"taxId\": \"A12B34C0000000123456XY\",\n        \"found\": true,\n        \"status\": \"success\",\n        \"message\": null,\n        \"referenceNumber\": \"1234567890\"\n      }\n    ]\n  }\n}"
                },
                {
                  "name": "401 توکن نامعتبر یا منقضی",
                  "status": "Unauthorized",
                  "code": 401,
                  "_postman_previewlanguage": "json",
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json; charset=utf-8"
                    }
                  ],
                  "cookie": [],
                  "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
                }
              ]
            }
          ],
          "description": "استعلام وضعیت ارسال، تکی و گروهی. ارسال به سامانه مودیان بعد از ثبت و به‌صورت خودکار انجام می‌شود."
        }
      ],
      "description": "ثبت، اصلاح، ابطال و پیگیری صورتحساب. هر صورتحساب ثبت‌شده از اعتبار شما کم می‌شود."
    },
    {
      "name": "۵) گزارش‌ها",
      "item": [
        {
          "name": "گزارش ارسالی‌ها؛ ۳۰ روز اخیر",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/reports/invoices",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "reports",
                "invoices"
              ],
              "query": [
                {
                  "key": "from",
                  "value": "2026-10-01",
                  "description": "شروع بازه‌ی تاریخ صدور (شامل خودش)؛ 2026-10-01 یا 2026-10-01T08:30:00Z",
                  "disabled": true
                },
                {
                  "key": "to",
                  "value": "2026-11-01",
                  "description": "پایان بازه (بدون خودش)",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "failed",
                  "description": "queued در صف · processing در حال پردازش · success موفق · failed ناموفق",
                  "disabled": true
                },
                {
                  "key": "economicId",
                  "value": "{{economicId}}",
                  "description": "شناسه‌ی شماره اقتصادی (id در فهرست شماره‌ها)",
                  "disabled": true
                },
                {
                  "key": "subject",
                  "value": "1",
                  "description": "موضوع: 1 اصلی · 2 اصلاحی · 3 ابطالی · 4 برگشت از فروش",
                  "disabled": true
                },
                {
                  "key": "pattern",
                  "value": "1",
                  "description": "الگوی صورتحساب، عدد ۱ تا ۳۰ طبق جدول الگوهای سامانه مودیان",
                  "disabled": true
                },
                {
                  "key": "channel",
                  "value": "3",
                  "description": "کانال ثبت: 1 ویزارد · 2 اکسل · 3 API",
                  "disabled": true
                },
                {
                  "key": "q",
                  "value": "A12B",
                  "description": "جست‌وجو: ابتدای شماره‌ی یکتا، شماره‌ی صورتحساب یا شناسه‌ی خریدار (حداکثر ۵۰ نویسه)",
                  "disabled": true
                },
                {
                  "key": "sort",
                  "value": "date",
                  "description": "date (پیش‌فرض) · status · taxid · eco · ins · inp · buyer · amount",
                  "disabled": true
                },
                {
                  "key": "dir",
                  "value": "desc",
                  "description": "desc (پیش‌فرض) یا asc",
                  "disabled": true
                },
                {
                  "key": "page",
                  "value": "1",
                  "description": "شماره‌ی صفحه از ۱",
                  "disabled": true
                },
                {
                  "key": "size",
                  "value": "25",
                  "description": "تعداد در صفحه، ۱ تا ۱۰۰",
                  "disabled": true
                }
              ]
            },
            "description": "فهرست صورتحساب‌های ثبت‌شده با هر کانالی (ویزارد، اکسل یا API). بدون هیچ پارامتر، ۳۰ روز اخیر برمی‌گردد و صفحه‌ی اول ۱۰ ردیف دارد.\nبازه بر اساس تاریخ صدور (issuedAt) است، میلادی و UTC. from شامل خودش و to بدون خودش است. اگر نفرستید ۳۰ روز اخیر برمی‌گردد؛ طول بازه حداکثر ۹۲ روز است.\nصفحه‌بندی: page از ۱ و size بین ۱ تا ۱۰۰ (پیش‌فرض ۱۰). تعداد صفحه‌ها = ceil(total / size). پارامتر نامعتبر بی‌صدا نادیده گرفته نمی‌شود و 400 validation_failed با نام پارامتر در field می‌گیرید.\nسقف نرخ: ۱۲۰ درخواست در دقیقه."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200', () => pm.expect([200]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"total\": 1,\n    \"page\": 1,\n    \"size\": 25,\n    \"items\": [\n      {\n        \"taxId\": \"A12B34C0000000123456XY\",\n        \"issuedAt\": \"2026-10-12T09:30:00Z\",\n        \"subject\": 1,\n        \"pattern\": 1,\n        \"type\": 1,\n        \"amount\": 2850000,\n        \"parentTaxId\": null,\n        \"economicId\": 12,\n        \"economicCode\": \"10101234567\",\n        \"companyName\": \"شرکت نمونه\",\n        \"buyerId\": \"10380123456\",\n        \"buyerType\": 2,\n        \"status\": \"failed\",\n        \"error\": \"متن خطا از سامانه‌ی مودیان\",\n        \"relatedCount\": 0,\n        \"hasActiveChild\": false,\n        \"channel\": 3\n      }\n    ]\n  }\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "429 بیش از سقف نرخ",
              "status": "Too Many Requests",
              "code": 429,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Retry-After",
                  "value": "30"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"rate_limited\",\n    \"message\": \"تعداد درخواست‌ها بیش از حد مجاز است؛ کمی بعد دوباره تلاش کنید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        },
        {
          "name": "گزارش ارسالی‌ها؛ همه‌ی فیلترها",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/reports/invoices?from=2026-10-01&to=2026-11-01&status=failed&economicId={{economicId}}&subject=1&pattern=1&channel=3&q=A12B&sort=date&dir=desc&page=1&size=25",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "reports",
                "invoices"
              ],
              "query": [
                {
                  "key": "from",
                  "value": "2026-10-01",
                  "description": "شروع بازه‌ی تاریخ صدور (شامل خودش)؛ 2026-10-01 یا 2026-10-01T08:30:00Z"
                },
                {
                  "key": "to",
                  "value": "2026-11-01",
                  "description": "پایان بازه (بدون خودش)"
                },
                {
                  "key": "status",
                  "value": "failed",
                  "description": "queued در صف · processing در حال پردازش · success موفق · failed ناموفق"
                },
                {
                  "key": "economicId",
                  "value": "{{economicId}}",
                  "description": "شناسه‌ی شماره اقتصادی (id در فهرست شماره‌ها)"
                },
                {
                  "key": "subject",
                  "value": "1",
                  "description": "موضوع: 1 اصلی · 2 اصلاحی · 3 ابطالی · 4 برگشت از فروش"
                },
                {
                  "key": "pattern",
                  "value": "1",
                  "description": "الگوی صورتحساب، عدد ۱ تا ۳۰ طبق جدول الگوهای سامانه مودیان"
                },
                {
                  "key": "channel",
                  "value": "3",
                  "description": "کانال ثبت: 1 ویزارد · 2 اکسل · 3 API"
                },
                {
                  "key": "q",
                  "value": "A12B",
                  "description": "جست‌وجو: ابتدای شماره‌ی یکتا، شماره‌ی صورتحساب یا شناسه‌ی خریدار (حداکثر ۵۰ نویسه)"
                },
                {
                  "key": "sort",
                  "value": "date",
                  "description": "date (پیش‌فرض) · status · taxid · eco · ins · inp · buyer · amount"
                },
                {
                  "key": "dir",
                  "value": "desc",
                  "description": "desc (پیش‌فرض) یا asc"
                },
                {
                  "key": "page",
                  "value": "1",
                  "description": "شماره‌ی صفحه از ۱"
                },
                {
                  "key": "size",
                  "value": "25",
                  "description": "تعداد در صفحه، ۱ تا ۱۰۰"
                }
              ]
            },
            "description": "همه‌ی پارامترهای ممکن در تب Params آمده‌اند؛ هرکدام را با تیک روشن/خاموش کنید.\nشیء هر ردیف: taxId، issuedAt، subject، pattern، type، amount (مبلغ کل)، parentTaxId (صورتحساب مرجع برای اصلاحی/ابطالی/برگشتی)، economicId/economicCode/companyName، buyerId/buyerType، status، error (فقط وقتی failed)، relatedCount، hasActiveChild (true یعنی برای این صورتحساب سند اصلاحی/ابطالی/برگشتی فعال ثبت شده و دیگر نمی‌تواند مرجع شود)، channel.\nبازه بر اساس تاریخ صدور (issuedAt) است، میلادی و UTC. from شامل خودش و to بدون خودش است. اگر نفرستید ۳۰ روز اخیر برمی‌گردد؛ طول بازه حداکثر ۹۲ روز است.\nصفحه‌بندی: page از ۱ و size بین ۱ تا ۱۰۰ (پیش‌فرض ۱۰). تعداد صفحه‌ها = ceil(total / size). پارامتر نامعتبر بی‌صدا نادیده گرفته نمی‌شود و 400 validation_failed با نام پارامتر در field می‌گیرید.\nسقف نرخ: ۱۲۰ درخواست در دقیقه."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200/400', () => pm.expect([200, 400]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"total\": 1,\n    \"page\": 1,\n    \"size\": 25,\n    \"items\": [\n      {\n        \"taxId\": \"A12B34C0000000123456XY\",\n        \"issuedAt\": \"2026-10-12T09:30:00Z\",\n        \"subject\": 1,\n        \"pattern\": 1,\n        \"type\": 1,\n        \"amount\": 2850000,\n        \"parentTaxId\": null,\n        \"economicId\": 12,\n        \"economicCode\": \"10101234567\",\n        \"companyName\": \"شرکت نمونه\",\n        \"buyerId\": \"10380123456\",\n        \"buyerType\": 2,\n        \"status\": \"failed\",\n        \"error\": \"متن خطا از سامانه‌ی مودیان\",\n        \"relatedCount\": 0,\n        \"hasActiveChild\": false,\n        \"channel\": 3\n      }\n    ]\n  }\n}"
            },
            {
              "name": "400 مقدار نامعتبر",
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"validation_failed\",\n    \"message\": \"مقدار status معتبر نیست (success | processing | queued | failed).\",\n    \"field\": \"status\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "400 بازه‌ی بیش از ۹۲ روز",
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"validation_failed\",\n    \"message\": \"طول بازه‌ی تاریخ حداکثر ۹۲ روز است.\",\n    \"field\": \"to\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        },
        {
          "name": "گزارش ارسالی‌ها؛ فقط ناموفق‌ها",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/reports/invoices?from=2026-10-01&to=2026-11-01&status=failed&page=1&size=25",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "reports",
                "invoices"
              ],
              "query": [
                {
                  "key": "from",
                  "value": "2026-10-01",
                  "description": "شروع بازه‌ی تاریخ صدور (شامل خودش)؛ 2026-10-01 یا 2026-10-01T08:30:00Z"
                },
                {
                  "key": "to",
                  "value": "2026-11-01",
                  "description": "پایان بازه (بدون خودش)"
                },
                {
                  "key": "status",
                  "value": "failed",
                  "description": "queued در صف · processing در حال پردازش · success موفق · failed ناموفق"
                },
                {
                  "key": "economicId",
                  "value": "{{economicId}}",
                  "description": "شناسه‌ی شماره اقتصادی (id در فهرست شماره‌ها)",
                  "disabled": true
                },
                {
                  "key": "subject",
                  "value": "1",
                  "description": "موضوع: 1 اصلی · 2 اصلاحی · 3 ابطالی · 4 برگشت از فروش",
                  "disabled": true
                },
                {
                  "key": "pattern",
                  "value": "1",
                  "description": "الگوی صورتحساب، عدد ۱ تا ۳۰ طبق جدول الگوهای سامانه مودیان",
                  "disabled": true
                },
                {
                  "key": "channel",
                  "value": "3",
                  "description": "کانال ثبت: 1 ویزارد · 2 اکسل · 3 API",
                  "disabled": true
                },
                {
                  "key": "q",
                  "value": "A12B",
                  "description": "جست‌وجو: ابتدای شماره‌ی یکتا، شماره‌ی صورتحساب یا شناسه‌ی خریدار (حداکثر ۵۰ نویسه)",
                  "disabled": true
                },
                {
                  "key": "sort",
                  "value": "date",
                  "description": "date (پیش‌فرض) · status · taxid · eco · ins · inp · buyer · amount",
                  "disabled": true
                },
                {
                  "key": "dir",
                  "value": "desc",
                  "description": "desc (پیش‌فرض) یا asc",
                  "disabled": true
                },
                {
                  "key": "page",
                  "value": "1",
                  "description": "شماره‌ی صفحه از ۱"
                },
                {
                  "key": "size",
                  "value": "25",
                  "description": "تعداد در صفحه، ۱ تا ۱۰۰"
                }
              ]
            },
            "description": "صورتحساب‌های ناموفق ماه جاری با علت در error.\nبازه بر اساس تاریخ صدور (issuedAt) است، میلادی و UTC. from شامل خودش و to بدون خودش است. اگر نفرستید ۳۰ روز اخیر برمی‌گردد؛ طول بازه حداکثر ۹۲ روز است.\nصفحه‌بندی: page از ۱ و size بین ۱ تا ۱۰۰ (پیش‌فرض ۱۰). تعداد صفحه‌ها = ceil(total / size). پارامتر نامعتبر بی‌صدا نادیده گرفته نمی‌شود و 400 validation_failed با نام پارامتر در field می‌گیرید.\nسقف نرخ: ۱۲۰ درخواست در دقیقه."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200', () => pm.expect([200]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"total\": 1,\n    \"page\": 1,\n    \"size\": 25,\n    \"items\": [\n      {\n        \"taxId\": \"A12B34C0000000123456XY\",\n        \"issuedAt\": \"2026-10-12T09:30:00Z\",\n        \"subject\": 1,\n        \"pattern\": 1,\n        \"type\": 1,\n        \"amount\": 2850000,\n        \"parentTaxId\": null,\n        \"economicId\": 12,\n        \"economicCode\": \"10101234567\",\n        \"companyName\": \"شرکت نمونه\",\n        \"buyerId\": \"10380123456\",\n        \"buyerType\": 2,\n        \"status\": \"failed\",\n        \"error\": \"متن خطا از سامانه‌ی مودیان\",\n        \"relatedCount\": 0,\n        \"hasActiveChild\": false,\n        \"channel\": 3\n      }\n    ]\n  }\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        },
        {
          "name": "گزارش ارسالی‌ها؛ فقط ثبت‌شده با API",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/reports/invoices?channel=3&page=1&size=25",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "reports",
                "invoices"
              ],
              "query": [
                {
                  "key": "from",
                  "value": "2026-10-01",
                  "description": "شروع بازه‌ی تاریخ صدور (شامل خودش)؛ 2026-10-01 یا 2026-10-01T08:30:00Z",
                  "disabled": true
                },
                {
                  "key": "to",
                  "value": "2026-11-01",
                  "description": "پایان بازه (بدون خودش)",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "failed",
                  "description": "queued در صف · processing در حال پردازش · success موفق · failed ناموفق",
                  "disabled": true
                },
                {
                  "key": "economicId",
                  "value": "{{economicId}}",
                  "description": "شناسه‌ی شماره اقتصادی (id در فهرست شماره‌ها)",
                  "disabled": true
                },
                {
                  "key": "subject",
                  "value": "1",
                  "description": "موضوع: 1 اصلی · 2 اصلاحی · 3 ابطالی · 4 برگشت از فروش",
                  "disabled": true
                },
                {
                  "key": "pattern",
                  "value": "1",
                  "description": "الگوی صورتحساب، عدد ۱ تا ۳۰ طبق جدول الگوهای سامانه مودیان",
                  "disabled": true
                },
                {
                  "key": "channel",
                  "value": "3",
                  "description": "کانال ثبت: 1 ویزارد · 2 اکسل · 3 API"
                },
                {
                  "key": "q",
                  "value": "A12B",
                  "description": "جست‌وجو: ابتدای شماره‌ی یکتا، شماره‌ی صورتحساب یا شناسه‌ی خریدار (حداکثر ۵۰ نویسه)",
                  "disabled": true
                },
                {
                  "key": "sort",
                  "value": "date",
                  "description": "date (پیش‌فرض) · status · taxid · eco · ins · inp · buyer · amount",
                  "disabled": true
                },
                {
                  "key": "dir",
                  "value": "desc",
                  "description": "desc (پیش‌فرض) یا asc",
                  "disabled": true
                },
                {
                  "key": "page",
                  "value": "1",
                  "description": "شماره‌ی صفحه از ۱"
                },
                {
                  "key": "size",
                  "value": "25",
                  "description": "تعداد در صفحه، ۱ تا ۱۰۰"
                }
              ]
            },
            "description": "فیلتر channel=3 فقط صورتحساب‌هایی را برمی‌گرداند که از طریق API ثبت شده‌اند.\nبازه بر اساس تاریخ صدور (issuedAt) است، میلادی و UTC. from شامل خودش و to بدون خودش است. اگر نفرستید ۳۰ روز اخیر برمی‌گردد؛ طول بازه حداکثر ۹۲ روز است.\nصفحه‌بندی: page از ۱ و size بین ۱ تا ۱۰۰ (پیش‌فرض ۱۰). تعداد صفحه‌ها = ceil(total / size). پارامتر نامعتبر بی‌صدا نادیده گرفته نمی‌شود و 400 validation_failed با نام پارامتر در field می‌گیرید.\nسقف نرخ: ۱۲۰ درخواست در دقیقه."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200', () => pm.expect([200]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"total\": 1,\n    \"page\": 1,\n    \"size\": 25,\n    \"items\": [\n      {\n        \"taxId\": \"A12B34C0000000123456XY\",\n        \"issuedAt\": \"2026-10-12T09:30:00Z\",\n        \"subject\": 1,\n        \"pattern\": 1,\n        \"type\": 1,\n        \"amount\": 2850000,\n        \"parentTaxId\": null,\n        \"economicId\": 12,\n        \"economicCode\": \"10101234567\",\n        \"companyName\": \"شرکت نمونه\",\n        \"buyerId\": \"10380123456\",\n        \"buyerType\": 2,\n        \"status\": \"failed\",\n        \"error\": \"متن خطا از سامانه‌ی مودیان\",\n        \"relatedCount\": 0,\n        \"hasActiveChild\": false,\n        \"channel\": 3\n      }\n    ]\n  }\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        },
        {
          "name": "گزارش خطاها؛ ۳۰ روز اخیر",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/reports/errors",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "reports",
                "errors"
              ],
              "query": [
                {
                  "key": "from",
                  "value": "2026-10-01",
                  "description": "شروع بازه‌ی تاریخ صدور",
                  "disabled": true
                },
                {
                  "key": "to",
                  "value": "2026-11-01",
                  "description": "پایان بازه (بدون خودش)",
                  "disabled": true
                },
                {
                  "key": "source",
                  "value": "submit",
                  "description": "مرحله‌ی خطا: validation رد در کنترل‌های سامانه پیش از ارسال · submit رد هنگام ارسال به سامانه مودیان · inquiry رد در استعلام نهایی",
                  "disabled": true
                },
                {
                  "key": "economicId",
                  "value": "{{economicId}}",
                  "description": "شناسه‌ی شماره اقتصادی",
                  "disabled": true
                },
                {
                  "key": "q",
                  "value": "400",
                  "description": "ابتدای شماره‌ی یکتا، شماره‌ی صورتحساب، کد خطا یا بخشی از متن خطا (برای جست‌وجو در متن حداقل ۳ نویسه)",
                  "disabled": true
                },
                {
                  "key": "page",
                  "value": "1",
                  "description": "شماره‌ی صفحه از ۱",
                  "disabled": true
                },
                {
                  "key": "size",
                  "value": "25",
                  "description": "تعداد در صفحه، ۱ تا ۱۰۰",
                  "disabled": true
                }
              ]
            },
            "description": "صورتحساب‌هایی که در یکی از مراحل رد شده‌اند، به‌همراه علت. هر صورتحساب یک ردیف دارد و در message مهم‌ترین علت آمده است. نتایج از جدیدترین به قدیمی‌ترین مرتب‌اند.\nبازه بر اساس تاریخ صدور (issuedAt) است، میلادی و UTC. from شامل خودش و to بدون خودش است. اگر نفرستید ۳۰ روز اخیر برمی‌گردد؛ طول بازه حداکثر ۹۲ روز است.\nصفحه‌بندی: page از ۱ و size بین ۱ تا ۱۰۰ (پیش‌فرض ۱۰). تعداد صفحه‌ها = ceil(total / size). پارامتر نامعتبر بی‌صدا نادیده گرفته نمی‌شود و 400 validation_failed با نام پارامتر در field می‌گیرید.\nسقف نرخ: ۱۲۰ درخواست در دقیقه."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200', () => pm.expect([200]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"total\": 1,\n    \"page\": 1,\n    \"size\": 25,\n    \"items\": [\n      {\n        \"taxId\": \"A12B34C0000000123456XY\",\n        \"issuedAt\": \"2026-10-12T09:30:00Z\",\n        \"subject\": 1,\n        \"pattern\": 1,\n        \"amount\": 2850000,\n        \"economicId\": 12,\n        \"economicCode\": \"10101234567\",\n        \"companyName\": \"شرکت نمونه\",\n        \"buyerId\": \"10380123456\",\n        \"buyerType\": 2,\n        \"source\": \"submit\",\n        \"code\": \"400\",\n        \"message\": \"متن خطا از سامانه‌ی مودیان\",\n        \"errorCount\": 1\n      }\n    ]\n  }\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "429 بیش از سقف نرخ",
              "status": "Too Many Requests",
              "code": 429,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Retry-After",
                  "value": "30"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"rate_limited\",\n    \"message\": \"تعداد درخواست‌ها بیش از حد مجاز است؛ کمی بعد دوباره تلاش کنید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        },
        {
          "name": "گزارش خطاها؛ همه‌ی فیلترها",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/reports/errors?from=2026-10-01&to=2026-11-01&source=submit&economicId={{economicId}}&q=400&page=1&size=25",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "reports",
                "errors"
              ],
              "query": [
                {
                  "key": "from",
                  "value": "2026-10-01",
                  "description": "شروع بازه‌ی تاریخ صدور"
                },
                {
                  "key": "to",
                  "value": "2026-11-01",
                  "description": "پایان بازه (بدون خودش)"
                },
                {
                  "key": "source",
                  "value": "submit",
                  "description": "مرحله‌ی خطا: validation رد در کنترل‌های سامانه پیش از ارسال · submit رد هنگام ارسال به سامانه مودیان · inquiry رد در استعلام نهایی"
                },
                {
                  "key": "economicId",
                  "value": "{{economicId}}",
                  "description": "شناسه‌ی شماره اقتصادی"
                },
                {
                  "key": "q",
                  "value": "400",
                  "description": "ابتدای شماره‌ی یکتا، شماره‌ی صورتحساب، کد خطا یا بخشی از متن خطا (برای جست‌وجو در متن حداقل ۳ نویسه)"
                },
                {
                  "key": "page",
                  "value": "1",
                  "description": "شماره‌ی صفحه از ۱"
                },
                {
                  "key": "size",
                  "value": "25",
                  "description": "تعداد در صفحه، ۱ تا ۱۰۰"
                }
              ]
            },
            "description": "source: validation (کنترل‌های سامانه پیش از ارسال؛ code همیشه null) · submit (رد هنگام ارسال) · inquiry (رد در استعلام نهایی). message حداکثر ۱۰۰۰ نویسه و برای validation ممکن است چند خط باشد؛ errorCount تعداد خطاهای ثبت‌شده برای صورتحساب است.\nبازه بر اساس تاریخ صدور (issuedAt) است، میلادی و UTC. from شامل خودش و to بدون خودش است. اگر نفرستید ۳۰ روز اخیر برمی‌گردد؛ طول بازه حداکثر ۹۲ روز است.\nصفحه‌بندی: page از ۱ و size بین ۱ تا ۱۰۰ (پیش‌فرض ۱۰). تعداد صفحه‌ها = ceil(total / size). پارامتر نامعتبر بی‌صدا نادیده گرفته نمی‌شود و 400 validation_failed با نام پارامتر در field می‌گیرید.\nسقف نرخ: ۱۲۰ درخواست در دقیقه."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('کد پاسخ 200/400', () => pm.expect([200, 400]).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "pm.test('قالب پاسخ استاندارد', () => pm.expect(j).to.have.property('success'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "200 موفق",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": true,\n  \"data\": {\n    \"total\": 1,\n    \"page\": 1,\n    \"size\": 25,\n    \"items\": [\n      {\n        \"taxId\": \"A12B34C0000000123456XY\",\n        \"issuedAt\": \"2026-10-12T09:30:00Z\",\n        \"subject\": 1,\n        \"pattern\": 1,\n        \"amount\": 2850000,\n        \"economicId\": 12,\n        \"economicCode\": \"10101234567\",\n        \"companyName\": \"شرکت نمونه\",\n        \"buyerId\": \"10380123456\",\n        \"buyerType\": 2,\n        \"source\": \"submit\",\n        \"code\": \"400\",\n        \"message\": \"متن خطا از سامانه‌ی مودیان\",\n        \"errorCount\": 1\n      }\n    ]\n  }\n}"
            },
            {
              "name": "400 مقدار نامعتبر source",
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"validation_failed\",\n    \"message\": \"مقدار source معتبر نیست (validation | submit | inquiry).\",\n    \"field\": \"source\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "400 تاریخ با قالب نادرست",
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"validation_failed\",\n    \"message\": \"مقدار from باید تاریخ میلادی مثل 2026-10-01 یا 2026-10-01T08:30:00Z باشد.\",\n    \"field\": \"from\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            },
            {
              "name": "401 توکن نامعتبر یا منقضی",
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                }
              ],
              "cookie": [],
              "body": "{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"unauthorized\",\n    \"message\": \"توکن دسترسی نامعتبر یا منقضی است. دوباره از /v1/auth/token توکن بگیرید.\"\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"
            }
          ]
        }
      ],
      "description": "گزارش‌های فقط‌خواندنی. فقط داده‌ی حساب صاحب توکن را برمی‌گردانند و صفحه‌بندی دارند."
    }
  ]
}