{
  "name": "Запись Management API без Idempotency-Key не повторяется после отправки",
  "description": "createLocation после 503 и после обрыва ответа не повторяется: ошибка server и transport с mayHaveBeenProcessed = true. Сбой соединения до отправки повторяется для любого запроса; если он не проходит — transport с mayHaveBeenProcessed = false. adjustMemberPoints объявляет необязательный Idempotency-Key: SDK создаёт ключ, и запрос повторяется после 503 с тем же ключом. 429 повторяется и без ключа. PUT не считается безопасным для повтора.",
  "client": {
    "api": "management",
    "credential": {"merchantKey": "lm_test_c0ffee5h0p01.4hc9xYLN7niA1mYZROcNs3EQZcXjncE7IShJcV5BvvQ"},
    "baseUrl": "https://api.example.com"
  },
  "calls": [
    {
      "operation": "createLocation",
      "args": {"body": {"code": "msk-01", "name": "Кофейня на Тверской", "address": "Москва, Тверская ул., 1"}},
      "expect": {
        "error": {
          "class": "server",
          "status": 503,
          "code": "http_503",
          "requestId": "01929c20-0001-7000-8000-000000000001"
        }
      }
    },
    {
      "operation": "createLocation",
      "args": {"body": {"code": "msk-01", "name": "Кофейня на Тверской", "address": "Москва, Тверская ул., 1"}},
      "expect": {"error": {"class": "transport", "mayHaveBeenProcessed": true, "idempotencyKey": null}}
    },
    {
      "operation": "createBrand",
      "args": {"body": {"name": "Зерно"}},
      "expect": {"result": {"id": "01929c1e-0032-7032-8032-000000000032", "name": "Зерно"}}
    },
    {
      "operation": "adjustMemberPoints",
      "args": {"member": "01929c1e-0040-7040-8040-000000000040", "body": {"amount": 500, "reason_code": "goodwill"}},
      "expect": {
        "result": {
          "transaction_id": "01929c1e-0093-7093-8093-000000000093",
          "amount": 500,
          "member_delta": 500,
          "available": 1535
        }
      }
    },
    {
      "operation": "createLocation",
      "args": {"body": {"code": "msk-01", "name": "Кофейня на Тверской", "address": "Москва, Тверская ул., 1"}},
      "expect": {
        "result": {
          "id": "01929c1e-0030-7030-8030-000000000030",
          "code": "msk-01",
          "name": "Кофейня на Тверской",
          "address": "Москва, Тверская ул., 1",
          "timezone": "Europe/Moscow",
          "brand_id": null,
          "legal_entity_id": null,
          "status": "active"
        }
      }
    },
    {
      "operation": "createBrand",
      "args": {"body": {"name": "Зерно"}},
      "expect": {"error": {"class": "transport", "mayHaveBeenProcessed": false}}
    },
    {
      "operation": "updateProgramRules",
      "args": {
        "program": "01929c1e-0010-7010-8010-000000000010",
        "body": {
          "point_type_id": "01929c1e-0011-7011-8011-000000000011",
          "accrual_percent_bp": 500,
          "redemption_confirmation": "weak_identifiers"
        }
      },
      "expect": {"error": {"class": "server", "status": 502, "code": null}}
    }
  ],
  "exchanges": [
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/management/v1/locations",
        "headers": {
          "authorization": "Bearer lm_test_c0ffee5h0p01.4hc9xYLN7niA1mYZROcNs3EQZcXjncE7IShJcV5BvvQ",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": null,
          "loyal-merchant": null
        },
        "json": {"code": "msk-01", "name": "Кофейня на Тверской", "address": "Москва, Тверская ул., 1"}
      },
      "response": {
        "status": 503,
        "headers": {
          "Content-Type": "application/problem+json",
          "X-Request-Id": "01929c20-0001-7000-8000-000000000001",
          "Loyal-Environment": "sandbox"
        },
        "json": {
          "type": "urn:loyal:problem:http_503",
          "title": "Service Unavailable",
          "status": 503,
          "code": "http_503",
          "request_id": "01929c20-0001-7000-8000-000000000001"
        }
      }
    },
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/management/v1/locations",
        "headers": {
          "authorization": "Bearer lm_test_c0ffee5h0p01.4hc9xYLN7niA1mYZROcNs3EQZcXjncE7IShJcV5BvvQ",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": null,
          "loyal-merchant": null
        },
        "json": {"code": "msk-01", "name": "Кофейня на Тверской", "address": "Москва, Тверская ул., 1"}
      },
      "failure": "after_send"
    },
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/management/v1/brands",
        "headers": {
          "authorization": "Bearer lm_test_c0ffee5h0p01.4hc9xYLN7niA1mYZROcNs3EQZcXjncE7IShJcV5BvvQ",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": null,
          "loyal-merchant": null
        },
        "json": {"name": "Зерно"}
      },
      "failure": "before_send"
    },
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/management/v1/brands",
        "headers": {
          "authorization": "Bearer lm_test_c0ffee5h0p01.4hc9xYLN7niA1mYZROcNs3EQZcXjncE7IShJcV5BvvQ",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": null,
          "loyal-merchant": null
        },
        "json": {"name": "Зерно"}
      },
      "response": {
        "status": 201,
        "headers": {
          "Content-Type": "application/json",
          "X-Request-Id": "01929c20-0002-7000-8000-000000000002",
          "Loyal-Environment": "sandbox"
        },
        "json": {"id": "01929c1e-0032-7032-8032-000000000032", "name": "Зерно"}
      }
    },
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/management/v1/members/01929c1e-0040-7040-8040-000000000040/point-adjustments",
        "headers": {
          "authorization": "Bearer lm_test_c0ffee5h0p01.4hc9xYLN7niA1mYZROcNs3EQZcXjncE7IShJcV5BvvQ",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": "{{idempotency-key}}",
          "loyal-merchant": null
        },
        "json": {"amount": 500, "reason_code": "goodwill"}
      },
      "response": {
        "status": 503,
        "headers": {
          "Content-Type": "application/problem+json",
          "X-Request-Id": "01929c20-0003-7000-8000-000000000003",
          "Loyal-Environment": "sandbox"
        },
        "json": {
          "type": "urn:loyal:problem:http_503",
          "title": "Service Unavailable",
          "status": 503,
          "code": "http_503",
          "request_id": "01929c20-0003-7000-8000-000000000003"
        }
      }
    },
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/management/v1/members/01929c1e-0040-7040-8040-000000000040/point-adjustments",
        "headers": {
          "authorization": "Bearer lm_test_c0ffee5h0p01.4hc9xYLN7niA1mYZROcNs3EQZcXjncE7IShJcV5BvvQ",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": "{{idempotency-key}}",
          "loyal-merchant": null
        },
        "json": {"amount": 500, "reason_code": "goodwill"}
      },
      "response": {
        "status": 201,
        "headers": {
          "Content-Type": "application/json",
          "X-Request-Id": "01929c20-0004-7000-8000-000000000004",
          "Loyal-Environment": "sandbox"
        },
        "json": {
          "transaction_id": "01929c1e-0093-7093-8093-000000000093",
          "amount": 500,
          "member_delta": 500,
          "available": 1535
        }
      }
    },
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/management/v1/locations",
        "headers": {
          "authorization": "Bearer lm_test_c0ffee5h0p01.4hc9xYLN7niA1mYZROcNs3EQZcXjncE7IShJcV5BvvQ",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": null,
          "loyal-merchant": null
        },
        "json": {"code": "msk-01", "name": "Кофейня на Тверской", "address": "Москва, Тверская ул., 1"}
      },
      "response": {
        "status": 429,
        "headers": {
          "Content-Type": "application/problem+json",
          "X-Request-Id": "01929c20-0005-7000-8000-000000000005",
          "Loyal-Environment": "sandbox",
          "Retry-After": "1",
          "RateLimit-Limit": "60",
          "RateLimit-Remaining": "0",
          "RateLimit-Reset": "1"
        },
        "json": {
          "type": "urn:loyal:problem:too_many_requests",
          "title": "Too many requests.",
          "status": 429,
          "code": "too_many_requests",
          "request_id": "01929c20-0005-7000-8000-000000000005"
        }
      }
    },
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/management/v1/locations",
        "headers": {
          "authorization": "Bearer lm_test_c0ffee5h0p01.4hc9xYLN7niA1mYZROcNs3EQZcXjncE7IShJcV5BvvQ",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": null,
          "loyal-merchant": null
        },
        "json": {"code": "msk-01", "name": "Кофейня на Тверской", "address": "Москва, Тверская ул., 1"}
      },
      "response": {
        "status": 201,
        "headers": {
          "Content-Type": "application/json",
          "X-Request-Id": "01929c20-0006-7000-8000-000000000006",
          "Loyal-Environment": "sandbox"
        },
        "json": {
          "id": "01929c1e-0030-7030-8030-000000000030",
          "code": "msk-01",
          "name": "Кофейня на Тверской",
          "address": "Москва, Тверская ул., 1",
          "timezone": "Europe/Moscow",
          "brand_id": null,
          "legal_entity_id": null,
          "status": "active"
        }
      }
    },
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/management/v1/brands",
        "headers": {
          "authorization": "Bearer lm_test_c0ffee5h0p01.4hc9xYLN7niA1mYZROcNs3EQZcXjncE7IShJcV5BvvQ",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": null,
          "loyal-merchant": null
        },
        "json": {"name": "Зерно"}
      },
      "failure": "before_send"
    },
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/management/v1/brands",
        "headers": {
          "authorization": "Bearer lm_test_c0ffee5h0p01.4hc9xYLN7niA1mYZROcNs3EQZcXjncE7IShJcV5BvvQ",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": null,
          "loyal-merchant": null
        },
        "json": {"name": "Зерно"}
      },
      "failure": "before_send"
    },
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/management/v1/brands",
        "headers": {
          "authorization": "Bearer lm_test_c0ffee5h0p01.4hc9xYLN7niA1mYZROcNs3EQZcXjncE7IShJcV5BvvQ",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": null,
          "loyal-merchant": null
        },
        "json": {"name": "Зерно"}
      },
      "failure": "before_send"
    },
    {
      "request": {
        "method": "PUT",
        "url": "https://api.example.com/api/management/v1/programs/01929c1e-0010-7010-8010-000000000010/rules",
        "headers": {
          "authorization": "Bearer lm_test_c0ffee5h0p01.4hc9xYLN7niA1mYZROcNs3EQZcXjncE7IShJcV5BvvQ",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": null,
          "loyal-merchant": null
        },
        "json": {
          "point_type_id": "01929c1e-0011-7011-8011-000000000011",
          "accrual_percent_bp": 500,
          "redemption_confirmation": "weak_identifiers"
        }
      },
      "response": {
        "status": 502,
        "headers": {"Content-Type": "text/html"},
        "text": "<html><head><title>502 Bad Gateway</title></head><body><h1>502 Bad Gateway</h1></body></html>"
      }
    }
  ],
  "sleeps": [500, 500, 1000, 500, 1000]
}
