{
  "name": "Ключ идемпотентности: свой UUIDv4 на каждый вызов или ключ вызывающего; где ключа нет — он запрещён",
  "description": "Без ключа вызывающего SDK создаёт UUIDv4 — новый для каждого вызова. Ключ вызывающего уходит как есть. Ключ у операции без Idempotency-Key и ключ с пробелом — ошибка configuration без запроса. Повтор, на который сервер ответил сохранённым ответом, виден в метаданных (Idempotent-Replayed).",
  "client": {
    "api": "runtime",
    "credential": {"terminalKey": "lk_test_k7m2p9q4r8s3.RqTvNAJirupwDOPZ8O48PZpsbGlZGfecp04FD7w06kw"},
    "baseUrl": "https://api.example.com"
  },
  "calls": [
    {
      "operation": "registerMember",
      "args": {
        "body": {
          "phone": "+79000000001",
          "consents": ["program_rules", "personal_data"],
          "first_name": "Анна",
          "email": "anna@example.com"
        }
      },
      "expect": {
        "result": {
          "id": "01929c1e-0040-7040-8040-000000000040",
          "status": "active",
          "masked_phone": "+7 *** ***-00-01",
          "first_name": "Анна",
          "registered_at": "2026-10-11T11:58:30.000000Z",
          "referral_code": "ANNA-7K2P",
          "balance": {
            "point_type_id": "01929c1e-0011-7011-8011-000000000011",
            "precision": 0,
            "available": 0,
            "pending": 0,
            "held": 0,
            "spendable": 0,
            "next_expiration": null
          },
          "tier": null,
          "stamps": []
        }
      }
    },
    {
      "operation": "issuePresentationCode",
      "args": {"member": "01929c1e-0040-7040-8040-000000000040"},
      "expect": {"result": {"code": "LY7K2P9Q", "expires_at": "2026-10-11T12:05:00.000000Z"}}
    },
    {
      "operation": "sendRegistrationCode",
      "args": {"body": {"phone": "+79000000002"}},
      "options": {"idempotencyKey": "registration:+79000000002:1"},
      "expect": {
        "result": {
          "verification_id": "01929c1e-0070-7070-8070-000000000070",
          "masked_recipient": "+7 *** ***-00-02",
          "channel": "sms",
          "expires_at": "2026-10-11T12:05:00.000000Z"
        },
        "meta": {"status": 201, "requestId": "01929c20-0003-7000-8000-000000000003", "idempotentReplayed": true}
      }
    },
    {
      "operation": "verifyCode",
      "args": {"verification": "01929c1e-0070-7070-8070-000000000070", "body": {"code": "000000"}},
      "options": {"idempotencyKey": "verify:1"},
      "expect": {"error": {"class": "configuration"}}
    },
    {
      "operation": "issuePresentationCode",
      "args": {"member": "01929c1e-0040-7040-8040-000000000040"},
      "options": {"idempotencyKey": "two words"},
      "expect": {"error": {"class": "configuration"}}
    },
    {
      "operation": "getBalance",
      "args": {"member": "01929c1e-0040-7040-8040-000000000040"},
      "expect": {
        "result": {
          "point_type_id": "01929c1e-0011-7011-8011-000000000011",
          "precision": 0,
          "available": 1035,
          "pending": 0,
          "held": 0,
          "spendable": 1035,
          "next_expiration": {"amount": 35, "at": "2027-10-11T12:00:01.250000Z"}
        }
      }
    }
  ],
  "exchanges": [
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/v1/members",
        "headers": {
          "authorization": "Bearer lk_test_k7m2p9q4r8s3.RqTvNAJirupwDOPZ8O48PZpsbGlZGfecp04FD7w06kw",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": "{{idempotency-key}}",
          "loyal-merchant": null
        },
        "json": {
          "phone": "+79000000001",
          "consents": ["program_rules", "personal_data"],
          "first_name": "Анна",
          "email": "anna@example.com"
        }
      },
      "response": {
        "status": 201,
        "headers": {
          "Content-Type": "application/json",
          "X-Request-Id": "01929c20-0001-7000-8000-000000000001",
          "Loyal-Environment": "sandbox"
        },
        "json": {
          "id": "01929c1e-0040-7040-8040-000000000040",
          "status": "active",
          "masked_phone": "+7 *** ***-00-01",
          "first_name": "Анна",
          "registered_at": "2026-10-11T11:58:30.000000Z",
          "referral_code": "ANNA-7K2P",
          "balance": {
            "point_type_id": "01929c1e-0011-7011-8011-000000000011",
            "precision": 0,
            "available": 0,
            "pending": 0,
            "held": 0,
            "spendable": 0,
            "next_expiration": null
          },
          "tier": null,
          "stamps": []
        }
      }
    },
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/v1/members/01929c1e-0040-7040-8040-000000000040/presentation-codes",
        "headers": {
          "authorization": "Bearer lk_test_k7m2p9q4r8s3.RqTvNAJirupwDOPZ8O48PZpsbGlZGfecp04FD7w06kw",
          "accept": "application/json",
          "content-type": null,
          "idempotency-key": "{{idempotency-key}}",
          "loyal-merchant": null
        }
      },
      "response": {
        "status": 201,
        "headers": {
          "Content-Type": "application/json",
          "X-Request-Id": "01929c20-0002-7000-8000-000000000002",
          "Loyal-Environment": "sandbox"
        },
        "json": {"code": "LY7K2P9Q", "expires_at": "2026-10-11T12:05:00.000000Z"}
      }
    },
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/v1/members:send-code",
        "headers": {
          "authorization": "Bearer lk_test_k7m2p9q4r8s3.RqTvNAJirupwDOPZ8O48PZpsbGlZGfecp04FD7w06kw",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": "registration:+79000000002:1",
          "loyal-merchant": null
        },
        "json": {"phone": "+79000000002"}
      },
      "response": {
        "status": 201,
        "headers": {
          "Content-Type": "application/json",
          "X-Request-Id": "01929c20-0003-7000-8000-000000000003",
          "Loyal-Environment": "sandbox",
          "Idempotent-Replayed": "true"
        },
        "json": {
          "verification_id": "01929c1e-0070-7070-8070-000000000070",
          "masked_recipient": "+7 *** ***-00-02",
          "channel": "sms",
          "expires_at": "2026-10-11T12:05:00.000000Z"
        }
      }
    },
    {
      "request": {
        "method": "GET",
        "url": "https://api.example.com/api/v1/members/01929c1e-0040-7040-8040-000000000040/balance",
        "headers": {
          "authorization": "Bearer lk_test_k7m2p9q4r8s3.RqTvNAJirupwDOPZ8O48PZpsbGlZGfecp04FD7w06kw",
          "accept": "application/json",
          "content-type": null,
          "idempotency-key": null,
          "loyal-merchant": null
        }
      },
      "response": {
        "status": 200,
        "headers": {
          "Content-Type": "application/json",
          "X-Request-Id": "01929c20-0004-7000-8000-000000000004",
          "Loyal-Environment": "sandbox"
        },
        "json": {
          "point_type_id": "01929c1e-0011-7011-8011-000000000011",
          "precision": 0,
          "available": 1035,
          "pending": 0,
          "held": 0,
          "spendable": 1035,
          "next_expiration": {"amount": 35, "at": "2027-10-11T12:00:01.250000Z"}
        }
      }
    }
  ],
  "sleeps": []
}
