{
  "name": "Действие через двоеточие: POST /receipts/{receipt}:confirm и :cancel",
  "description": "Двоеточие действия — часть шаблона пути и не кодируется. Завершающий «/» базового адреса отбрасывается. Операция без тела (cancelReceipt) не отправляет ни тела, ни Content-Type; ключ идемпотентности вызывающего уходит как есть, без ключа SDK создаёт свой.",
  "client": {
    "api": "runtime",
    "credential": {"terminalKey": "lk_test_k7m2p9q4r8s3.RqTvNAJirupwDOPZ8O48PZpsbGlZGfecp04FD7w06kw"},
    "baseUrl": "https://api.example.com/"
  },
  "calls": [
    {
      "operation": "confirmReceipt",
      "args": {
        "receipt": "01929c1e-0050-7050-8050-000000000050",
        "body": {"fiscal": {"drive": "9999078900001234", "document": "1042", "sign": "3522438401"}}
      },
      "options": {"idempotencyKey": "receipt:k7m2p9q4r8s3:2026-10-11:1042:confirm"},
      "expect": {
        "result": {
          "id": "01929c1e-0050-7050-8050-000000000050",
          "status": "confirmed",
          "number": "1042",
          "business_date": "2026-10-11",
          "purchased_at": "2026-10-11T14:59:58+03:00",
          "member": {
            "id": "01929c1e-0040-7040-8040-000000000040",
            "masked_phone": "+7 *** ***-00-01",
            "status": "active"
          },
          "points": {"point_type_id": "01929c1e-0011-7011-8011-000000000011", "precision": 0},
          "rules": {"snapshot_id": "01929c1e-0012-7012-8012-000000000012", "version": 3},
          "total": 100000,
          "discount": 0,
          "redeemed_money": 30000,
          "redeemed_points": 300,
          "points_earned": 35,
          "payable": 70000,
          "max_redeemable_points": 1000,
          "redemption_confirmation_required": false,
          "lines": [
            {
              "id": "1",
              "amount": 100000,
              "discount": 0,
              "redeemed_money": 30000,
              "redeemed_points": 300,
              "points_earned": 35,
              "payable": 70000,
              "returned_quantity": 0
            }
          ],
          "campaigns": [],
          "stamps": [],
          "explanation": [{"code": "accrual", "data": {"percent_bp": 500, "base": 70000, "points": 35}}],
          "reserved_until": null,
          "confirmed_at": "2026-10-11T12:00:01.250000Z"
        },
        "meta": {
          "operationId": "confirmReceipt",
          "method": "POST",
          "path": "/api/v1/receipts/{receipt}:confirm",
          "status": 200,
          "requestId": "01929c20-0001-7000-8000-000000000001",
          "idempotentReplayed": false,
          "environment": "sandbox"
        }
      }
    },
    {
      "operation": "cancelReceipt",
      "args": {"receipt": "01929c1e-0050-7050-8050-000000000050"},
      "expect": {
        "result": {
          "id": "01929c1e-0050-7050-8050-000000000050",
          "status": "voided",
          "number": "1042",
          "business_date": "2026-10-11",
          "purchased_at": "2026-10-11T14:59:58+03:00",
          "member": {
            "id": "01929c1e-0040-7040-8040-000000000040",
            "masked_phone": "+7 *** ***-00-01",
            "status": "active"
          },
          "points": {"point_type_id": "01929c1e-0011-7011-8011-000000000011", "precision": 0},
          "rules": {"snapshot_id": "01929c1e-0012-7012-8012-000000000012", "version": 3},
          "total": 100000,
          "discount": 0,
          "redeemed_money": 30000,
          "redeemed_points": 300,
          "points_earned": 35,
          "payable": 70000,
          "max_redeemable_points": 1000,
          "redemption_confirmation_required": false,
          "lines": [
            {
              "id": "1",
              "amount": 100000,
              "discount": 0,
              "redeemed_money": 30000,
              "redeemed_points": 300,
              "points_earned": 35,
              "payable": 70000,
              "returned_quantity": 0
            }
          ],
          "campaigns": [],
          "stamps": [],
          "explanation": [{"code": "accrual", "data": {"percent_bp": 500, "base": 70000, "points": 35}}],
          "reserved_until": null,
          "confirmed_at": "2026-10-11T12:00:01.250000Z"
        }
      }
    }
  ],
  "exchanges": [
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/v1/receipts/01929c1e-0050-7050-8050-000000000050:confirm",
        "headers": {
          "authorization": "Bearer lk_test_k7m2p9q4r8s3.RqTvNAJirupwDOPZ8O48PZpsbGlZGfecp04FD7w06kw",
          "accept": "application/json",
          "content-type": "application/json",
          "idempotency-key": "receipt:k7m2p9q4r8s3:2026-10-11:1042:confirm",
          "loyal-merchant": null
        },
        "json": {"fiscal": {"drive": "9999078900001234", "document": "1042", "sign": "3522438401"}}
      },
      "response": {
        "status": 200,
        "headers": {
          "Content-Type": "application/json",
          "X-Request-Id": "01929c20-0001-7000-8000-000000000001",
          "Loyal-Environment": "sandbox"
        },
        "json": {
          "id": "01929c1e-0050-7050-8050-000000000050",
          "status": "confirmed",
          "number": "1042",
          "business_date": "2026-10-11",
          "purchased_at": "2026-10-11T14:59:58+03:00",
          "member": {
            "id": "01929c1e-0040-7040-8040-000000000040",
            "masked_phone": "+7 *** ***-00-01",
            "status": "active"
          },
          "points": {"point_type_id": "01929c1e-0011-7011-8011-000000000011", "precision": 0},
          "rules": {"snapshot_id": "01929c1e-0012-7012-8012-000000000012", "version": 3},
          "total": 100000,
          "discount": 0,
          "redeemed_money": 30000,
          "redeemed_points": 300,
          "points_earned": 35,
          "payable": 70000,
          "max_redeemable_points": 1000,
          "redemption_confirmation_required": false,
          "lines": [
            {
              "id": "1",
              "amount": 100000,
              "discount": 0,
              "redeemed_money": 30000,
              "redeemed_points": 300,
              "points_earned": 35,
              "payable": 70000,
              "returned_quantity": 0
            }
          ],
          "campaigns": [],
          "stamps": [],
          "explanation": [{"code": "accrual", "data": {"percent_bp": 500, "base": 70000, "points": 35}}],
          "reserved_until": null,
          "confirmed_at": "2026-10-11T12:00:01.250000Z"
        }
      }
    },
    {
      "request": {
        "method": "POST",
        "url": "https://api.example.com/api/v1/receipts/01929c1e-0050-7050-8050-000000000050:cancel",
        "headers": {
          "authorization": "Bearer lk_test_k7m2p9q4r8s3.RqTvNAJirupwDOPZ8O48PZpsbGlZGfecp04FD7w06kw",
          "accept": "application/json",
          "content-type": null,
          "idempotency-key": "{{idempotency-key}}",
          "loyal-merchant": null
        }
      },
      "response": {
        "status": 200,
        "headers": {
          "Content-Type": "application/json",
          "X-Request-Id": "01929c20-0002-7000-8000-000000000002",
          "Loyal-Environment": "sandbox"
        },
        "json": {
          "id": "01929c1e-0050-7050-8050-000000000050",
          "status": "voided",
          "number": "1042",
          "business_date": "2026-10-11",
          "purchased_at": "2026-10-11T14:59:58+03:00",
          "member": {
            "id": "01929c1e-0040-7040-8040-000000000040",
            "masked_phone": "+7 *** ***-00-01",
            "status": "active"
          },
          "points": {"point_type_id": "01929c1e-0011-7011-8011-000000000011", "precision": 0},
          "rules": {"snapshot_id": "01929c1e-0012-7012-8012-000000000012", "version": 3},
          "total": 100000,
          "discount": 0,
          "redeemed_money": 30000,
          "redeemed_points": 300,
          "points_earned": 35,
          "payable": 70000,
          "max_redeemable_points": 1000,
          "redemption_confirmation_required": false,
          "lines": [
            {
              "id": "1",
              "amount": 100000,
              "discount": 0,
              "redeemed_money": 30000,
              "redeemed_points": 300,
              "points_earned": 35,
              "payable": 70000,
              "returned_quantity": 0
            }
          ],
          "campaigns": [],
          "stamps": [],
          "explanation": [{"code": "accrual", "data": {"percent_bp": 500, "base": 70000, "points": 35}}],
          "reserved_until": null,
          "confirmed_at": "2026-10-11T12:00:01.250000Z"
        }
      }
    }
  ],
  "sleeps": []
}
