{
  "info": {
    "name": "iSign — Түншийн API (server-to-server)",
    "description": "iSign-тэй интеграц хийх гуравдагч системд зориулсан багц.\n\n⚠ ЭНЭ БАГЦАД ЗӨВХӨН СЕРВЕР-СЕРВЕР дуудлага байна.\nБраузер дээрх үйлдлүүд (нэвтрэх, гэрээ үүсгэх редактор, гарын үсэг зурах) нь\nHTTP биш — iSign өргөтгөлтэй postMessage-ээр харилцдаг тул Postman-аар дуудагдахгүй.\nТэдгээрийг docs/examples/partner-demo.html дээрээс хараарай.\n\nБэлтгэл:\n  1. iSign-аас өөрийн системд `webhook_token` авна\n  2. Environment дээр {{token}}, {{baseUrl}}-ээ тохируулна\n  3. «Гэрээ үүсгэх» дуудлагууд хариунаас contractId-г автоматаар хадгална",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{token}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "http://localhost:8098/api/v1"
    },
    {
      "key": "contractId",
      "value": ""
    },
    {
      "key": "externalNumber",
      "value": ""
    }
  ],
  "item": [
    {
      "name": "1. Иргэн / байгууллага шалгах",
      "item": [
        {
          "name": "lookup — байгууллага",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/thirdparty/lookup",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "thirdparty",
                "lookup"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"legalEntityNumber\": \"0099990\"\n}"
            },
            "description": "Гэрээнд оруулах өмнө тухайн байгууллага iSign дээр бүртгэлтэй эсэхийг шалгана.\n\nАмжилттай: { result: { account_id, name, type: \"org\" } }\nОлдсонгүй:  HTTP 500 + message «Иргэн/Байгууллага олдсонгүй: …»"
          }
        },
        {
          "name": "lookup — иргэн",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/thirdparty/lookup",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "thirdparty",
                "lookup"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"civilId\": \"АА99999999\"\n}"
            },
            "description": "civilId нь регистрийн дугаар (кирилл үсэгтэй). Бүртгэлгүй бол HTTP 500 буцна."
          }
        }
      ]
    },
    {
      "name": "2. Гэрээ үүсгэх",
      "item": [
        {
          "name": "create — загвараас",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const j = pm.response.json();",
                  "if (j.result && j.data && j.data.contractId) {",
                  "  pm.collectionVariables.set('contractId', j.data.contractId);",
                  "  pm.collectionVariables.set('externalNumber', j.data.externalNumber);",
                  "  console.log('contractId хадгаллаа:', j.data.contractId);",
                  "}",
                  "pm.test('амжилттай', () => pm.expect(j.result).to.be.true);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/thirdparty/contract/create",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "thirdparty",
                "contract",
                "create"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"date\": \"2026-08-20T10:00:00+08:00\",\n  \"number\": \"MY-2026-0001\",\n  \"clientId\": \"AA99999999\",\n  \"formData\": {\n    \"serviceCode\": \"DEV_001\",\n    \"participantList\": [\n      {\n        \"type\": \"org\",\n        \"registerNumber\": \"0099990\",\n        \"companyName\": \"ТЕСТ КОМПАНИ ХХК\"\n      },\n      {\n        \"type\": \"citizen\",\n        \"registerNumber\": \"АА99999999\",\n        \"firstName\": \"НЭР\",\n        \"lastName\": \"ОВОГ\"\n      }\n    ]\n  }\n}"
            },
            "description": "iSign дээр урьдчилан бүртгүүлсэн ЗАГВАРААС гэрээ үүсгэнэ.\n\n  number       — ТАНЫ дотоод дугаар. Webhook-д буцаж ирнэ, гэрээгээ хожим\n                 хайхад хэрэглэгдэнэ. Давхардвал шинэ гэрээ үүсэхгүй,\n                 өмнөх нь буцна.\n  serviceCode  — iSign-тай тохирсон загварын код (жишээ: DEV_001)\n\n⚠ participantList-ийн БҮТЭЦ нь загвар бүрд ӨӨР.\n  iSign тал бүр загварт `signer_config_json` тохируулж, тэндээс ямар талбараас\n  регистр/нэрийг уншихыг заадаг. Тиймээс доорх бие нь ЗӨВХӨН БҮТЭЦ ҮЗҮҮЛЭХ жишээ —\n  өөрийн загварынхаа бодит талбаруудыг iSign-аас лавлаж авна уу.\n\n  Хэрэв тохиргоо дутуу бол:\n    400 «Оролцогч талын тоо (0) хангалтгүй. Хамгийн багадаа 2 тал шаардлагатай»\n\nХариу: { result: true, data: { contractId, contractUrl, externalNumber, status } }"
          }
        },
        {
          "name": "create — тусгай загвараас (engui_special)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const j = pm.response.json();",
                  "if (j.result && j.data && j.data.contractId) {",
                  "  pm.collectionVariables.set('contractId', j.data.contractId);",
                  "  pm.collectionVariables.set('externalNumber', j.data.externalNumber);",
                  "  console.log('contractId хадгаллаа:', j.data.contractId);",
                  "}",
                  "pm.test('амжилттай', () => pm.expect(j.result).to.be.true);",
                  "// ⚠ Тусгай загвар: гэрээ ноорог хэвээр — талууд баталтал PDF байхгүй."
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/thirdparty/contract/create",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "thirdparty",
                "contract",
                "create"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"date\": \"2026-08-20T10:00:00+08:00\",\n  \"number\": \"MY-2026-0002\",\n  \"clientId\": \"AA99999999\",\n  \"formData\": {\n    \"serviceCode\": \"ES_001\",\n    \"participantList\": [\n      {\n        \"type\": \"org\",\n        \"registerNumber\": \"0099990\",\n        \"companyName\": \"ТЕСТ КОМПАНИ ХХК\"\n      },\n      {\n        \"type\": \"citizen\",\n        \"registerNumber\": \"АА99999999\",\n        \"firstName\": \"НЭР\",\n        \"lastName\": \"ОВОГ\"\n      }\n    ]\n  }\n}"
            },
            "description": "ТУСГАЙ ЗАГВАРААС (engui_special) гэрээ үүсгэнэ.\n\nДуудлага нь ердийн create-тэй ЯГ ИЖИЛ — зөвхөн serviceCode нь iSign дээр\ncontract_type=\"engui_special\" гэж тохируулсан загварыг заана.\n\nЯлгаа:\n  · field_mapping нь PDF талбар руу биш, загварын ХУВЬСАГЧ руу буудаг\n    (schema_json.variables.<id>.value).\n  · Гэрээ НООРОГ (draft) төлөвт үүснэ. PDF нь хараахан байхгүй —\n    талууд /engui-special/{contractId} дээр бөглөж баталсны дараа\n    Typst-ээр render хийгдэж, гарын үсгийн талбар байрлана.\n  · Тиймээс create хийсэн ДАРУЙД contract/file татвал файл ирэхгүй.\n    Төлөвөө contract/list эсвэл webhook-оор хянана.\n\nБоломжит алдаанууд:\n  400 «тусгай загвар нийтлэгдээгүй байна» — админ загвараа publish хийгээгүй\n  400 «'employee' ролийн тал (party_index 1) оролцогчид алга»\n      — signer_config-оос гарсан оролцогчид загварын ролиудыг бүрэн\n        хамраагүй. role_mapping_json эсвэл participantList-ээ шалгана уу."
          },
          "response": []
        },
        {
          "name": "create-pdf — өөрийн PDF-ээс",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const j = pm.response.json();",
                  "if (j.result && j.data && j.data.contractId) {",
                  "  pm.collectionVariables.set('contractId', j.data.contractId);",
                  "  pm.collectionVariables.set('externalNumber', j.data.externalNumber);",
                  "}",
                  "pm.test('амжилттай', () => pm.expect(j.result).to.be.true);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "url": {
              "raw": "{{baseUrl}}/thirdparty/contract/create-pdf",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "thirdparty",
                "contract",
                "create-pdf"
              ]
            },
            "body": {
              "mode": "formdata",
              "formdata": [
                {
                  "key": "name",
                  "value": "Хөдөлмөрийн гэрээ",
                  "type": "text"
                },
                {
                  "key": "number",
                  "value": "MY-2026-0002",
                  "type": "text"
                },
                {
                  "key": "signers",
                  "value": "[{\"party_index\":0,\"type\":\"citizen\",\"civil_id\":\"АА99999999\"}]",
                  "type": "text"
                },
                {
                  "key": "fields",
                  "value": "[]",
                  "type": "text",
                  "description": "Заавал биш. Гарын үсгийн болон чөлөөт талбарын байрлал."
                },
                {
                  "key": "callback",
                  "value": "",
                  "type": "text",
                  "description": "Заавал биш. Одоогоор зөвхөн бүртгэлд хадгалагдана."
                },
                {
                  "key": "file",
                  "type": "file",
                  "src": [],
                  "description": "PDF файл. Postman дээр өөрийн файлаа сонгоно уу."
                }
              ]
            },
            "description": "Өөрийн PDF-ээс шууд гэрээ үүсгэнэ (multipart/form-data).\n\nsigners — JSON массив:\n  party_index  0 = үүсгэгч тал, 1+ = нөгөө талууд\n  type         \"citizen\" | \"org\"\n  civil_id     type=citizen үед регистр\n  reg_num      type=org үед байгууллагын регистр\n\n⚠ Content-Type-ыг ГАРААР бүү тавь — Postman multipart boundary-г өөрөө нэмнэ."
          }
        }
      ]
    },
    {
      "name": "3. Төлөв ба эцсийн файл",
      "item": [
        {
          "name": "contract/list — миний гэрээнүүд",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/thirdparty/contract/list",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "thirdparty",
                "contract",
                "list"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"civilId\": \"АА99999999\"\n}"
            },
            "description": "Тухайн иргэн/байгууллагатай холбоотой, ТАНЫ системээр үүссэн гэрээнүүд.\n\ncivilId эсвэл legalEntityNumber-ийн аль нэгийг өгнө.\n\n⚠ Хариунд contractId БАЙХГҮЙ. Гэрээгээ дараагийн дуудлагад хаяглахдаа\n   serviceRequestNumber (= таны илгээсэн number) -ийг ашиглана."
          }
        },
        {
          "name": "contract/file — эцсийн PDF татах (contract_id-аар)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('PDF ирлээ', () => {",
                  "  pm.response.to.have.status(200);",
                  "  pm.expect(pm.response.headers.get('Content-Type')).to.include('pdf');",
                  "});",
                  "console.log('төлөв   :', pm.response.headers.get('X-ISign-Contract-Status'));",
                  "console.log('зурсан  :', pm.response.headers.get('X-ISign-Signed-Num') + '/' + pm.response.headers.get('X-ISign-Signer-Num'));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/thirdparty/contract/file",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "thirdparty",
                "contract",
                "file"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"contract_id\": \"{{contractId}}\"\n}"
            },
            "description": "Гэрээний ХАМГИЙН СҮҮЛИЙН (гарын үсэгтэй) PDF-ийг буцаана.\n\nХариу нь PDF-ийн түүхий байт. Төлөвийг header-ээс уншина:\n  X-ISign-Contract-Status   draft | created | pending | completed | rejected\n  X-ISign-Signed-Num        хэдэн тал зурсан\n  X-ISign-Signer-Num        нийт хэдэн тал зурах ёстой\n\nБүх тал зурж дууссан хувилбарыг авахыг хүсвэл\nX-ISign-Contract-Status = completed болтол хүлээнэ.\n\nАлдаа:\n  401  токен буруу / байхгүй\n  403  хуучин нийтлэг токен ашигласан — өөрийн webhook_token хэрэглэнэ үү\n  404  гэрээ олдсонгүй ЭСВЭЛ таны систем үүсгээгүй гэрээ"
          }
        },
        {
          "name": "contract/file — эцсийн PDF татах (өөрийн дугаараар)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/thirdparty/contract/file",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "thirdparty",
                "contract",
                "file"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"thirdparty_id\": \"{{externalNumber}}\"\n}"
            },
            "description": "contract_id хадгалаагүй бол ӨӨРИЙН дугаараараа (үүсгэхэд илгээсэн `number`)\nтатаж болно. Үр дүн ижил."
          }
        }
      ]
    },
    {
      "name": "4. Сөрөг тохиолдол (аюулгүй байдал шалгах)",
      "item": [
        {
          "name": "токенгүй → 401",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/thirdparty/contract/file",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "thirdparty",
                "contract",
                "file"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"contract_id\": \"{{contractId}}\"\n}"
            },
            "description": "Токенгүй хүсэлт 401 буцаах ёстой."
          }
        },
        {
          "name": "өөр системийн гэрээ → 404",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/thirdparty/contract/file",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "thirdparty",
                "contract",
                "file"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"contract_id\": \"01ZZZZZZZZZZZZZZZZZZZZZZZZ\"\n}"
            },
            "description": "Байхгүй гэрээ ба ӨӨР түншийн гэрээ хоёрт ЯЛГААГҮЙ 404 буцна —\nхариуны ялгаагаар бусдын гэрээ байгаа эсэхийг тандах боломжгүй."
          }
        }
      ]
    }
  ]
}
