{
  "info": {
    "_postman_id": "b2508ce7-05f2-461e-af30-70d38a76761a",
    "name": "OpenFinance PSD2 Collection Regular API (RTC)",
    "description": "# OpenFinance PSD2 Collection — README\n\n## First Use (required!)\n\nBefore starting to work with the collection, you must **once** execute the request from the **First Use Install** folder:\n\n> **`jsrsasign.lib Install`** — loads the `jsrsasign` cryptographic library into Postman global variables. Without this step, all requests with signing will fail with an error. \n  \n\n## Collection Structure\n\n| Folder | Description |\n| --- | --- |\n| **First Use Install** | Signature library installation (run once) |\n| **Regular API → Consent** | Create, view, status, delete AIS/PIIS consent |\n| **Regular API → Accounts** | Retrieve account list, account info, balances, transactions |\n| **Regular API → Payments** | Create, view, status, delete payments |\n| **Regular API → Payments Periodic** | Create, view, status, delete recurring payments |\n| **Premium API → Administrative → Onboarding** | TPP onboarding with a provider |\n| **Premium API → Special-Accounts xAIS** | Special requests for account statements (xAIS) |\n| **Premium API → Special-Accounts xPIS** | Special requests for payments (xPIS) |\n| **ASPSP side API → Contract** | TPP contract management |\n| **ASPSP side API → SCA API** | SCA authorization (AIS/PIS create, update, status) |\n| **ASPSP side API → ASPSP Consent Management** | ASPSP-side consent management |\n| **ASPSP side API → ASPSP Callback API** | Callback API (payment status change) |\n| **ASPSP side API → ASPSP Config Sync** | Config Sync API |\n\n---\n\n## Environment Variables\n\n### 1\\. Configured manually once (request signing)\n\nThese variables are related to TPP identification and request signing. They are set once during environment setup.\n\n| Variable | Description |\n| --- | --- |\n| `base_url` | Base API URL (e.g., `https://openfinance.saltedge.com`) |\n| `provider_code` | Provider code (bank/ASPSP) |\n| `TPP_PRIVATE_KEY` | TPP private key in PEM format (used for JWS signing) |\n| `TPP_SIGN_CERT` | TPP certificate in PEM format (passed in the `x-jws-signature` header) |\n| `SIGN_ALG` | Signing algorithm (default: `RS256`) |\n\n---\n\n### 2\\. Configured manually before a request (part of the endpoint URL)\n\nThese variables are part of the URL path and must be set manually before sending the corresponding requests.\n\n| Variable | Allowed Values |\n| --- | --- |\n| `consent-category` | `account-access` / `funds-confirmations` |\n| `account_type` | `accounts` / `card-accounts` |\n| `payment_services` | `payments` / `bulk-payments` / `periodic-payments` |\n| `payment_product` | `sepa-credit-transfers` / `instant-sepa-credit-transfers` / `target-2-payments` / `cross-border-credit-transfers` |\n| `xpis_payment_service` | `payments` / `bulk-payments` / `periodic-payments` |\n| `xpis_payment_product` | `pain.001-sepa-credit-transfers` / `pain.001-instant-sepa-credit-transfers` / `pain.001-target-2-payments` / `pain.001-cross-border-credit-transfers` |\n\n---\n\n### 3\\. Set automatically (from API responses / pre-request scripts)\n\nThese variables do not need to be set manually — they are populated by scripts automatically.\n\n| Variable | Source |\n| --- | --- |\n| `consentId` | From `Consent Create` response |\n| `auth` | From `Consent Create` response (AIS auth token) |\n| `payment_id` | From `Payment Create` / `Periodic Payment Create` response |\n| `authPis` | From `Payment Create` response (PIS auth token) |\n| `xpis_payment_id` | From `Create xPIS` response |\n| `onboardingId` | From `OnBoarding Create` response |\n| `account_id` | From `Get Accounts` response |\n| `transactions_id` | From `Get Transactions` response |\n| `x-request-id` | Generated in pre-request script (UUID) |\n| `date` | Generated in pre-request script (current date) |\n| `certificate_signature` | Generated in pre-request script (Detached JWS signature) |\n\n---\n\n## How signing works (x-jws-signature)\n\nEvery request that requires signing automatically generates the `x-jws-signature` header via a pre-request script:\n\n1. The script takes `TPP_PRIVATE_KEY` and `TPP_SIGN_CERT` from the environment\n    \n2. Forms a Detached JWS signature of the request body using the algorithm from `SIGN_ALG`\n    \n3. Saves the result to the `certificate_signature` variable\n    \n4. The `x-jws-signature` header substitutes the value automatically\n    \n\n---\n\n## Quick Start\n\n1. Select the **OF ENV v0.2 STG** environment\n    \n2. Fill in the variables from section **1** (`base_url`, `provider_code`, `TPP_PRIVATE_KEY`, `TPP_SIGN_CERT`, `SIGN_ALG`)\n    \n3. Run the **`jsrsasign.lib Install`** request (folder **First Use Install**)\n    \n4. Set the required variables from section **2** depending on the scenario\n    \n5. Send requests — variables from section **3** will be populated automatically\n    \n\n# Consent & Payment Body Presets Exemples\n\n## Consent Body Presets\n\nDepending on the `consentType`, the structure of `access` and the available `rights` differ.\n\nBelow are the 4 main consent types with fully populated examples.\n\n---\n\n# 1\\. Global Consent\n\n## Description\n\n`global` consent provides access to all available accounts/cards of the selected type without specifying a concrete account.\n\n## Available access sections\n\n- `payments`\n    \n- `cards`\n    \n- `cardAccounts`\n    \n\n## Available rights\n\n- `ais`\n    \n- `ownerName`\n    \n\n## Fully populated example\n\n``` json\n{\n  \"access\": {\n    \"payments\": [\n      {\n        \"rights\": [\"ais\", \"ownerName\"]\n      }\n    ],\n    \"cards\": [\n      {\n        \"rights\": [\"ais\", \"ownerName\"]\n      }\n    ],\n    \"cardAccounts\": [\n      {\n        \"rights\": [\"ais\", \"ownerName\"]\n      }\n    ]\n  },\n  \"consentType\": \"global\",\n  \"recurringIndicator\": true,\n  \"validTo\": \"2027-01-01\",\n  \"frequencyPerDay\": 4\n}\n\n ```\n\n---\n\n# 2\\. Detailed Consent\n\n## Description\n\n`detailed` consent provides access only to explicitly specified accounts.\n\nAn account identifier must be provided for every access section.\n\n## Available access sections\n\n- `payments`\n    \n- `cards`\n    \n- `cardAccounts`\n    \n\n## Available rights\n\n- `accountDetails`\n    \n- `balances`\n    \n- `transactions`\n    \n- `ownerName`\n    \n\n## Supported account identifiers\n\n| Access Section | Account Identifier |\n| --- | --- |\n| `payments` | `iban` |\n| `cards` | `pan` |\n| `cardAccounts` | `maskedPan` |\n\n## Fully populated example\n\n``` json\n{\n  \"access\": {\n    \"payments\": [\n      {\n        \"account\": {\n          \"iban\": \"DE89370400440532013000\"\n        },\n        \"rights\": [\n          \"accountDetails\",\n          \"balances\",\n          \"transactions\",\n          \"ownerName\"\n        ]\n      }\n    ],\n    \"cards\": [\n      {\n        \"account\": {\n          \"pan\": \"1234567890123456\"\n        },\n        \"rights\": [\n          \"accountDetails\",\n          \"balances\",\n          \"transactions\",\n          \"ownerName\"\n        ]\n      }\n    ],\n    \"cardAccounts\": [\n      {\n        \"account\": {\n          \"maskedPan\": \"1234********3456\"\n        },\n        \"rights\": [\n          \"accountDetails\",\n          \"balances\",\n          \"transactions\",\n          \"ownerName\"\n        ]\n      }\n    ]\n  },\n  \"consentType\": \"detailed\",\n  \"recurringIndicator\": true,\n  \"validTo\": \"2026-12-31\",\n  \"frequencyPerDay\": 4\n}\n\n ```\n\n---\n\n# 3\\. ASPSP Managed Consent\n\n## Description\n\n`aspspManaged` consent allows the ASPSP to determine the list of accessible accounts automatically.\n\n## Available access sections\n\n- `payments`\n    \n- `cards`\n    \n- `cardAccounts`\n    \n\n## Available rights\n\n- `accountDetails`\n    \n- `balances`\n    \n- `transactions`\n    \n\n## Fully populated example\n\n``` json\n{\n  \"access\": {\n    \"payments\": [\n      {\n        \"rights\": [\n          \"accountDetails\",\n          \"balances\",\n          \"transactions\"\n        ]\n      }\n    ],\n    \"cards\": [\n      {\n        \"rights\": [\n          \"accountDetails\",\n          \"balances\",\n          \"transactions\"\n        ]\n      }\n    ],\n    \"cardAccounts\": [\n      {\n        \"rights\": [\n          \"accountDetails\",\n          \"balances\",\n          \"transactions\"\n        ]\n      }\n    ]\n  },\n  \"consentType\": \"aspspManaged\",\n  \"recurringIndicator\": true,\n  \"validTo\": \"2026-12-31\",\n  \"frequencyPerDay\": 4\n}\n\n ```\n\n---\n\n# 4\\. Account List Consent\n\n## Description\n\n`accountList` consent is used to retrieve the list of available accounts.\n\n## Available access sections\n\n- `payments`\n    \n- `cards`\n    \n- `cardAccounts`\n    \n\n## Available rights\n\n- `accountDetails`\n    \n- `balances`\n    \n- `ownerName`\n    \n\n> `transactions` right is not supported for `accountList` consent. \n  \n\n## Fully populated example\n\n``` json\n{\n  \"access\": {\n    \"payments\": [\n      {\n        \"rights\": [\n          \"accountDetails\",\n          \"balances\",\n          \"ownerName\"\n        ]\n      }\n    ],\n    \"cards\": [\n      {\n        \"rights\": [\n          \"accountDetails\",\n          \"balances\",\n          \"ownerName\"\n        ]\n      }\n    ],\n    \"cardAccounts\": [\n      {\n        \"rights\": [\n          \"accountDetails\",\n          \"balances\",\n          \"ownerName\"\n        ]\n      }\n    ]\n  },\n  \"consentType\": \"accountList\",\n  \"recurringIndicator\": true,\n  \"validTo\": \"2026-12-31\",\n  \"frequencyPerDay\": 4\n}\n\n ```\n\n---\n\n# Access Sections Summary\n\n| Access Section | Purpose |\n| --- | --- |\n| `payments` | Access to payment accounts |\n| `cards` | Access to card resources |\n| `cardAccounts` | Access to card accounts |\n\n---\n\n# Rights Summary\n\n| Right | Description |\n| --- | --- |\n| `ais` | General AIS access |\n| `ownerName` | Access to owner name |\n| `accountDetails` | Access to account details |\n| `balances` | Access to balances |\n| `transactions` | Access to transactions |\n\n---\n\n# Payment Body Presets\n\nDifferent body structures are used depending on the `payment_service` and `payment_product`.\n\nBelow are the main payment body types with fully populated examples.\n\n---\n\n# 1\\. Single Payment\n\n## Used for\n\n- `payments`\n    \n\n## Supported payment products\n\n- `sepa-credit-transfers`\n    \n- `instant-sepa-credit-transfers`\n    \n- `target-2-payments`\n    \n- `cross-border-credit-transfers`\n    \n\n## Fully populated example\n\n``` json\n{\n  \"instructedAmount\": {\n    \"amount\": \"1500.50\",\n    \"currency\": \"EUR\"\n  },\n  \"endToEndIdentification\": \"E2E-123456\",\n  \"creditor\": {\n    \"name\": \"John Smith\"\n  },\n  \"creditorName\": \"ACME Corp\",\n  \"creditorAccount\": {\n    \"iban\": \"DE89370400440532013000\",\n    \"bic\": \"BARCGB22XXX\"\n  },\n  \"debtorAccount\": {\n    \"iban\": \"ES9577529831786229644461\",\n    \"bic\": \"BARCGB22XXX\"\n  }\n}\n\n ```\n\n---\n\n# 2\\. Bulk Payment\n\n## Used for\n\n- `bulk-payments`\n    \n\n## Supported payment products\n\n- `sepa-credit-transfers`\n    \n- `instant-sepa-credit-transfers`\n    \n- `target-2-payments`\n    \n- `cross-border-credit-transfers`\n    \n\n## Fully populated example\n\n``` json\n{\n  \"paymentInformationId\": \"BULK-001\",\n  \"numberOfTransactions\": 2,\n  \"controlSum\": \"3001.00\",\n  \"creditTransfers\": [\n    {\n      \"instructedAmount\": {\n        \"amount\": \"1500.50\",\n        \"currency\": \"EUR\"\n      },\n      \"creditor\": {\n        \"name\": \"John Smith\"\n      },\n      \"creditorName\": \"ACME Corp\",\n      \"creditorAccount\": {\n        \"iban\": \"DE89370400440532013000\",\n        \"bic\": \"BARCGB22XXX\"\n      },\n      \"remittanceInformationUnstructured\": [\n        \"Invoice #1001\"\n      ]\n    },\n    {\n      \"instructedAmount\": {\n        \"amount\": \"1500.50\",\n        \"currency\": \"EUR\"\n      },\n      \"creditor\": {\n        \"name\": \"Jane Doe\"\n      },\n      \"creditorName\": \"Contoso Ltd\",\n      \"creditorAccount\": {\n        \"iban\": \"FR7630006000011234567890189\",\n        \"bic\": \"AGRIFRPPXXX\"\n      },\n      \"remittanceInformationUnstructured\": [\n        \"Invoice #1002\"\n      ]\n    }\n  ],\n  \"debtorAccount\": {\n    \"iban\": \"ES9577529831786229644461\",\n    \"bic\": \"BARCGB22XXX\"\n  }\n}\n\n ```\n\n---\n\n# 3\\. Periodic Payment\n\n## Used for\n\n- `periodic-payments`\n    \n\n## Supported payment products\n\n- `sepa-credit-transfers`\n    \n- `instant-sepa-credit-transfers`\n    \n- `target-2-payments`\n    \n- `cross-border-credit-transfers`\n    \n\n## Fully populated example\n\n``` json\n{\n  \"instructedAmount\": {\n    \"amount\": \"1500.50\",\n    \"currency\": \"EUR\"\n  },\n  \"endToEndIdentification\": \"E2E-123456\",\n  \"frequency\": \"Monthly\",\n  \"startDate\": \"2026-01-01\",\n  \"endDate\": \"2026-12-31\",\n  \"dayOfExecution\": \"15\",\n  \"creditor\": {\n    \"name\": \"John Smith\"\n  },\n  \"creditorName\": \"ACME Corp\",\n  \"creditorAccount\": {\n    \"iban\": \"DE89370400440532013000\",\n    \"bic\": \"BARCGB22XXX\"\n  },\n  \"debtorAccount\": {\n    \"iban\": \"ES9577529831786229644461\",\n    \"bic\": \"BARCGB22XXX\"\n  }\n}\n\n ```\n\n---\n\n# Payment Services Summary\n\n| Payment Service | Description |\n| --- | --- |\n| `payments` | Single payment |\n| `bulk-payments` | Bulk payment |\n| `periodic-payments` | Periodic payment |\n\n---\n\n# Payment Products Summary\n\n| Payment Product | Description |\n| --- | --- |\n| `sepa-credit-transfers` | SEPA Credit Transfer |\n| `instant-sepa-credit-transfers` | Instant SEPA Credit Transfer |\n| `target-2-payments` | TARGET2 Payment |\n| `cross-border-credit-transfers` | Cross-border Credit Transfer |",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "_exporter_id": "44919908",
    "_collection_link": "https://go.postman.co/collection/44919908-b2508ce7-05f2-461e-af30-70d38a76761a?source=collection_link"
  },
  "item": [
    {
      "name": "First Use Install",
      "item": [
        {
          "name": "jsrsasign.lib Install",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.sendRequest(\"https://kjur.github.io/jsrsasign/jsrsasign-all-min.js\", (err, res) => {",
                  "    if (!err) {",
                  "        pm.globals.set(\"jsrsasign\", res.text());",
                  "        console.log(\"✅ jsrsasign installed successfully!\");",
                  "    } else {",
                  "        console.error(\"❌ Failed to download jsrsasign:\", err);",
                  "    }",
                  "});"
                ],
                "type": "text/javascript",
                "packages": {},
                "requests": {}
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "https://postman-echo.com/get",
              "protocol": "https",
              "host": [
                "postman-echo",
                "com"
              ],
              "path": [
                "get"
              ]
            }
          },
          "response": []
        }
      ],
      "description": "Before using this collection we should run only once GET request from this folder!\n\nTo repeat: we need to run it only once!"
    },
    {
      "name": "Regulated API",
      "item": [
        {
          "name": "Global Consent",
          "item": [
            {
              "name": "Consent Create",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"x-request-id\", xRequestId)",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const response = pm.response.json();",
                      "pm.environment.set(\"consentId\", response.consentId);"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "header": [
                  {
                    "key": "PSU-IP-Address",
                    "value": "192.168.8.78",
                    "type": "text"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "Client-Redirect-URI",
                    "value": "https://google.com/",
                    "type": "text"
                  },
                  {
                    "key": "Accept",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"access\": {\n    \"payments\": [\n      {\n        \"rights\": [\"ais\", \"ownerName\"]\n      }\n    ]\n  },\n  \"consentType\": \"global\",\n  \"recurringIndicator\": true,\n  \"validTo\": \"2027-01-01\",\n  \"frequencyPerDay\": 4\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Show Consent",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}/{{consentId}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}",
                    "{{consentId}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Get Consent Status",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}/{{consentId}}/status",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}",
                    "{{consentId}}",
                    "status"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Delete Consent",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "DELETE",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}/{{consentId}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}",
                    "{{consentId}}"
                  ]
                }
              },
              "response": []
            }
          ]
        },
        {
          "name": "Detailed Consent",
          "item": [
            {
              "name": "Consent Create",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"x-request-id\", xRequestId)",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const response = pm.response.json();",
                      "pm.environment.set(\"consentId\", response.consentId);"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "header": [
                  {
                    "key": "PSU-IP-Address",
                    "value": "192.168.8.78",
                    "type": "text"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "Client-Redirect-URI",
                    "value": "https://google.com/",
                    "type": "text"
                  },
                  {
                    "key": "Accept",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"access\": {\n    \"payments\": [\n      {\n        \"account\": {\n          \"iban\": \"{{iban}}\"\n        },\n        \"rights\": [\n          \"accountDetails\",\n          \"balances\",\n          \"transactions\",\n          \"ownerName\"\n        ]\n      }\n    ]\n  },\n  \"consentType\": \"detailed\",\n  \"recurringIndicator\": true,\n  \"validTo\": \"2027-01-01\",\n  \"frequencyPerDay\": 4\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Show Consent",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}/{{consentId}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}",
                    "{{consentId}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Get Consent Status",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}/{{consentId}}/status",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}",
                    "{{consentId}}",
                    "status"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Delete Consent",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "DELETE",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}/{{consentId}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}",
                    "{{consentId}}"
                  ]
                }
              },
              "response": []
            }
          ]
        },
        {
          "name": "ASPSP Managed Consent",
          "item": [
            {
              "name": "Consent Create",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"x-request-id\", xRequestId)",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const response = pm.response.json();",
                      "pm.environment.set(\"consentId\", response.consentId);"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "header": [
                  {
                    "key": "PSU-IP-Address",
                    "value": "192.168.8.78",
                    "type": "text"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "Client-Redirect-URI",
                    "value": "https://google.com/",
                    "type": "text"
                  },
                  {
                    "key": "Accept",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"access\": {\n    \"payments\": [\n      {\n        \"rights\": [\n          \"accountDetails\",\n          \"balances\",\n          \"transactions\"\n        ]\n      }\n    ]\n  },\n  \"consentType\": \"aspspManaged\",\n  \"recurringIndicator\": true,\n  \"validTo\": \"2027-01-01\",\n  \"frequencyPerDay\": 4\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Show Consent",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}/{{consentId}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}",
                    "{{consentId}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Get Consent Status",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}/{{consentId}}/status",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}",
                    "{{consentId}}",
                    "status"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Delete Consent",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "DELETE",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}/{{consentId}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}",
                    "{{consentId}}"
                  ]
                }
              },
              "response": []
            }
          ]
        },
        {
          "name": "Account List Consent",
          "item": [
            {
              "name": "Consent Create",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"x-request-id\", xRequestId)",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const response = pm.response.json();",
                      "pm.environment.set(\"consentId\", response.consentId);"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "header": [
                  {
                    "key": "PSU-IP-Address",
                    "value": "192.168.8.78",
                    "type": "text"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "Client-Redirect-URI",
                    "value": "https://google.com/",
                    "type": "text"
                  },
                  {
                    "key": "Accept",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"access\": {\n    \"payments\": [\n      {\n        \"rights\": [\n          \"accountDetails\",\n          \"balances\",\n          \"ownerName\"\n        ]\n      }\n    ]\n  },\n  \"consentType\": \"accountList\",\n  \"recurringIndicator\": true,\n  \"validTo\": \"2027-01-01\",\n  \"frequencyPerDay\": 4\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Show Consent",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}/{{consentId}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}",
                    "{{consentId}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Get Consent Status",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}/{{consentId}}/status",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}",
                    "{{consentId}}",
                    "status"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Delete Consent",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "DELETE",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/consents/{{consent-category}}/{{consentId}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "consents",
                    "{{consent-category}}",
                    "{{consentId}}"
                  ]
                }
              },
              "response": []
            }
          ]
        },
        {
          "name": "Accounts",
          "item": [
            {
              "name": "Get Accounts",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const response = pm.response.json();",
                      "pm.environment.set(\"account_id\", response.accounts[0].resourceId);",
                      "",
                      "pm.environment.set(\"iban\", response.accounts[0].iban);"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "protocolProfileBehavior": {
                "disabledSystemHeaders": {}
              },
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text",
                    "disabled": true
                  },
                  {
                    "key": "Consent-ID",
                    "value": "{{consentId}}",
                    "type": "text"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*",
                    "type": "text",
                    "disabled": true
                  },
                  {
                    "key": "User-ID",
                    "value": "1",
                    "type": "text"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/{{account_type}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "{{account_type}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Get Account Info",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      ""
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "protocolProfileBehavior": {
                "disabledSystemHeaders": {}
              },
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text",
                    "disabled": true
                  },
                  {
                    "key": "Consent-ID",
                    "value": "{{consentId}}",
                    "type": "text"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*",
                    "type": "text",
                    "disabled": true
                  },
                  {
                    "key": "User-ID",
                    "value": "1",
                    "type": "text"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/{{account_type}}/{{account_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "{{account_type}}",
                    "{{account_id}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Get Account Balances",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      ""
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "protocolProfileBehavior": {
                "disabledSystemHeaders": {}
              },
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text",
                    "disabled": true
                  },
                  {
                    "key": "Consent-ID",
                    "value": "{{consentId}}",
                    "type": "text"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*",
                    "type": "text",
                    "disabled": true
                  },
                  {
                    "key": "User-ID",
                    "value": "1",
                    "type": "text"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/{{account_type}}/{{account_id}}/balances",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "{{account_type}}",
                    "{{account_id}}",
                    "balances"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Get Transactions",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const response = pm.response.json();",
                      "pm.environment.set(\"transactions_id\", response.transactions[0].transactionId);"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "protocolProfileBehavior": {
                "disabledSystemHeaders": {}
              },
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text",
                    "disabled": true
                  },
                  {
                    "key": "Consent-ID",
                    "value": "{{consentId}}",
                    "type": "text"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*",
                    "type": "text",
                    "disabled": true
                  },
                  {
                    "key": "User-ID",
                    "value": "1",
                    "type": "text"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/{{account_type}}/{{account_id}}/transactions",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "{{account_type}}",
                    "{{account_id}}",
                    "transactions"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Get Transaction Info",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      ""
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "protocolProfileBehavior": {
                "disabledSystemHeaders": {}
              },
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text",
                    "disabled": true
                  },
                  {
                    "key": "Consent-ID",
                    "value": "{{consentId}}",
                    "type": "text"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*",
                    "type": "text",
                    "disabled": true
                  },
                  {
                    "key": "User-ID",
                    "value": "1",
                    "type": "text"
                  }
                ],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/{{account_type}}/{{account_id}}/transactions/{{transactions_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "{{account_type}}",
                    "{{account_id}}",
                    "transactions",
                    "{{transactions_id}}"
                  ]
                }
              },
              "response": []
            }
          ]
        },
        {
          "name": "Single Payment",
          "item": [
            {
              "name": "Single Payment Create",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const response = pm.response.json();",
                      "pm.environment.set(\"payment_id\", response.paymentId);"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "protocolProfileBehavior": {
                "disabledSystemHeaders": {
                  "accept": true
                }
              },
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "header": [
                  {
                    "key": "PSU-IP-Address",
                    "value": "192.168.8.78",
                    "type": "text"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "Client-Redirect-URI",
                    "value": "https://google.com/",
                    "type": "text"
                  },
                  {
                    "key": "Accept",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \n    \"instructedAmount\": {\n      \"amount\": \"10.3\",\n      \"currency\": \"GBP\"\n    },\n    \"creditor\": {\n      \"name\": \"John Snow\"\n    },\n    \"endToEndIdentification\": \"12341234\",\n    \"creditorName\": \"John Smith\",\n    \"creditorAccount\": {\n      \"iban\": \"FK54RAND61068421435452\"\n    },\n    \"debtorAccount\": {\n      \"iban\": \"{{iban}}\",\n      \"bic\": \"BARCGB22XXX\"\n    }\n  }",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/payments/{{payment_product}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "payments",
                    "{{payment_product}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Show Single Payment",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/payments/{{payment_product}}/{{payment_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "payments",
                    "{{payment_product}}",
                    "{{payment_id}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Get Single Payment Status",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/payments/{{payment_product}}/{{payment_id}}/status",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "payments",
                    "{{payment_product}}",
                    "{{payment_id}}",
                    "status"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Delete Single Payment",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "DELETE",
                "header": [],
                "body": {
                  "mode": "raw",
                  "raw": "",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/payments/{{payment_product}}/{{payment_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "payments",
                    "{{payment_product}}",
                    "{{payment_id}}"
                  ]
                }
              },
              "response": []
            }
          ]
        },
        {
          "name": "Bulk Payment",
          "item": [
            {
              "name": "Bulk Payment Create",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const response = pm.response.json();",
                      "pm.environment.set(\"payment_id\", response.paymentId);"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "protocolProfileBehavior": {
                "disabledSystemHeaders": {
                  "accept": true
                }
              },
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "header": [
                  {
                    "key": "PSU-IP-Address",
                    "value": "192.168.8.78",
                    "type": "text"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "Client-Redirect-URI",
                    "value": "https://google.com/",
                    "type": "text"
                  },
                  {
                    "key": "Accept",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"paymentInformationId\": \"BULK-001\",\n  \"numberOfTransactions\": 2,\n  \"controlSum\": \"3001.00\",\n  \"creditTransfers\": [\n    {\n      \"instructedAmount\": {\n        \"amount\": \"1500.50\",\n        \"currency\": \"EUR\"\n      },\n      \"creditor\": {\n        \"name\": \"John Smith\"\n      },\n      \"creditorName\": \"ACME Corp\",\n      \"creditorAccount\": {\n        \"iban\": \"DE89370400440532013000\",\n        \"bic\": \"BARCGB22XXX\"\n      },\n      \"remittanceInformationUnstructured\": [\n        \"Invoice #1001\"\n      ]\n    },\n    {\n      \"instructedAmount\": {\n        \"amount\": \"1500.50\",\n        \"currency\": \"EUR\"\n      },\n      \"creditor\": {\n        \"name\": \"Jane Doe\"\n      },\n      \"creditorName\": \"Contoso Ltd\",\n      \"creditorAccount\": {\n        \"iban\": \"FR7630006000011234567890189\",\n        \"bic\": \"AGRIFRPPXXX\"\n      },\n      \"remittanceInformationUnstructured\": [\n        \"Invoice #1002\"\n      ]\n    }\n  ],\n  \"debtorAccount\": {\n    \"iban\": \"{{iban}}\",\n    \"bic\": \"BARCGB22XXX\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/bulk-payments/{{payment_product}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "bulk-payments",
                    "{{payment_product}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Show Bulk Payment",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/bulk-payments/{{payment_product}}/{{payment_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "bulk-payments",
                    "{{payment_product}}",
                    "{{payment_id}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Get Bulk Payment Status",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/bulk-payments/{{payment_product}}/{{payment_id}}/status",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "bulk-payments",
                    "{{payment_product}}",
                    "{{payment_id}}",
                    "status"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Delete Bulk Payment",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "DELETE",
                "header": [],
                "body": {
                  "mode": "raw",
                  "raw": "",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/bulk-payments/{{payment_product}}/{{payment_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "bulk-payments",
                    "{{payment_product}}",
                    "{{payment_id}}"
                  ]
                }
              },
              "response": []
            }
          ]
        },
        {
          "name": "Periodic Payment",
          "item": [
            {
              "name": "Periodic Payment Create",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "exec": [
                      "const response = pm.response.json();",
                      "pm.environment.set(\"payment_id\", response.paymentId);"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "protocolProfileBehavior": {
                "disabledSystemHeaders": {
                  "accept": true
                }
              },
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "header": [
                  {
                    "key": "PSU-IP-Address",
                    "value": "192.168.8.78",
                    "type": "text"
                  },
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "Client-Redirect-URI",
                    "value": "https://google.com/",
                    "type": "text"
                  },
                  {
                    "key": "Accept",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"instructedAmount\": {\n    \"amount\": \"1500.50\",\n    \"currency\": \"EUR\"\n  },\n  \"endToEndIdentification\": \"E2E-123456\",\n  \"frequency\": \"Monthly\",\n  \"startDate\": \"2026-08-08\",\n  \"endDate\": \"2026-12-31\",\n  \"dayOfExecution\": \"15\",\n  \"creditor\": {\n    \"name\": \"John Smith\"\n  },\n  \"creditorName\": \"ACME Corp\",\n  \"creditorAccount\": {\n    \"iban\": \"DE89370400440532013000\",\n    \"bic\": \"BARCGB22XXX\"\n  },\n  \"debtorAccount\": {\n    \"iban\": \"{{iban}}\",\n    \"bic\": \"BARCGB22XXX\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/periodic-payments/{{payment_product}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "periodic-payments",
                    "{{payment_product}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Show Periodic Payment",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/periodic-payments/{{payment_product}}/{{payment_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "periodic-payments",
                    "{{payment_product}}",
                    "{{payment_id}}"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Get Periodic Payment Status",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/periodic-payments/{{payment_product}}/{{payment_id}}/status",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "periodic-payments",
                    "{{payment_product}}",
                    "{{payment_id}}",
                    "status"
                  ]
                }
              },
              "response": []
            },
            {
              "name": "Delete Periodic Payment",
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "exec": [
                      "// Detached JWS (x-jws-signature) builder — UNIVERSAL (JSON + XML SAFE)",
                      "",
                      "// ---------- LOAD LIB ----------",
                      "if (typeof KJUR === 'undefined') {",
                      "    const lib = pm.globals.get(\"jsrsasign\");",
                      "    if (!lib) throw new Error(\"jsrsasign not installed\");",
                      "    if (typeof navigator === 'undefined') var navigator = {};",
                      "    if (typeof window === 'undefined') var window = {};",
                      "    eval(lib);",
                      "}",
                      "",
                      "// ---------- CONFIG ----------",
                      "const CONFIG = {",
                      "    privateKey: pm.environment.get(\"TPP_PRIVATE_KEY\"),",
                      "    signCert: pm.environment.get(\"TPP_SIGN_CERT\"),",
                      "    alg: pm.environment.get(\"SIGN_ALG\") || \"RS256\",",
                      "    mandatoryHeaders: [\"x-request-id\", \"digest\"],",
                      "    conditionalHeaders: [\"api-contract-id\", \"psu-id\", \"psu-corporate-id\", \"client-redirect-uri\"]",
                      "};",
                      "",
                      "if (!CONFIG.privateKey) throw new Error(\"TPP_PRIVATE_KEY missing\");",
                      "if (!CONFIG.signCert) throw new Error(\"TPP_SIGN_CERT missing\");",
                      "",
                      "// ---------- UTILS ----------",
                      "const Utils = {",
                      "    base64url: (str) =>",
                      "        CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, ''),",
                      "",
                      "    pemToDer: (pem) =>",
                      "        pem.replace(/-----BEGIN CERTIFICATE-----/g, '')",
                      "           .replace(/-----END CERTIFICATE-----/g, '')",
                      "           .replace(/\\s/g, ''),",
                      "",
                      "    timestamp: () =>",
                      "        new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),",
                      "",
                      "    sha256Digest: (body) => {",
                      "        const hash = CryptoJS.SHA256(body);",
                      "        return `SHA-256=${CryptoJS.enc.Base64.stringify(hash)}`;",
                      "    },",
                      "",
                      "    setHeader: (name, value) => {",
                      "        pm.request.headers.upsert({ key: name, value });",
                      "    },",
                      "",
                      "    resolve: (val) =>",
                      "        pm.variables.replaceIn(String(val || \"\")).trim(),",
                      "",
                      "    normalizeBody: (body) => {",
                      "        return body",
                      "            .replace(/\\r\\n/g, \"\\n\") // CRLF → LF",
                      "            .trim();",
                      "    },",
                      "",
                      "    sign: (data, key, alg) => {",
                      "        const map = {",
                      "            RS256: \"SHA256withRSA\",",
                      "            RS384: \"SHA384withRSA\",",
                      "            RS512: \"SHA512withRSA\",",
                      "            PS256: \"SHA256withRSAandMGF1\",",
                      "            PS384: \"SHA384withRSAandMGF1\",",
                      "            PS512: \"SHA512withRSAandMGF1\"",
                      "        };",
                      "",
                      "        const sig = new KJUR.crypto.Signature({ alg: map[alg] });",
                      "        sig.init(key.replace(/\\\\n/g, \"\\n\"));",
                      "        sig.updateString(data);",
                      "",
                      "        return hextob64(sig.sign())",
                      "            .replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');",
                      "    }",
                      "};",
                      "",
                      "// ---------- STEP 1: BODY (FIXED) ----------",
                      "let rawBody = pm.request.body?.raw || \"\";",
                      "",
                      "// 🔥 КРИТИЧНО: резолвим переменные",
                      "rawBody = pm.variables.replaceIn(rawBody);",
                      "",
                      "// 🔥 нормализуем",
                      "const body = Utils.normalizeBody(rawBody);",
                      "",
                      "// ---------- STEP 2: DIGEST ----------",
                      "const digest = Utils.sha256Digest(body);",
                      "Utils.setHeader(\"Digest\", digest);",
                      "",
                      "// ---------- STEP 3: X-REQUEST-ID ----------",
                      "let xRequestId = Utils.resolve(pm.request.headers.get(\"x-request-id\"));",
                      "",
                      "if (!xRequestId || xRequestId.includes(\"{{\")) {",
                      "    xRequestId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {",
                      "        const r = Math.random() * 16 | 0;",
                      "        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);",
                      "    });",
                      "}",
                      "",
                      "Utils.setHeader(\"X-Request-Id\", xRequestId);",
                      "",
                      "// ---------- STEP 4: HEADERS TO SIGN ----------",
                      "const headersToSign = [...CONFIG.mandatoryHeaders];",
                      "",
                      "CONFIG.conditionalHeaders.forEach(name => {",
                      "    const val = Utils.resolve(pm.request.headers.get(name));",
                      "    if (val && !val.includes(\"{{\")) {",
                      "        headersToSign.push(name);",
                      "    }",
                      "});",
                      "",
                      "const uniqueHeaders = [...new Set(headersToSign)];",
                      "",
                      "// ---------- STEP 5: HEADERS STRING ----------",
                      "const headerLines = uniqueHeaders.map(name => {",
                      "    const value = Utils.resolve(pm.request.headers.get(name));",
                      "    if (!value) throw new Error(`Missing header: ${name}`);",
                      "    return `${name}: ${value}`;",
                      "});",
                      "",
                      "const headersString = headerLines.join(\"\\n\");",
                      "",
                      "// ---------- STEP 6: PATH ----------",
                      "const fullPath = pm.request.url.getPath();",
                      "const apiPath = (fullPath.match(/(\\/v\\d+\\/.*)/) || [])[1] || fullPath;",
                      "",
                      "// ---------- STEP 7: PROTECTED HEADER ----------",
                      "const protectedHeader = {",
                      "    typ: \"JOSE\",",
                      "    b64: false,",
                      "    x5c: [Utils.pemToDer(CONFIG.signCert)],",
                      "    crit: [\"b64\", \"sigT\", \"sigD\"],",
                      "    sigT: Utils.timestamp(),",
                      "    sigD: {",
                      "        pars: uniqueHeaders,",
                      "        mId: \"http://uri.etsi.org/19182/HttpHeaders\"",
                      "    },",
                      "    alg: CONFIG.alg,",
                      "    aud: `${pm.request.method} ${apiPath}`",
                      "};",
                      "",
                      "const protectedB64 = Utils.base64url(JSON.stringify(protectedHeader));",
                      "",
                      "// ---------- STEP 8: SIGN ----------",
                      "const signingInput = `${protectedB64}.${headersString}`;",
                      "const signature = Utils.sign(signingInput, CONFIG.privateKey, CONFIG.alg);",
                      "",
                      "// ---------- STEP 9: FINAL ----------",
                      "const jws = `${protectedB64}..${signature}`;",
                      "Utils.setHeader(\"x-jws-signature\", jws);",
                      "",
                      "// ---------- DEBUG ----------",
                      "console.log(\"════════════════════════════════════\");",
                      "console.log(\"BODY (normalized):\", JSON.stringify(body));",
                      "console.log(\"DIGEST:\", digest);",
                      "console.log(\"HEADERS:\", headersString);",
                      "console.log(\"SIGN INPUT:\", signingInput);",
                      "console.log(\"JWS:\", jws);",
                      "console.log(\"════════════════════════════════════\");"
                    ],
                    "type": "text/javascript",
                    "packages": {},
                    "requests": {}
                  }
                }
              ],
              "request": {
                "method": "DELETE",
                "header": [],
                "body": {
                  "mode": "raw",
                  "raw": "",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{base_url}}/{{provider_code}}/api/v2/periodic-payments/{{payment_product}}/{{payment_id}}",
                  "host": [
                    "{{base_url}}"
                  ],
                  "path": [
                    "{{provider_code}}",
                    "api",
                    "v2",
                    "periodic-payments",
                    "{{payment_product}}",
                    "{{payment_id}}"
                  ]
                }
              },
              "response": []
            }
          ]
        }
      ]
    }
  ]
}