{
  "info": {
    "_postman_id": "4aac230f-75cc-4915-a3ea-ccc3eae7f4b8",
    "name": "Guru_API 1.0.0",
    "description": "# 🚀 Get started here\n\nThis collection guides you through CRUD operations (GET, POST, PUT, DELETE), variables, and tests.\n\n## 🔖 **How to use this collection**\n\n#### **Step 1: Send requests**\n\nRESTful APIs allow you to perform CRUD operations using the POST, GET, PUT, and DELETE HTTP methods.\n\nThis collection contains each of these request types. Open each request and click \"Send\" to see what happens.\n\n#### **Step 2: View responses**\n\nObserve the response tab for status code (200 OK), response time, and size.\n\n#### **Step 3: Send new Body data**\n\nUpdate or add new data in \"Body\" in the POST request. Typically, Body data is also used in PUT and PATCH requests.\n\n```\n{\n    \"name\": \"Add your name in the body\"\n}\n\n```\n\n#### **Step 4: Update the variable**\n\nVariables enable you to store and reuse values in Postman. We have created a variable called `base_url` with the sample request [https://postman-api-learner.glitch.me](https://postman-api-learner.glitch.me). Replace it with your API endpoint to customize this collection.\n\n#### **Step 5: Add tests in the \"Tests\" tab**\n\nTests help you confirm that your API is working as expected. You can write test scripts in JavaScript and view the output in the \"Test Results\" tab.\n\n<img src=\"https://content.pstmn.io/b5f280a7-4b09-48ec-857f-0a7ed99d7ef8/U2NyZWVuc2hvdCAyMDIzLTAzLTI3IGF0IDkuNDcuMjggUE0ucG5n\">\n\n## 💪 Pro tips\n\n- Use folders to group related requests and organize the collection.\n- Add more scripts in \"Tests\" to verify if the API works as expected and execute flows.\n    \n\n## ℹ️ Resources\n\n[Building requests](https://learning.postman.com/docs/sending-requests/requests/)  \n[Authorizing requests](https://learning.postman.com/docs/sending-requests/authorization/)  \n[Using variables](https://learning.postman.com/docs/sending-requests/variables/)  \n[Managing environments](https://learning.postman.com/docs/sending-requests/managing-environments/)  \n[Writing scripts](https://learning.postman.com/docs/writing-scripts/intro-to-scripts/)",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "_exporter_id": "959327"
  },
  "item": [
    {
      "name": "Auth",
      "item": [
        {
          "name": "Auth - Access Token",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                  "",
                  "pm.test(\"returns access_token and refresh_token\", () => {",
                  "    const body = pm.response.json();",
                  "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                  "    pm.expect(body.refresh_token, \"refresh_token\").to.be.a(\"string\").and.not.empty;",
                  "    pm.environment.set(\"access_token\", body.access_token);",
                  "    pm.environment.set(\"refresh_token\", body.refresh_token);",
                  "});",
                  "",
                  "pm.test(\"response time < 5000ms\", () => pm.expect(pm.response.responseTime).to.be.below(5000));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n    \"username\": \"{{username}}\",\n    \"password\": \"{{password}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{url}}/oauth/token",
              "host": [
                "{{url}}"
              ],
              "path": [
                "oauth",
                "token"
              ]
            }
          },
          "response": []
        },
        {
          "name": "Auth - Refresh Token",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                  "",
                  "pm.test(\"returns new access_token and refresh_token\", () => {",
                  "    const body = pm.response.json();",
                  "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                  "    pm.expect(body.refresh_token, \"refresh_token\").to.be.a(\"string\").and.not.empty;",
                  "    pm.environment.set(\"access_token\", body.access_token);",
                  "    pm.environment.set(\"refresh_token\", body.refresh_token);",
                  "});",
                  "",
                  "pm.test(\"response time < 5000ms\", () => pm.expect(pm.response.responseTime).to.be.below(5000));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n    \"refresh_token\": \"{{refresh_token}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{url}}/oauth/refreshtoken",
              "host": [
                "{{url}}"
              ],
              "path": [
                "oauth",
                "refreshtoken"
              ]
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "Shopping",
      "item": [
        {
          "name": "Get Offers",
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const addDays = (n) => {",
                  "    const d = new Date();",
                  "    d.setDate(d.getDate() + n);",
                  "    return d.toISOString().split('T')[0];",
                  "};",
                  "pm.environment.set('date_1', addDays(12));"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                  "",
                  "pm.test(\"returns non-empty offers array\", () => {",
                  "    const body = pm.response.json();",
                  "    pm.expect(body.offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                  "});",
                  "",
                  "pm.test(\"each offer has journeys with slices and a token\", () => {",
                  "    const offers = pm.response.json().offers;",
                  "    offers.forEach((offer, i) => {",
                  "        pm.expect(offer.journeys, `offer[${i}].journeys`).to.be.an(\"array\").and.not.empty;",
                  "        offer.journeys.forEach((j, ji) => {",
                  "            pm.expect(j.slices, `offer[${i}].journeys[${ji}].slices`).to.be.an(\"array\").and.not.empty;",
                  "            j.slices.forEach((s, si) => {",
                  "                pm.expect(s.token, `offer[${i}].journeys[${ji}].slices[${si}].token`).to.be.a(\"string\").and.not.empty;",
                  "            });",
                  "        });",
                  "    });",
                  "});",
                  "",
                  "pm.test(\"saves first slice token for Price Offer\", () => {",
                  "    const body = pm.response.json();",
                  "    const token = body.offers[0].journeys[0].slices[0].token;",
                  "    pm.expect(token).to.be.a(\"string\").and.not.empty;",
                  "    pm.environment.set(\"selected_tokens\", token);",
                  "});",
                  "",
                  "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{access_token}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=AZUL&route=SAO,RIO,{{date_1}}",
              "host": [
                "{{url}}"
              ],
              "path": [
                "offers"
              ],
              "query": [
                {
                  "key": "adts",
                  "value": "1"
                },
                {
                  "key": "chds",
                  "value": "0"
                },
                {
                  "key": "infs",
                  "value": "0"
                },
                {
                  "key": "provider_type",
                  "value": "AZUL"
                },
                {
                  "key": "route",
                  "value": "SAO,RIO,{{date_1}}"
                }
              ]
            }
          },
          "response": []
        },
        {
          "name": "Price Offer",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                  "",
                  "pm.test(\"returns offer object\", () => {",
                  "    const body = pm.response.json();",
                  "    pm.expect(body.offer, \"offer\").to.be.an(\"object\");",
                  "    pm.expect(body.offer.journeys, \"offer.journeys\").to.be.an(\"array\").and.not.empty;",
                  "});",
                  "",
                  "pm.test(\"offer has price\", () => {",
                  "    const offer = pm.response.json().offer;",
                  "    pm.expect(offer.price, \"offer.price\").to.be.an(\"object\");",
                  "    pm.expect(offer.price.total, \"offer.price.total\").to.be.a(\"number\").and.above(0);",
                  "});",
                  "",
                  "pm.test(\"saves priced token for Create Booking\", () => {",
                  "    const body = pm.response.json();",
                  "    const token = body.offer.journeys[0].slices[0].token;",
                  "    pm.expect(token).to.be.a(\"string\").and.not.empty;",
                  "    pm.environment.set(\"selected_tokens\", token);",
                  "});",
                  "",
                  "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{access_token}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{url}}/offers/price?slice_tokens={{selected_tokens}}",
              "host": [
                "{{url}}"
              ],
              "path": [
                "offers",
                "price"
              ],
              "query": [
                {
                  "key": "slice_tokens",
                  "value": "{{selected_tokens}}"
                }
              ]
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "Booking",
      "item": [
        {
          "name": "Create Booking",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                  "",
                  "pm.test(\"returns booking object with id\", () => {",
                  "    const body = pm.response.json();",
                  "    pm.expect(body.booking, \"booking\").to.be.an(\"object\");",
                  "    pm.expect(body.booking.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                  "    pm.environment.set(\"booking_id\", body.booking.id);",
                  "});",
                  "",
                  "pm.test(\"booking has provider locator\", () => {",
                  "    const booking = pm.response.json().booking;",
                  "    pm.expect(booking.provider, \"booking.provider\").to.be.an(\"object\");",
                  "    pm.expect(booking.provider.locator, \"booking.provider.locator\").to.be.a(\"string\").and.not.empty;",
                  "    pm.environment.set(\"loc\", booking.provider.locator);",
                  "});",
                  "",
                  "pm.test(\"booking has passengers\", () => {",
                  "    const booking = pm.response.json().booking;",
                  "    pm.expect(booking.passengers, \"booking.passengers\").to.be.an(\"array\").and.not.empty;",
                  "});",
                  "",
                  "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{access_token}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"selected_tokens\": [\n    \"{{selected_tokens}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"2000-08-24\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"frequent_flyers\": [\n        {\n          \"airline\": \"G3\",\n          \"code\": \"116444\"\n        }\n      ],\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{url}}/bookings",
              "host": [
                "{{url}}"
              ],
              "path": [
                "bookings"
              ]
            }
          },
          "response": []
        },
        {
          "name": "Get Booking",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                  "",
                  "pm.test(\"returns booking object with matching id\", () => {",
                  "    const body = pm.response.json();",
                  "    pm.expect(body.booking, \"booking\").to.be.an(\"object\");",
                  "    pm.expect(body.booking.id, \"booking.id\").to.equal(pm.environment.get(\"booking_id\"));",
                  "});",
                  "",
                  "pm.test(\"booking has slices\", () => {",
                  "    const booking = pm.response.json().booking;",
                  "    pm.expect(booking.slices, \"booking.slices\").to.be.an(\"array\").and.not.empty;",
                  "});",
                  "",
                  "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{access_token}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{url}}/bookings/{{booking_id}}",
              "host": [
                "{{url}}"
              ],
              "path": [
                "bookings",
                "{{booking_id}}"
              ]
            }
          },
          "response": []
        },
        {
          "name": "Cancel Booking Tickets",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                  "",
                  "pm.test(\"response body is empty\", () => {",
                  "    pm.expect(pm.response.text()).to.be.empty;",
                  "});",
                  "",
                  "pm.test(\"response time < 30000ms\", () => pm.expect(pm.response.responseTime).to.be.below(30000));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{access_token}}",
                  "type": "string"
                }
              ]
            },
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{url}}/bookings/{{booking_id}}/tickets",
              "host": [
                "{{url}}"
              ],
              "path": [
                "bookings",
                "{{booking_id}}",
                "tickets"
              ]
            }
          },
          "response": []
        },
        {
          "name": "Cancel Booking",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                  "",
                  "pm.test(\"response body is empty\", () => {",
                  "    pm.expect(pm.response.text()).to.be.empty;",
                  "});",
                  "",
                  "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{access_token}}",
                  "type": "string"
                }
              ]
            },
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{url}}/bookings/{{booking_id}}",
              "host": [
                "{{url}}"
              ],
              "path": [
                "bookings",
                "{{booking_id}}"
              ]
            }
          },
          "response": []
        },
        {
          "name": "Import Booking",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{url}}/bookings/import",
              "host": [
                "{{url}}"
              ],
              "path": [
                "bookings",
                "import"
              ]
            },
            "description": "Imports an existing booking from a provider using the PNR (locator). Set `save: true` to persist it in the database.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"locator\": \"BKJJ25\",\n  \"provider_type\": \"LATAM\",\n  \"save\": true,\n  \"provider_id\": \"\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Update Booking",
          "request": {
            "method": "PATCH",
            "header": [],
            "url": {
              "raw": "{{url}}/bookings/{{booking_id}}",
              "host": [
                "{{url}}"
              ],
              "path": [
                "bookings",
                "{{booking_id}}"
              ],
              "variable": [
                {
                  "key": "booking_id",
                  "value": "{{booking_id}}"
                }
              ]
            },
            "description": "Updates passenger information in an existing booking.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"booking_passengers_info\": [\n    {\n      \"passenger_id\": \"{{passenger_id}}\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"middle_name\": \"\",\n      \"birth_date\": \"1990-01-15\",\n      \"gender_type\": \"GENDER_TYPE_MALE\",\n      \"redress\": \"\",\n      \"nationality\": \"BR\",\n      \"email\": \"john.doe@example.com\",\n      \"phone\": \"+5511999999999\",\n      \"documents\": []\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Split Booking",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{url}}/bookings/{{booking_id}}/split",
              "host": [
                "{{url}}"
              ],
              "path": [
                "bookings",
                "{{booking_id}}",
                "split"
              ],
              "variable": [
                {
                  "key": "booking_id",
                  "value": "{{booking_id}}"
                }
              ]
            },
            "description": "Moves one or more passengers into a new child booking.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"passenger_ids\": [\n    \"{{passenger_id}}\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Price Booking",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{url}}/bookings/{{booking_id}}/price",
              "host": [
                "{{url}}"
              ],
              "path": [
                "bookings",
                "{{booking_id}}",
                "price"
              ],
              "variable": [
                {
                  "key": "booking_id",
                  "value": "{{booking_id}}"
                }
              ]
            },
            "description": "Triggers a repricing of the booking against the provider. Set `informative: true` to preview without saving.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"lowest_price\": false,\n  \"informative\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Update Booking Frequent Flyers",
          "request": {
            "method": "PATCH",
            "header": [],
            "url": {
              "raw": "{{url}}/bookings/{{booking_id}}/frequent-flyers",
              "host": [
                "{{url}}"
              ],
              "path": [
                "bookings",
                "{{booking_id}}",
                "frequent-flyers"
              ],
              "variable": [
                {
                  "key": "booking_id",
                  "value": "{{booking_id}}"
                }
              ]
            },
            "description": "Updates frequent flyer information for passengers in the booking.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"passengers\": [\n    {\n      \"passenger_id\": \"{{passenger_id}}\",\n      \"airline\": \"G3\",\n      \"code\": \"123456789\"\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "Ticket",
      "item": [
        {
          "name": "Get Tickets",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{url}}/tickets?start_date={{date_tickets_start}}&end_date={{date_tickets_end}}&page=1&per_page=50&timezone=America%2FSao_Paulo",
              "host": [
                "{{url}}"
              ],
              "path": [
                "tickets"
              ],
              "query": [
                {
                  "key": "start_date",
                  "value": "{{date_tickets_start}}"
                },
                {
                  "key": "end_date",
                  "value": "{{date_tickets_end}}"
                },
                {
                  "key": "page",
                  "value": "1"
                },
                {
                  "key": "per_page",
                  "value": "50"
                },
                {
                  "key": "timezone",
                  "value": "America%2FSao_Paulo"
                }
              ]
            },
            "description": "Lists tickets issued within a date range. Maximum range is 7 days."
          },
          "response": [],
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const addDays = (n) => {",
                  "    const d = new Date();",
                  "    d.setDate(d.getDate() + n);",
                  "    return d.toISOString().split('T')[0];",
                  "};",
                  "pm.environment.set('date_tickets_start', addDays(-30));",
                  "pm.environment.set('date_tickets_end',   addDays(0));"
                ]
              }
            }
          ]
        },
        {
          "name": "Create Ticket (Invoice)",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{url}}/tickets",
              "host": [
                "{{url}}"
              ],
              "path": [
                "tickets"
              ]
            },
            "description": "Issues tickets for a booking using invoice as form of payment.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"FOP_TYPE_INVOICE\"\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Get Ticket",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                  "",
                  "pm.test(\"returns ticket with matching number\", () => {",
                  "    const body = pm.response.json();",
                  "    pm.expect(body.number, \"number\").to.equal(pm.environment.get(\"number\") || pm.variables.get(\"number\"));",
                  "});",
                  "",
                  "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{access_token}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{url}}/tickets/{{number}}",
              "host": [
                "{{url}}"
              ],
              "path": [
                "tickets",
                "{{number}}"
              ]
            }
          },
          "response": []
        },
        {
          "name": "Delete Ticket",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                  "",
                  "pm.test(\"response body is empty\", () => {",
                  "    pm.expect(pm.response.text()).to.be.empty;",
                  "});",
                  "",
                  "pm.test(\"response time < 30000ms\", () => pm.expect(pm.response.responseTime).to.be.below(30000));"
                ],
                "type": "text/javascript"
              }
            }
          ],
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{access_token}}",
                  "type": "string"
                }
              ]
            },
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{url}}/tickets/{{number}}",
              "host": [
                "{{url}}"
              ],
              "path": [
                "tickets",
                "{{number}}"
              ]
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "Exchange",
      "item": [
        {
          "name": "Simulate Ticket Reissuance (Estimate)",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{url}}/exchange/estimate",
              "host": [
                "{{url}}"
              ],
              "path": [
                "exchange",
                "estimate"
              ]
            },
            "description": "Simulates ticket reissuance and returns a price estimate. Always call this before POST /exchange to preview costs.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"ticket_numbers\": [\n    \"0014995096800\",\n    \"0014995096801\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Reissue Airline Tickets",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{url}}/exchange",
              "host": [
                "{{url}}"
              ],
              "path": [
                "exchange"
              ]
            },
            "description": "Reissues airline tickets into a new booking (new PNR). Call POST /exchange/estimate first to obtain new_slice_tokens and total values.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"new_slice_tokens\": {{new_slice_tokens}},\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"TICKET\",\n      \"tickets\": {{ticket_numbers}},\n      \"total\": {{total_tickets_credit_amount}},\n      \"passenger_ids\": {{new_booking_passenger_ids}}\n    },\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{balance_price_total}},\n      \"passenger_ids\": {{new_booking_passenger_ids}}\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "Flows",
      "description": "Reference integration scenarios.\n\nTicketless providers (AZUL, LATAM): ticket cancellation via DELETE /bookings/{id}/tickets also cancels the booking — no separate DELETE /bookings/{id} call is needed.\n\nTicketfull providers (AMADEUS, FARELOGIX, SABRE, GOL, ELATAM): each ticket must be cancelled individually via DELETE /tickets/{number} (descending order, newest first — required for reissue scenarios), then the booking is cancelled via DELETE /bookings/{id}.\n\nEach scenario is self-contained: it starts with 'Auth - Access Token' so it can be run end-to-end via the Postman Collection Runner without prerequisite steps.",
      "item": [
        {
          "name": "Full Flow - Search, Booking, Ticketing and Cancel",
          "id": "dd646312-aa36-4542-9b2c-dda7834b2fb0",
          "item": [
            {
              "name": "One-way",
              "item": [
                {
                  "name": "One-way 1 ADT — Ticketless (AZUL) | Invoice",
                  "description": "Single adult, one-way, AZUL provider, invoice payment. Cancellation via DELETE /bookings/{id}/tickets cancels tickets and booking together.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound)\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const token = offers[0].journeys[0].slices[0].token;",
                              "    pm.expect(token, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=AZUL&route=SAO,RIO,{{date_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "AZUL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"11999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"52998224725\",\n          \"type\": \"CPF\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Invoice)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert TICKETED)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const number = pm.environment.get('number');",
                              "if (!number) {",
                              "    throw new Error('number is missing. Ensure Create Ticket ran successfully before Get Ticket (assert TICKETED).');",
                              "}",
                              "const url = pm.request.url.toString();",
                              "pm.request.url = url.replace(/\\/tickets\\/[^?#]*$/, '/tickets/' + number);"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket_status\").to.equal(\"TICKETED\");",
                              "});",
                              "",
                              "pm.test(\"ticket has matching number\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.number, \"number\").to.equal(pm.environment.get(\"number\"));",
                              "});",
                              "",
                              "pm.test(\"ticket has passenger object\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.passenger, 'passenger').to.be.an('object');",
                              "    pm.expect(t.passenger.pax_type, 'passenger.pax_type').to.be.oneOf(['ADT', 'CHD', 'INF']);",
                              "    pm.expect(t.passenger.first_name, 'passenger.first_name').to.be.a('string').and.not.empty;",
                              "    pm.expect(t.passenger.last_name, 'passenger.last_name').to.be.a('string').and.not.empty;",
                              "});",
                              "",
                              "pm.test(\"ticket has slices with legs\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.slices, 'slices').to.be.an('array').and.not.empty;",
                              "    t.slices.forEach((s, i) => {",
                              "        pm.expect(s.origin, `slices[${i}].origin`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.destination, `slices[${i}].destination`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.legs, `slices[${i}].legs`).to.be.an('array').and.not.empty;",
                              "    });",
                              "});",
                              "",
                              "pm.test(\"ticket has price with total\", () => {",
                              "    const price = pm.response.json().price;",
                              "    pm.expect(price, 'price').to.be.an('object');",
                              "    pm.expect(Number(price.total), 'price.total').to.be.a('number').and.not.NaN;",
                              "});",
                              "",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking Tickets (cancels all tickets AND the booking for ticketless providers)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}",
                            "tickets"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "One-way 1 ADT — Ticketless (LATAM) | Invoice",
                  "description": "Single adult, one-way, LATAM provider, invoice payment. Cancellation via DELETE /bookings/{id}/tickets cancels tickets and booking together.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound)\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const token = offers[0].journeys[0].slices[0].token;",
                              "    pm.expect(token, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=LATAM&route=SAO,RIO,{{date_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "LATAM"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"11999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"52998224725\",\n          \"type\": \"CPF\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Invoice)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert TICKETED)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const number = pm.environment.get('number');",
                              "if (!number) {",
                              "    throw new Error('number is missing. Ensure Create Ticket ran successfully before Get Ticket (assert TICKETED).');",
                              "}",
                              "const url = pm.request.url.toString();",
                              "pm.request.url = url.replace(/\\/tickets\\/[^?#]*$/, '/tickets/' + number);"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket_status\").to.equal(\"TICKETED\");",
                              "});",
                              "",
                              "pm.test(\"ticket has matching number\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.number, \"number\").to.equal(pm.environment.get(\"number\"));",
                              "});",
                              "",
                              "pm.test(\"ticket has passenger object\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.passenger, 'passenger').to.be.an('object');",
                              "    pm.expect(t.passenger.pax_type, 'passenger.pax_type').to.be.oneOf(['ADT', 'CHD', 'INF']);",
                              "    pm.expect(t.passenger.first_name, 'passenger.first_name').to.be.a('string').and.not.empty;",
                              "    pm.expect(t.passenger.last_name, 'passenger.last_name').to.be.a('string').and.not.empty;",
                              "});",
                              "",
                              "pm.test(\"ticket has slices with legs\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.slices, 'slices').to.be.an('array').and.not.empty;",
                              "    t.slices.forEach((s, i) => {",
                              "        pm.expect(s.origin, `slices[${i}].origin`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.destination, `slices[${i}].destination`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.legs, `slices[${i}].legs`).to.be.an('array').and.not.empty;",
                              "    });",
                              "});",
                              "",
                              "pm.test(\"ticket has price with total\", () => {",
                              "    const price = pm.response.json().price;",
                              "    pm.expect(price, 'price').to.be.an('object');",
                              "    pm.expect(Number(price.total), 'price.total').to.be.a('number').and.not.NaN;",
                              "});",
                              "",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking Tickets (cancels all tickets AND the booking for ticketless providers)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}",
                            "tickets"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "One-way 1 ADT — Ticketfull (ELATAM) | Invoice",
                  "description": "Single adult, one-way, ELATAM provider, invoice payment. Tickets cancelled one-by-one then booking cancelled.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound)\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const token = offers[0].journeys[0].slices[0].token;",
                              "    pm.expect(token, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=ELATAM&route=SAO,RIO,{{date_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "ELATAM"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Invoice)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert TICKETED)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const number = pm.environment.get('number');",
                              "if (!number) {",
                              "    throw new Error('number is missing. Ensure Create Ticket ran successfully before Get Ticket (assert TICKETED).');",
                              "}",
                              "const url = pm.request.url.toString();",
                              "pm.request.url = url.replace(/\\/tickets\\/[^?#]*$/, '/tickets/' + number);"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket_status\").to.equal(\"TICKETED\");",
                              "});",
                              "",
                              "pm.test(\"ticket has matching number\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.number, \"number\").to.equal(pm.environment.get(\"number\"));",
                              "});",
                              "",
                              "pm.test(\"ticket has passenger object\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.passenger, 'passenger').to.be.an('object');",
                              "    pm.expect(t.passenger.pax_type, 'passenger.pax_type').to.be.oneOf(['ADT', 'CHD', 'INF']);",
                              "    pm.expect(t.passenger.first_name, 'passenger.first_name').to.be.a('string').and.not.empty;",
                              "    pm.expect(t.passenger.last_name, 'passenger.last_name').to.be.a('string').and.not.empty;",
                              "});",
                              "",
                              "pm.test(\"ticket has slices with legs\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.slices, 'slices').to.be.an('array').and.not.empty;",
                              "    t.slices.forEach((s, i) => {",
                              "        pm.expect(s.origin, `slices[${i}].origin`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.destination, `slices[${i}].destination`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.legs, `slices[${i}].legs`).to.be.an('array').and.not.empty;",
                              "    });",
                              "});",
                              "",
                              "pm.test(\"ticket has price with total\", () => {",
                              "    const price = pm.response.json().price;",
                              "    pm.expect(price, 'price').to.be.an('object');",
                              "    pm.expect(Number(price.total), 'price.total').to.be.a('number').and.not.NaN;",
                              "});",
                              "",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Delete Ticket (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                              "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                              "}",
                              "// On first iteration, save full list for the Get Ticket loop",
                              "const savedRaw = pm.environment.get('get_ticket_numbers');",
                              "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                              "if (saved.length === 0) {",
                              "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "} else {",
                              "    // proceed to the next request in the folder",
                              "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                              "});",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "One-way 1 ADT — Ticketfull (GOL) | Invoice",
                  "description": "Single adult, one-way, GOL provider, invoice payment. Tickets cancelled one-by-one then booking cancelled.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound)\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const token = offers[0].journeys[0].slices[0].token;",
                              "    pm.expect(token, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Invoice)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert TICKETED)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const number = pm.environment.get('number');",
                              "if (!number) {",
                              "    throw new Error('number is missing. Ensure Create Ticket ran successfully before Get Ticket (assert TICKETED).');",
                              "}",
                              "const url = pm.request.url.toString();",
                              "pm.request.url = url.replace(/\\/tickets\\/[^?#]*$/, '/tickets/' + number);"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket_status\").to.equal(\"TICKETED\");",
                              "});",
                              "",
                              "pm.test(\"ticket has matching number\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.number, \"number\").to.equal(pm.environment.get(\"number\"));",
                              "});",
                              "",
                              "pm.test(\"ticket has passenger object\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.passenger, 'passenger').to.be.an('object');",
                              "    pm.expect(t.passenger.pax_type, 'passenger.pax_type').to.be.oneOf(['ADT', 'CHD', 'INF']);",
                              "    pm.expect(t.passenger.first_name, 'passenger.first_name').to.be.a('string').and.not.empty;",
                              "    pm.expect(t.passenger.last_name, 'passenger.last_name').to.be.a('string').and.not.empty;",
                              "});",
                              "",
                              "pm.test(\"ticket has slices with legs\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.slices, 'slices').to.be.an('array').and.not.empty;",
                              "    t.slices.forEach((s, i) => {",
                              "        pm.expect(s.origin, `slices[${i}].origin`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.destination, `slices[${i}].destination`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.legs, `slices[${i}].legs`).to.be.an('array').and.not.empty;",
                              "    });",
                              "});",
                              "",
                              "pm.test(\"ticket has price with total\", () => {",
                              "    const price = pm.response.json().price;",
                              "    pm.expect(price, 'price').to.be.an('object');",
                              "    pm.expect(Number(price.total), 'price.total').to.be.a('number').and.not.NaN;",
                              "});",
                              "",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Delete Ticket (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                              "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                              "}",
                              "// On first iteration, save full list for the Get Ticket loop",
                              "const savedRaw = pm.environment.get('get_ticket_numbers');",
                              "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                              "if (saved.length === 0) {",
                              "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "} else {",
                              "    // proceed to the next request in the folder",
                              "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                              "});",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "One-way 1 ADT — Ticketless (AZUL) | Credit Card",
                  "description": "Single adult, one-way, AZUL provider, credit card payment. Cancellation via DELETE /bookings/{id}/tickets cancels tickets and booking together.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound)\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const token = offers[0].journeys[0].slices[0].token;",
                              "    pm.expect(token, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=AZUL&route=SAO,RIO,{{date_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "AZUL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"11999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"52998224725\",\n          \"type\": \"CPF\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});",
                              "pm.test(\"saves booking slice token for Get Installments\", () => {\n    const slices = pm.response.json().booking.slices || [];\n    pm.expect(slices.length, \"at least one slice\").to.be.above(0);\n    pm.expect(slices[0].token, \"slices[0].token\").to.be.a(\"string\").and.not.empty;\n    pm.environment.set(\"booking_token\", slices[0].token);\n});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Installments",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves plan_token for 3 installments\", () => {",
                              "    const body = pm.response.json();",
                              "    const plans = body.installment_plans || [];",
                              "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                              "    const plan3 = plans.find(p => p.installment === 3);",
                              "    const planToken = plan3 ? plan3.plan_token : plans[0].plan_token;",
                              "    pm.expect(planToken, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"plan_token\", planToken);",
                              "});"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/installments?creditcard_bin=555544&selected_tokens={{booking_token}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "installments"
                          ],
                          "query": [
                            {
                              "key": "creditcard_bin",
                              "value": "555544"
                            },
                            {
                              "key": "selected_tokens",
                              "value": "{{booking_token}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Credit Card)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555444433331111\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{plan_token}}\"\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert TICKETED)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const number = pm.environment.get('number');",
                              "if (!number) {",
                              "    throw new Error('number is missing. Ensure Create Ticket ran successfully before Get Ticket (assert TICKETED).');",
                              "}",
                              "const url = pm.request.url.toString();",
                              "pm.request.url = url.replace(/\\/tickets\\/[^?#]*$/, '/tickets/' + number);"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket_status\").to.equal(\"TICKETED\");",
                              "});",
                              "",
                              "pm.test(\"ticket has matching number\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.number, \"number\").to.equal(pm.environment.get(\"number\"));",
                              "});",
                              "",
                              "pm.test(\"ticket has passenger object\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.passenger, 'passenger').to.be.an('object');",
                              "    pm.expect(t.passenger.pax_type, 'passenger.pax_type').to.be.oneOf(['ADT', 'CHD', 'INF']);",
                              "    pm.expect(t.passenger.first_name, 'passenger.first_name').to.be.a('string').and.not.empty;",
                              "    pm.expect(t.passenger.last_name, 'passenger.last_name').to.be.a('string').and.not.empty;",
                              "});",
                              "",
                              "pm.test(\"ticket has slices with legs\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.slices, 'slices').to.be.an('array').and.not.empty;",
                              "    t.slices.forEach((s, i) => {",
                              "        pm.expect(s.origin, `slices[${i}].origin`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.destination, `slices[${i}].destination`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.legs, `slices[${i}].legs`).to.be.an('array').and.not.empty;",
                              "    });",
                              "});",
                              "",
                              "pm.test(\"ticket has price with total\", () => {",
                              "    const price = pm.response.json().price;",
                              "    pm.expect(price, 'price').to.be.an('object');",
                              "    pm.expect(Number(price.total), 'price.total').to.be.a('number').and.not.NaN;",
                              "});",
                              "",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking Tickets (cancels all tickets AND the booking for ticketless providers)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}",
                            "tickets"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "One-way 1 ADT — Ticketless (LATAM) | Credit Card",
                  "description": "Single adult, one-way, LATAM provider, credit card payment. Cancellation via DELETE /bookings/{id}/tickets cancels tickets and booking together.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound)\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const token = offers[0].journeys[0].slices[0].token;",
                              "    pm.expect(token, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=LATAM&route=SAO,RIO,{{date_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "LATAM"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"11999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"52998224725\",\n          \"type\": \"CPF\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});",
                              "pm.test(\"saves booking slice token for Get Installments\", () => {\n    const slices = pm.response.json().booking.slices || [];\n    pm.expect(slices.length, \"at least one slice\").to.be.above(0);\n    pm.expect(slices[0].token, \"slices[0].token\").to.be.a(\"string\").and.not.empty;\n    pm.environment.set(\"booking_token\", slices[0].token);\n});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Installments",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves plan_token for 3 installments\", () => {",
                              "    const body = pm.response.json();",
                              "    const plans = body.installment_plans || [];",
                              "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                              "    const plan3 = plans.find(p => p.installment === 3);",
                              "    const planToken = plan3 ? plan3.plan_token : plans[0].plan_token;",
                              "    pm.expect(planToken, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"plan_token\", planToken);",
                              "});"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/installments?creditcard_bin=400000&selected_tokens={{booking_token}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "installments"
                          ],
                          "query": [
                            {
                              "key": "creditcard_bin",
                              "value": "400000"
                            },
                            {
                              "key": "selected_tokens",
                              "value": "{{booking_token}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Credit Card)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"4000000000001091\",\n        \"card_brand\": \"VISA\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{plan_token}}\"\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert TICKETED)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const number = pm.environment.get('number');",
                              "if (!number) {",
                              "    throw new Error('number is missing. Ensure Create Ticket ran successfully before Get Ticket (assert TICKETED).');",
                              "}",
                              "const url = pm.request.url.toString();",
                              "pm.request.url = url.replace(/\\/tickets\\/[^?#]*$/, '/tickets/' + number);"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket_status\").to.equal(\"TICKETED\");",
                              "});",
                              "",
                              "pm.test(\"ticket has matching number\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.number, \"number\").to.equal(pm.environment.get(\"number\"));",
                              "});",
                              "",
                              "pm.test(\"ticket has passenger object\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.passenger, 'passenger').to.be.an('object');",
                              "    pm.expect(t.passenger.pax_type, 'passenger.pax_type').to.be.oneOf(['ADT', 'CHD', 'INF']);",
                              "    pm.expect(t.passenger.first_name, 'passenger.first_name').to.be.a('string').and.not.empty;",
                              "    pm.expect(t.passenger.last_name, 'passenger.last_name').to.be.a('string').and.not.empty;",
                              "});",
                              "",
                              "pm.test(\"ticket has slices with legs\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.slices, 'slices').to.be.an('array').and.not.empty;",
                              "    t.slices.forEach((s, i) => {",
                              "        pm.expect(s.origin, `slices[${i}].origin`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.destination, `slices[${i}].destination`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.legs, `slices[${i}].legs`).to.be.an('array').and.not.empty;",
                              "    });",
                              "});",
                              "",
                              "pm.test(\"ticket has price with total\", () => {",
                              "    const price = pm.response.json().price;",
                              "    pm.expect(price, 'price').to.be.an('object');",
                              "    pm.expect(Number(price.total), 'price.total').to.be.a('number').and.not.NaN;",
                              "});",
                              "",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking Tickets (cancels all tickets AND the booking for ticketless providers)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}",
                            "tickets"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "One-way 1 ADT — Ticketfull (ELATAM) | Credit Card",
                  "description": "Single adult, one-way, ELATAM provider, credit card payment. Tickets cancelled one-by-one then booking cancelled.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound)\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const token = offers[0].journeys[0].slices[0].token;",
                              "    pm.expect(token, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=ELATAM&route=SAO,RIO,{{date_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "ELATAM"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});",
                              "pm.test(\"saves booking slice token for Get Installments\", () => {\n    const slices = pm.response.json().booking.slices || [];\n    pm.expect(slices.length, \"at least one slice\").to.be.above(0);\n    pm.expect(slices[0].token, \"slices[0].token\").to.be.a(\"string\").and.not.empty;\n    pm.environment.set(\"booking_token\", slices[0].token);\n});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Installments",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves plan_token for 3 installments\", () => {",
                              "    const body = pm.response.json();",
                              "    const plans = body.installment_plans || [];",
                              "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                              "    const plan3 = plans.find(p => p.installment === 3);",
                              "    const planToken = plan3 ? plan3.plan_token : plans[0].plan_token;",
                              "    pm.expect(planToken, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"plan_token\", planToken);",
                              "});"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/installments?creditcard_bin=400000&selected_tokens={{booking_token}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "installments"
                          ],
                          "query": [
                            {
                              "key": "creditcard_bin",
                              "value": "400000"
                            },
                            {
                              "key": "selected_tokens",
                              "value": "{{booking_token}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Credit Card)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"4000000000001091\",\n        \"card_brand\": \"VISA\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{plan_token}}\"\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert TICKETED)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const number = pm.environment.get('number');",
                              "if (!number) {",
                              "    throw new Error('number is missing. Ensure Create Ticket ran successfully before Get Ticket (assert TICKETED).');",
                              "}",
                              "const url = pm.request.url.toString();",
                              "pm.request.url = url.replace(/\\/tickets\\/[^?#]*$/, '/tickets/' + number);"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket_status\").to.equal(\"TICKETED\");",
                              "});",
                              "",
                              "pm.test(\"ticket has matching number\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.number, \"number\").to.equal(pm.environment.get(\"number\"));",
                              "});",
                              "",
                              "pm.test(\"ticket has passenger object\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.passenger, 'passenger').to.be.an('object');",
                              "    pm.expect(t.passenger.pax_type, 'passenger.pax_type').to.be.oneOf(['ADT', 'CHD', 'INF']);",
                              "    pm.expect(t.passenger.first_name, 'passenger.first_name').to.be.a('string').and.not.empty;",
                              "    pm.expect(t.passenger.last_name, 'passenger.last_name').to.be.a('string').and.not.empty;",
                              "});",
                              "",
                              "pm.test(\"ticket has slices with legs\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.slices, 'slices').to.be.an('array').and.not.empty;",
                              "    t.slices.forEach((s, i) => {",
                              "        pm.expect(s.origin, `slices[${i}].origin`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.destination, `slices[${i}].destination`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.legs, `slices[${i}].legs`).to.be.an('array').and.not.empty;",
                              "    });",
                              "});",
                              "",
                              "pm.test(\"ticket has price with total\", () => {",
                              "    const price = pm.response.json().price;",
                              "    pm.expect(price, 'price').to.be.an('object');",
                              "    pm.expect(Number(price.total), 'price.total').to.be.a('number').and.not.NaN;",
                              "});",
                              "",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Delete Ticket (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                              "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                              "}",
                              "// On first iteration, save full list for the Get Ticket loop",
                              "const savedRaw = pm.environment.get('get_ticket_numbers');",
                              "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                              "if (saved.length === 0) {",
                              "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "} else {",
                              "    // proceed to the next request in the folder",
                              "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                              "});",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "One-way 1 ADT — Ticketfull (GOL) | Credit Card",
                  "description": "Single adult, one-way, GOL provider, credit card payment. Tickets cancelled one-by-one then booking cancelled.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound)\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const token = offers[0].journeys[0].slices[0].token;",
                              "    pm.expect(token, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});",
                              "pm.test(\"saves booking slice token for Get Installments\", () => {\n    const slices = pm.response.json().booking.slices || [];\n    pm.expect(slices.length, \"at least one slice\").to.be.above(0);\n    pm.expect(slices[0].token, \"slices[0].token\").to.be.a(\"string\").and.not.empty;\n    pm.environment.set(\"booking_token\", slices[0].token);\n});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Installments",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves plan_token for 3 installments\", () => {",
                              "    const body = pm.response.json();",
                              "    const plans = body.installment_plans || [];",
                              "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                              "    const plan3 = plans.find(p => p.installment === 3);",
                              "    const planToken = plan3 ? plan3.plan_token : plans[0].plan_token;",
                              "    pm.expect(planToken, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"plan_token\", planToken);",
                              "});"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/installments?creditcard_bin=555555&selected_tokens={{booking_token}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "installments"
                          ],
                          "query": [
                            {
                              "key": "creditcard_bin",
                              "value": "555555"
                            },
                            {
                              "key": "selected_tokens",
                              "value": "{{booking_token}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Credit Card)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{plan_token}}\"\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert TICKETED)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const number = pm.environment.get('number');",
                              "if (!number) {",
                              "    throw new Error('number is missing. Ensure Create Ticket ran successfully before Get Ticket (assert TICKETED).');",
                              "}",
                              "const url = pm.request.url.toString();",
                              "pm.request.url = url.replace(/\\/tickets\\/[^?#]*$/, '/tickets/' + number);"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket_status\").to.equal(\"TICKETED\");",
                              "});",
                              "",
                              "pm.test(\"ticket has matching number\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.number, \"number\").to.equal(pm.environment.get(\"number\"));",
                              "});",
                              "",
                              "pm.test(\"ticket has passenger object\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.passenger, 'passenger').to.be.an('object');",
                              "    pm.expect(t.passenger.pax_type, 'passenger.pax_type').to.be.oneOf(['ADT', 'CHD', 'INF']);",
                              "    pm.expect(t.passenger.first_name, 'passenger.first_name').to.be.a('string').and.not.empty;",
                              "    pm.expect(t.passenger.last_name, 'passenger.last_name').to.be.a('string').and.not.empty;",
                              "});",
                              "",
                              "pm.test(\"ticket has slices with legs\", () => {",
                              "    const t = pm.response.json();",
                              "    pm.expect(t.slices, 'slices').to.be.an('array').and.not.empty;",
                              "    t.slices.forEach((s, i) => {",
                              "        pm.expect(s.origin, `slices[${i}].origin`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.destination, `slices[${i}].destination`).to.be.a('string').and.not.empty;",
                              "        pm.expect(s.legs, `slices[${i}].legs`).to.be.an('array').and.not.empty;",
                              "    });",
                              "});",
                              "",
                              "pm.test(\"ticket has price with total\", () => {",
                              "    const price = pm.response.json().price;",
                              "    pm.expect(price, 'price').to.be.an('object');",
                              "    pm.expect(Number(price.total), 'price.total').to.be.a('number').and.not.NaN;",
                              "});",
                              "",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Delete Ticket (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                              "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                              "}",
                              "// On first iteration, save full list for the Get Ticket loop",
                              "const savedRaw = pm.environment.get('get_ticket_numbers');",
                              "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                              "if (saved.length === 0) {",
                              "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "} else {",
                              "    // proceed to the next request in the folder",
                              "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                              "});",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                }
              ],
              "id": "cb777801-d5f7-4722-8e2c-4153b724a441"
            },
            {
              "name": "Round-trip",
              "item": [
                {
                  "name": "Round-trip 2 ADT + 1 CHD + 1 INF — Ticketless (AZUL) | Invoice",
                  "description": "Family round-trip, AZUL provider, invoice payment.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                              "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                              "    // The first slice of each journey carries the token we need.",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const journeys = offers[0].journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    const outbound = journeys[0].slices[0].token;",
                              "    const inbound = journeys[1].slices[0].token;",
                              "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.expect(inbound, \"inbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", outbound);",
                              "    pm.environment.set(\"slice_token_2\", inbound);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=2&chds=1&infs=1&provider_type=AZUL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "2"
                            },
                            {
                              "key": "chds",
                              "value": "1"
                            },
                            {
                              "key": "infs",
                              "value": "1"
                            },
                            {
                              "key": "provider_type",
                              "value": "AZUL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"11999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"52998224725\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"11999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"11144477735\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"CHD\",\n      \"first_name\": \"Alice\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"2018-07-10\",\n      \"phone_number\": \"11999559997\",\n      \"email\": \"alice@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"39053344705\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"INF\",\n      \"first_name\": \"Sam\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"2024-11-01\",\n      \"phone_number\": \"11999559996\",\n      \"email\": \"sam@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"24843803480\",\n          \"type\": \"CPF\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Invoice)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking Tickets (cancels all tickets AND the booking for ticketless providers)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}",
                            "tickets"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "Round-trip 2 ADT + 1 CHD + 1 INF — Ticketless (AZUL) | Credit Card",
                  "description": "Family round-trip, AZUL provider, credit card payment.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                              "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                              "    // The first slice of each journey carries the token we need.",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const journeys = offers[0].journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    const outbound = journeys[0].slices[0].token;",
                              "    const inbound = journeys[1].slices[0].token;",
                              "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.expect(inbound, \"inbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", outbound);",
                              "    pm.environment.set(\"slice_token_2\", inbound);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=2&chds=1&infs=1&provider_type=AZUL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "2"
                            },
                            {
                              "key": "chds",
                              "value": "1"
                            },
                            {
                              "key": "infs",
                              "value": "1"
                            },
                            {
                              "key": "provider_type",
                              "value": "AZUL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"11999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"52998224725\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"11999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"11144477735\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"CHD\",\n      \"first_name\": \"Alice\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"2018-07-10\",\n      \"phone_number\": \"11999559997\",\n      \"email\": \"alice@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"39053344705\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"INF\",\n      \"first_name\": \"Sam\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"2024-11-01\",\n      \"phone_number\": \"11999559996\",\n      \"email\": \"sam@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"24843803480\",\n          \"type\": \"CPF\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Credit Card)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555444433331111\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      }\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking Tickets (cancels all tickets AND the booking for ticketless providers)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}",
                            "tickets"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "Round-trip 2 ADT + 1 CHD + 1 INF — Ticketless (LATAM) | Invoice",
                  "description": "Family round-trip, LATAM provider, invoice payment.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                              "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                              "    // The first slice of each journey carries the token we need.",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const journeys = offers[0].journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    const outbound = journeys[0].slices[0].token;",
                              "    const inbound = journeys[1].slices[0].token;",
                              "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.expect(inbound, \"inbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", outbound);",
                              "    pm.environment.set(\"slice_token_2\", inbound);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=2&chds=1&infs=1&provider_type=LATAM&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "2"
                            },
                            {
                              "key": "chds",
                              "value": "1"
                            },
                            {
                              "key": "infs",
                              "value": "1"
                            },
                            {
                              "key": "provider_type",
                              "value": "LATAM"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"11999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"52998224725\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"11999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"11144477735\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"CHD\",\n      \"first_name\": \"Alice\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"2018-07-10\",\n      \"phone_number\": \"11999559997\",\n      \"email\": \"alice@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"39053344705\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"INF\",\n      \"first_name\": \"Sam\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"2024-11-01\",\n      \"phone_number\": \"11999559996\",\n      \"email\": \"sam@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"24843803480\",\n          \"type\": \"CPF\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Invoice)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking Tickets (cancels all tickets AND the booking for ticketless providers)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}",
                            "tickets"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "Round-trip 2 ADT + 1 CHD + 1 INF — Ticketless (LATAM) | Credit Card",
                  "description": "Family round-trip, LATAM provider, credit card payment.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                              "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                              "    // The first slice of each journey carries the token we need.",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const journeys = offers[0].journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    const outbound = journeys[0].slices[0].token;",
                              "    const inbound = journeys[1].slices[0].token;",
                              "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.expect(inbound, \"inbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", outbound);",
                              "    pm.environment.set(\"slice_token_2\", inbound);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=2&chds=1&infs=1&provider_type=LATAM&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "2"
                            },
                            {
                              "key": "chds",
                              "value": "1"
                            },
                            {
                              "key": "infs",
                              "value": "1"
                            },
                            {
                              "key": "provider_type",
                              "value": "LATAM"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"11999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"52998224725\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"11999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"11144477735\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"CHD\",\n      \"first_name\": \"Alice\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"2018-07-10\",\n      \"phone_number\": \"11999559997\",\n      \"email\": \"alice@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"39053344705\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"INF\",\n      \"first_name\": \"Sam\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"2024-11-01\",\n      \"phone_number\": \"11999559996\",\n      \"email\": \"sam@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"24843803480\",\n          \"type\": \"CPF\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Credit Card)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"4000000000001091\",\n        \"card_brand\": \"VISA\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      }\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking Tickets (cancels all tickets AND the booking for ticketless providers)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}",
                            "tickets"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "Round-trip 2 ADT + 1 CHD + 1 INF — Ticketfull (ELATAM) | Invoice",
                  "description": "Family round-trip, ELATAM provider, invoice payment.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                              "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                              "    // The first slice of each journey carries the token we need.",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const journeys = offers[0].journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    const outbound = journeys[0].slices[0].token;",
                              "    const inbound = journeys[1].slices[0].token;",
                              "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.expect(inbound, \"inbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", outbound);",
                              "    pm.environment.set(\"slice_token_2\", inbound);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=2&chds=1&infs=1&provider_type=ELATAM&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "2"
                            },
                            {
                              "key": "chds",
                              "value": "1"
                            },
                            {
                              "key": "infs",
                              "value": "1"
                            },
                            {
                              "key": "provider_type",
                              "value": "ELATAM"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"55 11 999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515200\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"CHD\",\n      \"first_name\": \"Alice\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"2018-07-10\",\n      \"phone_number\": \"55 11 999559997\",\n      \"email\": \"alice@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515201\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"INF\",\n      \"first_name\": \"Sam\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"2024-11-01\",\n      \"phone_number\": \"55 11 999559996\",\n      \"email\": \"sam@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515202\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2024-11-01\",\n          \"expires_at\": \"2033-11-01\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Invoice)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Delete Ticket (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                              "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                              "}",
                              "// On first iteration, save full list for the Get Ticket loop",
                              "const savedRaw = pm.environment.get('get_ticket_numbers');",
                              "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                              "if (saved.length === 0) {",
                              "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "} else {",
                              "    // proceed to the next request in the folder",
                              "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                              "});",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "Round-trip 2 ADT + 1 CHD + 1 INF — Ticketfull (ELATAM) | Credit Card",
                  "description": "Family round-trip, ELATAM provider, credit card payment.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                              "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                              "    // The first slice of each journey carries the token we need.",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const journeys = offers[0].journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    const outbound = journeys[0].slices[0].token;",
                              "    const inbound = journeys[1].slices[0].token;",
                              "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.expect(inbound, \"inbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", outbound);",
                              "    pm.environment.set(\"slice_token_2\", inbound);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=2&chds=1&infs=1&provider_type=ELATAM&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "2"
                            },
                            {
                              "key": "chds",
                              "value": "1"
                            },
                            {
                              "key": "infs",
                              "value": "1"
                            },
                            {
                              "key": "provider_type",
                              "value": "ELATAM"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"55 11 999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515200\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"CHD\",\n      \"first_name\": \"Alice\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"2018-07-10\",\n      \"phone_number\": \"55 11 999559997\",\n      \"email\": \"alice@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515201\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"INF\",\n      \"first_name\": \"Sam\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"2024-11-01\",\n      \"phone_number\": \"55 11 999559996\",\n      \"email\": \"sam@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515202\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2024-11-01\",\n          \"expires_at\": \"2033-11-01\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Credit Card)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"4000000000001091\",\n        \"card_brand\": \"VISA\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      }\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Delete Ticket (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                              "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                              "}",
                              "// On first iteration, save full list for the Get Ticket loop",
                              "const savedRaw = pm.environment.get('get_ticket_numbers');",
                              "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                              "if (saved.length === 0) {",
                              "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "} else {",
                              "    // proceed to the next request in the folder",
                              "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                              "});",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "Round-trip 2 ADT + 1 CHD + 1 INF — Ticketfull (GOL) | Invoice",
                  "description": "Family round-trip, GOL provider, invoice payment.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                              "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                              "    // The first slice of each journey carries the token we need.",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const journeys = offers[0].journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    const outbound = journeys[0].slices[0].token;",
                              "    const inbound = journeys[1].slices[0].token;",
                              "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.expect(inbound, \"inbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", outbound);",
                              "    pm.environment.set(\"slice_token_2\", inbound);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=2&chds=1&infs=1&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "2"
                            },
                            {
                              "key": "chds",
                              "value": "1"
                            },
                            {
                              "key": "infs",
                              "value": "1"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"55 11 999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515200\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"CHD\",\n      \"first_name\": \"Alice\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"2018-07-10\",\n      \"phone_number\": \"55 11 999559997\",\n      \"email\": \"alice@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515201\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"INF\",\n      \"first_name\": \"Sam\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"2024-11-01\",\n      \"phone_number\": \"55 11 999559996\",\n      \"email\": \"sam@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515202\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2024-11-01\",\n          \"expires_at\": \"2033-11-01\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Invoice)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Delete Ticket (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                              "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                              "}",
                              "// On first iteration, save full list for the Get Ticket loop",
                              "const savedRaw = pm.environment.get('get_ticket_numbers');",
                              "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                              "if (saved.length === 0) {",
                              "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "} else {",
                              "    // proceed to the next request in the folder",
                              "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                              "});",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "Round-trip 2 ADT + 1 CHD + 1 INF — Ticketfull (GOL) | Credit Card",
                  "description": "Family round-trip, GOL provider, credit card payment.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token and refresh_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                              "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                              "    // The first slice of each journey carries the token we need.",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const journeys = offers[0].journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    const outbound = journeys[0].slices[0].token;",
                              "    const inbound = journeys[1].slices[0].token;",
                              "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.expect(inbound, \"inbound token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"slice_token_1\", outbound);",
                              "    pm.environment.set(\"slice_token_2\", inbound);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers?adts=2&chds=1&infs=1&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "2"
                            },
                            {
                              "key": "chds",
                              "value": "1"
                            },
                            {
                              "key": "infs",
                              "value": "1"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens for Create Booking\", () => {",
                              "    // Price response mirrors the offer structure: one journey per slice direction.",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"55 11 999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515200\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"CHD\",\n      \"first_name\": \"Alice\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"2018-07-10\",\n      \"phone_number\": \"55 11 999559997\",\n      \"email\": \"alice@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515201\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"INF\",\n      \"first_name\": \"Sam\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"2024-11-01\",\n      \"phone_number\": \"55 11 999559996\",\n      \"email\": \"sam@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515202\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2024-11-01\",\n          \"expires_at\": \"2033-11-01\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                              "pm.test(\"saves booking_total from booking.price.total\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    const total = b && b.price && b.price.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const ids = passengers.map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves ticket numbers for Delete Ticket steps\", () => {",
                              "    const passengers = pm.response.json().booking.passengers || [];",
                              "    const numbers = [];",
                              "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                              "    // sort descending: when a ticket is reissued, the newer (higher) number must be cancelled first",
                              "    numbers.sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket (Credit Card)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets array with numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // sort descending for the per-ticket cancel flow",
                              "    const numbers = tickets.map(t => t.number).sort().reverse();",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      }\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is TICKETED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Delete Ticket (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                              "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                              "}",
                              "// On first iteration, save full list for the Get Ticket loop",
                              "const savedRaw = pm.environment.get('get_ticket_numbers');",
                              "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                              "if (saved.length === 0) {",
                              "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "} else {",
                              "    // proceed to the next request in the folder",
                              "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) {",
                              "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                              "});",
                              "// Loop: if there are still tickets left, repeat this request.",
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking.id matches\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                              "});",
                              "pm.test(\"booking status is CANCELLED\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                }
              ],
              "id": "46b97710-8506-4301-bef1-ca6b0992ea3a"
            }
          ]
        },
        {
          "name": "Ancillaries",
          "item": [
            {
              "id": "535fda90-6010-41e0-a361-e4406ebb3030",
              "name": "Round-trip 2 ADT — Ticketfull (GOL) | Seat On-Hold | Credit Card",
              "item": [
                {
                  "id": "125c2af0-256e-490a-b746-8573f746e50d",
                  "name": "Auth - Access Token",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "const addDays = (n) => {",
                          "    const d = new Date();",
                          "    d.setDate(d.getDate() + n);",
                          "    return d.toISOString().split('T')[0];",
                          "};",
                          "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                          "pm.environment.set('date_2', addDays(19));  // inbound source",
                          "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                          "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves access_token and refresh_token\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"access_token\", body.access_token);",
                          "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/oauth/token",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "a1a0d827-ceda-46ef-bd4e-440f370eb58a",
                  "name": "Get Offers",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                          "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                          "    // The first slice of each journey carries the token we need.",
                          "    const offers = pm.response.json().offers;",
                          "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                          "    const journeys = offers[0].journeys;",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    const outbound = journeys[0].slices[0].token;",
                          "    const inbound  = journeys[1].slices[0].token;",
                          "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(inbound,  \"inbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"slice_token_1\", outbound);",
                          "    pm.environment.set(\"slice_token_2\", inbound);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers?adts=2&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers"
                      ],
                      "query": [
                        {
                          "key": "adts",
                          "value": "2"
                        },
                        {
                          "key": "chds",
                          "value": "0"
                        },
                        {
                          "key": "infs",
                          "value": "0"
                        },
                        {
                          "key": "provider_type",
                          "value": "GOL"
                        },
                        {
                          "key": "route",
                          "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                        }
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "8f55b7bb-4f09-4de4-a74e-1773950c387c",
                  "name": "Price Offer",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves priced tokens for Create Booking\", () => {",
                          "    const journeys = pm.response.json().offer.journeys || [];",
                          "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                          "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers",
                        "price?slice_tokens={{slice_token_1}},{{slice_token_2}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "f39d287e-b1d1-445c-85d3-5b35ba30b54c",
                  "name": "Create Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves booking_id and locator\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"booking_id\", b.id);",
                          "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"55 11 999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515200\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "77db474b-b522-4729-b7b7-658293820a21",
                  "name": "Get Booking (assert ON_HOLD)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is ONHOLD\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"ONHOLD\");",
                          "});",
                          "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                          "pm.test(\"saves booking_total from booking.price.total\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    const total = b && b.price && b.price.total;",
                          "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                          "    pm.environment.set(\"booking_total\", String(total));",
                          "});",
                          "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    const ids = passengers.map(p => p.id).filter(Boolean);",
                          "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                          "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                          "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                          "});",
                          "pm.test(\"saves ticket_numbers for Delete Ticket steps\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    const numbers = [];",
                          "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                          "    numbers.sort().reverse();",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                          "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                          "});",
                          "pm.test(\"saves slice and leg ids for ancillary requests\", () => {",
                          "    const slices = pm.response.json().booking.slices || [];",
                          "    pm.expect(slices.length, \"round-trip must have 2 slices\").to.be.at.least(2);",
                          "    pm.environment.set(\"slice_id_1\", slices[0].id);",
                          "    pm.environment.set(\"slice_id_2\", slices[1].id);",
                          "    pm.expect(slices[0].legs, \"outbound legs\").to.be.an(\"array\").and.not.empty;",
                          "    pm.expect(slices[1].legs, \"return legs\").to.be.an(\"array\").and.not.empty;",
                          "    pm.environment.set(\"leg_id_1\", slices[0].legs[0].id);",
                          "    pm.environment.set(\"leg_id_2\", slices[1].legs[0].id);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "3c9e4810-88f0-4e47-ab9d-f3a6aaec678c",
                  "name": "Get Seat Map",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves seat tokens: pax1 → 1st available seat, pax2 → 2nd available seat\", () => {",
                          "    const cabins = (pm.response.json().seat_map || {}).cabins || [];",
                          "    pm.expect(cabins, \"cabins\").to.be.an(\"array\").and.not.empty;",
                          "    // Collect all available seat elements (elements with at least one service).",
                          "    const available = [];",
                          "    for (const cabin of cabins)",
                          "        for (const row of cabin.rows || [])",
                          "            for (const section of row.sections || [])",
                          "                for (const elem of section.elements || [])",
                          "                    if ((elem.available_services || []).length > 0)",
                          "                        available.push(elem);",
                          "    pm.expect(available.length, \"at least 2 available seats\").to.be.at.least(2);",
                          "    // passenger_ids was saved by Get Booking (assert ON_HOLD) as a JSON array.",
                          "    const paxIds = JSON.parse(pm.environment.get(\"passenger_ids\") || \"[]\");",
                          "    // pax1 → first available seat, pax2 → second available seat.",
                          "    // Each element carries one service per passenger; match by passenger_id.",
                          "    const svc1 = available[0].available_services.find(s => s.passenger_id === paxIds[0]);",
                          "    const svc2 = available[1].available_services.find(s => s.passenger_id === paxIds[1]);",
                          "    pm.expect(svc1, \"service for pax1 on seat 1\").to.exist;",
                          "    pm.expect(svc2, \"service for pax2 on seat 2\").to.exist;",
                          "    pm.environment.set(\"seat_token_pax1_leg1\", svc1.token);",
                          "    pm.environment.set(\"seat_token_pax2_leg1\", svc2.token);",
                          "    pm.environment.set(\"seat_ancillary_total\",",
                          "        ((svc1.price && svc1.price.amount) || 0) + ((svc2.price && svc2.price.amount) || 0));",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}/legs/{{leg_id_1}}/seat-map",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}",
                        "legs",
                        "{{leg_id_1}}",
                        "seat-map"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "01c8d49f-82ef-48c3-a10d-8dfbbc6265cd",
                  "name": "Select Seat (on-hold — no payment required)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"seat selection successful\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.success, \"success\").to.be.true;",
                          "    pm.expect(body.seat_ancillaries, \"seat_ancillaries\").to.be.an(\"array\").and.not.empty;",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"legs\": [\n    {\n      \"leg_id\": \"{{leg_id_1}}\",\n      \"seat_tokens\": [\"{{seat_token_pax1_leg1}}\", \"{{seat_token_pax2_leg1}}\"]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}/seats",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}",
                        "seats"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "da74b116-4db5-413d-96ca-f701bb41e654",
                  "name": "Get Booking (assert extras > 0, update booking_total)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking.price.total_extras is greater than 0 after ancillary selection\", () => {",
                          "    const price = pm.response.json().booking.price || {};",
                          "    pm.expect(price.total_extras, \"booking.price.total_extras\").to.be.a(\"number\").and.above(0);",
                          "});",
                          "pm.test(\"updates booking_total with new total (base + extras)\", () => {",
                          "    const price = pm.response.json().booking.price || {};",
                          "    pm.expect(price.total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                          "    pm.environment.set(\"booking_total\", String(price.total));",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "4bffc04a-3265-410b-870e-0016c4bf63c3",
                  "name": "Create Ticket (Credit Card)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"returns tickets array with numbers\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                          "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                          "    pm.environment.set(\"number\", tickets[0].number);",
                          "    // sort descending for the per-ticket cancel flow",
                          "    const numbers = tickets.map(t => t.number).sort().reverse();",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      }\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "cef84d22-12fa-40f7-b253-94981bcd404b",
                  "name": "Get Ticket (assert TICKETED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is TICKETED\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"TICKETED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "63143bf3-b2aa-41b7-a18e-e4b0ef9f2ce3",
                  "name": "Get Booking (assert TICKETED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is TICKETED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"TICKETED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "6a35f97f-db9a-4a33-a288-39bba18aad96",
                  "name": "Delete Ticket (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                          "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                          "}",
                          "// On first iteration, save full list for the Get Ticket loop",
                          "const savedRaw = pm.environment.get('get_ticket_numbers');",
                          "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                          "if (saved.length === 0) {",
                          "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "} else {",
                          "    // proceed to the next request in the folder",
                          "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                          "}"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "ded2d167-808a-4db1-af65-fc366f0ace71",
                  "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                          "});",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "}"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "a42ecab4-9e2c-4c35-b28f-98ee8de789f5",
                  "name": "Cancel Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "5f11d88a-f0c2-4992-af31-ad67770a5d9e",
                  "name": "Get Booking (assert CANCELLED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is CANCELLED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                }
              ]
            },
            {
              "id": "df5b501a-8592-4f59-bac0-68c5cf5cdb22",
              "name": "Round-trip 2 ADT — Ticketfull (GOL) | Seat Ticketed | Credit Card",
              "item": [
                {
                  "id": "e6fa3155-bbd1-4a85-9110-77ec82e8bb6a",
                  "name": "Auth - Access Token",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "const addDays = (n) => {",
                          "    const d = new Date();",
                          "    d.setDate(d.getDate() + n);",
                          "    return d.toISOString().split('T')[0];",
                          "};",
                          "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                          "pm.environment.set('date_2', addDays(19));  // inbound source",
                          "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                          "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves access_token and refresh_token\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"access_token\", body.access_token);",
                          "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/oauth/token",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "53e811a0-7050-45d7-96a0-f1ff74cc1ebc",
                  "name": "Get Offers",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                          "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                          "    // The first slice of each journey carries the token we need.",
                          "    const offers = pm.response.json().offers;",
                          "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                          "    const journeys = offers[0].journeys;",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    const outbound = journeys[0].slices[0].token;",
                          "    const inbound  = journeys[1].slices[0].token;",
                          "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(inbound,  \"inbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"slice_token_1\", outbound);",
                          "    pm.environment.set(\"slice_token_2\", inbound);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers?adts=2&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers"
                      ],
                      "query": [
                        {
                          "key": "adts",
                          "value": "2"
                        },
                        {
                          "key": "chds",
                          "value": "0"
                        },
                        {
                          "key": "infs",
                          "value": "0"
                        },
                        {
                          "key": "provider_type",
                          "value": "GOL"
                        },
                        {
                          "key": "route",
                          "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                        }
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "52172b5d-49f2-458c-a579-051a2027d0cd",
                  "name": "Price Offer",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves priced tokens for Create Booking\", () => {",
                          "    const journeys = pm.response.json().offer.journeys || [];",
                          "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                          "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers",
                        "price?slice_tokens={{slice_token_1}},{{slice_token_2}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "0be35867-637a-46e5-9916-15307bbb4b05",
                  "name": "Create Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves booking_id and locator\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"booking_id\", b.id);",
                          "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"55 11 999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515200\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "f6393cdb-565f-45aa-8108-281bad3b40a3",
                  "name": "Get Booking (assert ON_HOLD)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is ONHOLD\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"ONHOLD\");",
                          "});",
                          "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                          "pm.test(\"saves booking_total from booking.price.total\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    const total = b && b.price && b.price.total;",
                          "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                          "    pm.environment.set(\"booking_total\", String(total));",
                          "});",
                          "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    const ids = passengers.map(p => p.id).filter(Boolean);",
                          "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                          "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                          "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                          "});",
                          "pm.test(\"saves ticket_numbers for Delete Ticket steps\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    const numbers = [];",
                          "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                          "    numbers.sort().reverse();",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                          "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                          "});",
                          "pm.test(\"saves slice and leg ids for ancillary requests\", () => {",
                          "    const slices = pm.response.json().booking.slices || [];",
                          "    pm.expect(slices.length, \"round-trip must have 2 slices\").to.be.at.least(2);",
                          "    pm.environment.set(\"slice_id_1\", slices[0].id);",
                          "    pm.environment.set(\"slice_id_2\", slices[1].id);",
                          "    pm.expect(slices[0].legs, \"outbound legs\").to.be.an(\"array\").and.not.empty;",
                          "    pm.expect(slices[1].legs, \"return legs\").to.be.an(\"array\").and.not.empty;",
                          "    pm.environment.set(\"leg_id_1\", slices[0].legs[0].id);",
                          "    pm.environment.set(\"leg_id_2\", slices[1].legs[0].id);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "a5bed998-8a5e-4a32-b88d-9ccc236dd36c",
                  "name": "Create Ticket (Credit Card)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"returns tickets array with numbers\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                          "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                          "    pm.environment.set(\"number\", tickets[0].number);",
                          "    // sort descending for the per-ticket cancel flow",
                          "    const numbers = tickets.map(t => t.number).sort().reverse();",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      }\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "c3e76cfe-b9a1-49fd-b869-72a8233670d5",
                  "name": "Get Ticket (assert TICKETED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is TICKETED\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"TICKETED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "0d176d23-092f-4e3b-bcd9-52c62d794921",
                  "name": "Get Booking (assert TICKETED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is TICKETED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"TICKETED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "b4900f67-68e8-4c2f-a58e-a0993bf58746",
                  "name": "Get Seat Map",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves seat tokens: pax1 → 1st available seat, pax2 → 2nd available seat\", () => {",
                          "    const cabins = (pm.response.json().seat_map || {}).cabins || [];",
                          "    pm.expect(cabins, \"cabins\").to.be.an(\"array\").and.not.empty;",
                          "    // Collect all available seat elements (elements with at least one service).",
                          "    const available = [];",
                          "    for (const cabin of cabins)",
                          "        for (const row of cabin.rows || [])",
                          "            for (const section of row.sections || [])",
                          "                for (const elem of section.elements || [])",
                          "                    if ((elem.available_services || []).length > 0)",
                          "                        available.push(elem);",
                          "    pm.expect(available.length, \"at least 2 available seats\").to.be.at.least(2);",
                          "    // passenger_ids was saved by Get Booking (assert ON_HOLD) as a JSON array.",
                          "    const paxIds = JSON.parse(pm.environment.get(\"passenger_ids\") || \"[]\");",
                          "    // pax1 → first available seat, pax2 → second available seat.",
                          "    // Each element carries one service per passenger; match by passenger_id.",
                          "    const svc1 = available[0].available_services.find(s => s.passenger_id === paxIds[0]);",
                          "    const svc2 = available[1].available_services.find(s => s.passenger_id === paxIds[1]);",
                          "    pm.expect(svc1, \"service for pax1 on seat 1\").to.exist;",
                          "    pm.expect(svc2, \"service for pax2 on seat 2\").to.exist;",
                          "    pm.environment.set(\"seat_token_pax1_leg1\", svc1.token);",
                          "    pm.environment.set(\"seat_token_pax2_leg1\", svc2.token);",
                          "    pm.environment.set(\"seat_ancillary_total\",",
                          "        ((svc1.price && svc1.price.amount) || 0) + ((svc2.price && svc2.price.amount) || 0));",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}/legs/{{leg_id_1}}/seat-map",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}",
                        "legs",
                        "{{leg_id_1}}",
                        "seat-map"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "9450c403-c72c-44a3-8fed-59eb0573c722",
                  "name": "Select Seat (ticketed — payment required)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"seat selection successful\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.success, \"success\").to.be.true;",
                          "    pm.expect(body.seat_ancillaries, \"seat_ancillaries\").to.be.an(\"array\").and.not.empty;",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"legs\": [\n    {\n      \"leg_id\": \"{{leg_id_1}}\",\n      \"seat_tokens\": [\"{{seat_token_pax1_leg1}}\", \"{{seat_token_pax2_leg1}}\"]\n    }\n  ],\n  \"payment\": {\n    \"fop_type\": \"CREDITCARD\",\n    \"total\": {{seat_ancillary_total}},\n    \"passenger_ids\": {{passenger_ids}},\n    \"payment_card\": {\n      \"holder\": \"JOHN DOE\",\n      \"number\": \"5555555555554444\",\n      \"card_brand\": \"MASTERCARD\",\n      \"expire_date\": \"03/30\",\n      \"cvv\": \"737\"\n    }\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}/seats",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}",
                        "seats"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "a89385d3-ed3d-4c60-a31b-a68314ef7295",
                  "name": "Get Booking (assert TICKETED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is TICKETED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"TICKETED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "c18b8fbc-789a-49cc-92bb-968a6c98926c",
                  "name": "Delete Ticket (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                          "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                          "}",
                          "// On first iteration, save full list for the Get Ticket loop",
                          "const savedRaw = pm.environment.get('get_ticket_numbers');",
                          "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                          "if (saved.length === 0) {",
                          "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "} else {",
                          "    // proceed to the next request in the folder",
                          "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                          "}"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "4cbc4279-791a-4e38-b1f0-2edf054fa476",
                  "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                          "});",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "}"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "b1acb5a0-a992-487b-83ee-a0c80b8446db",
                  "name": "Cancel Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "a80cdab8-cc47-4313-92bb-63a11ba9c845",
                  "name": "Get Booking (assert CANCELLED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is CANCELLED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                }
              ]
            },
            {
              "id": "08469665-043d-454f-ba3f-1b017bcceef4",
              "name": "Round-trip 2 ADT — Ticketfull (GOL) | Baggage On-Hold | Credit Card",
              "item": [
                {
                  "id": "de151a70-0d03-4b7b-a5a1-6e11443d4f09",
                  "name": "Auth - Access Token",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "const addDays = (n) => {",
                          "    const d = new Date();",
                          "    d.setDate(d.getDate() + n);",
                          "    return d.toISOString().split('T')[0];",
                          "};",
                          "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                          "pm.environment.set('date_2', addDays(19));  // inbound source",
                          "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                          "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves access_token and refresh_token\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"access_token\", body.access_token);",
                          "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/oauth/token",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "7e6a886b-9a33-4c0e-a864-d87ff58b6cda",
                  "name": "Get Offers",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                          "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                          "    // The first slice of each journey carries the token we need.",
                          "    const offers = pm.response.json().offers;",
                          "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                          "    const journeys = offers[0].journeys;",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    const outbound = journeys[0].slices[0].token;",
                          "    const inbound  = journeys[1].slices[0].token;",
                          "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(inbound,  \"inbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"slice_token_1\", outbound);",
                          "    pm.environment.set(\"slice_token_2\", inbound);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers?adts=2&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers"
                      ],
                      "query": [
                        {
                          "key": "adts",
                          "value": "2"
                        },
                        {
                          "key": "chds",
                          "value": "0"
                        },
                        {
                          "key": "infs",
                          "value": "0"
                        },
                        {
                          "key": "provider_type",
                          "value": "GOL"
                        },
                        {
                          "key": "route",
                          "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                        }
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "f65f165d-b51e-4781-a7e2-754f0003ca05",
                  "name": "Price Offer",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves priced tokens for Create Booking\", () => {",
                          "    const journeys = pm.response.json().offer.journeys || [];",
                          "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                          "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers",
                        "price?slice_tokens={{slice_token_1}},{{slice_token_2}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "430356b1-5350-4c94-9689-02365a305dc7",
                  "name": "Create Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves booking_id and locator\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"booking_id\", b.id);",
                          "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"55 11 999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515200\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "76e9edbe-2d08-4601-a7f7-45e2eeb9abb5",
                  "name": "Get Booking (assert ON_HOLD)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is ONHOLD\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"ONHOLD\");",
                          "});",
                          "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                          "pm.test(\"saves booking_total from booking.price.total\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    const total = b && b.price && b.price.total;",
                          "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                          "    pm.environment.set(\"booking_total\", String(total));",
                          "});",
                          "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    const ids = passengers.map(p => p.id).filter(Boolean);",
                          "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                          "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                          "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                          "});",
                          "pm.test(\"saves ticket_numbers for Delete Ticket steps\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    const numbers = [];",
                          "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                          "    numbers.sort().reverse();",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                          "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                          "});",
                          "pm.test(\"saves slice and leg ids for ancillary requests\", () => {",
                          "    const slices = pm.response.json().booking.slices || [];",
                          "    pm.expect(slices.length, \"round-trip must have 2 slices\").to.be.at.least(2);",
                          "    pm.environment.set(\"slice_id_1\", slices[0].id);",
                          "    pm.environment.set(\"slice_id_2\", slices[1].id);",
                          "    pm.expect(slices[0].legs, \"outbound legs\").to.be.an(\"array\").and.not.empty;",
                          "    pm.expect(slices[1].legs, \"return legs\").to.be.an(\"array\").and.not.empty;",
                          "    pm.environment.set(\"leg_id_1\", slices[0].legs[0].id);",
                          "    pm.environment.set(\"leg_id_2\", slices[1].legs[0].id);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "c655a72d-e31a-49be-821b-13925b16abf0",
                  "name": "Get Baggage Options",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves baggage tokens for pax1 and pax2 on slice1\", () => {",
                          "    const perPax = pm.response.json().baggage_options || [];",
                          "    pm.expect(perPax.length, \"baggage_options must have at least 2 passengers\").to.be.at.least(2);",
                          "    const opts0 = perPax[0].baggage_options || [];",
                          "    const opts1 = perPax[1].baggage_options || [];",
                          "    pm.expect(opts0.length, \"pax1 must have at least one baggage option\").to.be.above(0);",
                          "    pm.expect(opts1.length, \"pax2 must have at least one baggage option\").to.be.above(0);",
                          "    pm.environment.set(\"baggage_token_pax1_s1\", opts0[0].token);",
                          "    pm.environment.set(\"baggage_token_pax2_s1\", opts1[0].token);",
                          "    const price1 = (opts0[0].price && opts0[0].price.amount) || 0;",
                          "    const price2 = (opts1[0].price && opts1[0].price.amount) || 0;",
                          "    pm.environment.set(\"baggage_ancillary_total\", price1 + price2);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}/slices/{{slice_id_1}}/baggage-options",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}",
                        "slices",
                        "{{slice_id_1}}",
                        "baggage-options"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "d959fb71-dcc4-407e-b372-cbcd9fb12942",
                  "name": "Select Baggage (on-hold — no payment required)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"baggage selection successful\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.success, \"success\").to.be.true;",
                          "    pm.expect(body.ancillaries, \"ancillaries\").to.be.an(\"array\").and.not.empty;",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"slices\": [\n    {\n      \"slice_id\": \"{{slice_id_1}}\",\n      \"baggage_tokens\": [\"{{baggage_token_pax1_s1}}\", \"{{baggage_token_pax2_s1}}\"]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}/baggages",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}",
                        "baggages"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "9de814df-124d-41c3-aee5-258624b78f1e",
                  "name": "Get Booking (assert extras > 0, update booking_total)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking.price.total_extras is greater than 0 after ancillary selection\", () => {",
                          "    const price = pm.response.json().booking.price || {};",
                          "    pm.expect(price.total_extras, \"booking.price.total_extras\").to.be.a(\"number\").and.above(0);",
                          "});",
                          "pm.test(\"updates booking_total with new total (base + extras)\", () => {",
                          "    const price = pm.response.json().booking.price || {};",
                          "    pm.expect(price.total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                          "    pm.environment.set(\"booking_total\", String(price.total));",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "12a5464d-b1b9-4276-ab8e-7007ad3213f9",
                  "name": "Create Ticket (Credit Card)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"returns tickets array with numbers\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                          "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                          "    pm.environment.set(\"number\", tickets[0].number);",
                          "    // sort descending for the per-ticket cancel flow",
                          "    const numbers = tickets.map(t => t.number).sort().reverse();",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      }\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "dffe8b3d-8c16-4f61-be34-ed6997c8df91",
                  "name": "Get Ticket (assert TICKETED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is TICKETED\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"TICKETED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "6efc73c5-8f2f-474e-b9d1-6ac3f75f8161",
                  "name": "Get Booking (assert TICKETED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is TICKETED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"TICKETED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "3fd61d26-1255-4201-8c11-5bf92f6c1b33",
                  "name": "Delete Ticket (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                          "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                          "}",
                          "// On first iteration, save full list for the Get Ticket loop",
                          "const savedRaw = pm.environment.get('get_ticket_numbers');",
                          "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                          "if (saved.length === 0) {",
                          "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "} else {",
                          "    // proceed to the next request in the folder",
                          "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                          "}"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "cfd7b456-4104-4255-8e39-403fe9f1b641",
                  "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                          "});",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "}"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "c037131f-04ea-420b-9e0f-3759f09ef023",
                  "name": "Cancel Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "2f18a5d0-7cd3-4991-b14f-9435f6f68b4f",
                  "name": "Get Booking (assert CANCELLED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is CANCELLED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                }
              ]
            },
            {
              "id": "1520b1eb-79c3-4d7b-9fba-b05a9342fd51",
              "name": "Round-trip 2 ADT — Ticketfull (GOL) | Baggage Ticketed | Credit Card",
              "item": [
                {
                  "id": "3c57068d-1c5d-4760-8e00-22e0293286b8",
                  "name": "Auth - Access Token",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "const addDays = (n) => {",
                          "    const d = new Date();",
                          "    d.setDate(d.getDate() + n);",
                          "    return d.toISOString().split('T')[0];",
                          "};",
                          "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                          "pm.environment.set('date_2', addDays(19));  // inbound source",
                          "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                          "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves access_token and refresh_token\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"access_token\", body.access_token);",
                          "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/oauth/token",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "e676098d-34fa-4c5a-92ac-127d09e5c53f",
                  "name": "Get Offers",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                          "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                          "    // The first slice of each journey carries the token we need.",
                          "    const offers = pm.response.json().offers;",
                          "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                          "    const journeys = offers[0].journeys;",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    const outbound = journeys[0].slices[0].token;",
                          "    const inbound  = journeys[1].slices[0].token;",
                          "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(inbound,  \"inbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"slice_token_1\", outbound);",
                          "    pm.environment.set(\"slice_token_2\", inbound);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers?adts=2&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers"
                      ],
                      "query": [
                        {
                          "key": "adts",
                          "value": "2"
                        },
                        {
                          "key": "chds",
                          "value": "0"
                        },
                        {
                          "key": "infs",
                          "value": "0"
                        },
                        {
                          "key": "provider_type",
                          "value": "GOL"
                        },
                        {
                          "key": "route",
                          "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                        }
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "ea1e2f87-7d29-4e65-8022-bf1dd8a0374f",
                  "name": "Price Offer",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves priced tokens for Create Booking\", () => {",
                          "    const journeys = pm.response.json().offer.journeys || [];",
                          "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                          "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers",
                        "price?slice_tokens={{slice_token_1}},{{slice_token_2}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "1c1d6be0-71f9-44de-b6c8-fe6f7537b5e4",
                  "name": "Create Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves booking_id and locator\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"booking_id\", b.id);",
                          "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"55 11 999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515200\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "8c42e7c4-6eb5-4038-878b-e1b8f735a44c",
                  "name": "Get Booking (assert ON_HOLD)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is ONHOLD\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"ONHOLD\");",
                          "});",
                          "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                          "pm.test(\"saves booking_total from booking.price.total\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    const total = b && b.price && b.price.total;",
                          "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                          "    pm.environment.set(\"booking_total\", String(total));",
                          "});",
                          "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    const ids = passengers.map(p => p.id).filter(Boolean);",
                          "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                          "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                          "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                          "});",
                          "pm.test(\"saves ticket_numbers for Delete Ticket steps\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    const numbers = [];",
                          "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                          "    numbers.sort().reverse();",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                          "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                          "});",
                          "pm.test(\"saves slice and leg ids for ancillary requests\", () => {",
                          "    const slices = pm.response.json().booking.slices || [];",
                          "    pm.expect(slices.length, \"round-trip must have 2 slices\").to.be.at.least(2);",
                          "    pm.environment.set(\"slice_id_1\", slices[0].id);",
                          "    pm.environment.set(\"slice_id_2\", slices[1].id);",
                          "    pm.expect(slices[0].legs, \"outbound legs\").to.be.an(\"array\").and.not.empty;",
                          "    pm.expect(slices[1].legs, \"return legs\").to.be.an(\"array\").and.not.empty;",
                          "    pm.environment.set(\"leg_id_1\", slices[0].legs[0].id);",
                          "    pm.environment.set(\"leg_id_2\", slices[1].legs[0].id);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "f4cf1dc4-b3d1-4548-af70-2217ca9b8d24",
                  "name": "Create Ticket (Credit Card)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"returns tickets array with numbers\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                          "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                          "    pm.environment.set(\"number\", tickets[0].number);",
                          "    // sort descending for the per-ticket cancel flow",
                          "    const numbers = tickets.map(t => t.number).sort().reverse();",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      }\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "29ae4e93-567e-4f93-9420-8797700ecd99",
                  "name": "Get Ticket (assert TICKETED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is TICKETED\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"TICKETED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "d78f78a4-f1cd-45cc-bf40-fbea7c8ae65b",
                  "name": "Get Booking (assert TICKETED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is TICKETED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"TICKETED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "8ccf8a5d-f967-4736-8045-fc8812ab7841",
                  "name": "Get Baggage Options",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves baggage tokens for pax1 and pax2 on slice1\", () => {",
                          "    const perPax = pm.response.json().baggage_options || [];",
                          "    pm.expect(perPax.length, \"baggage_options must have at least 2 passengers\").to.be.at.least(2);",
                          "    const opts0 = perPax[0].baggage_options || [];",
                          "    const opts1 = perPax[1].baggage_options || [];",
                          "    pm.expect(opts0.length, \"pax1 must have at least one baggage option\").to.be.above(0);",
                          "    pm.expect(opts1.length, \"pax2 must have at least one baggage option\").to.be.above(0);",
                          "    pm.environment.set(\"baggage_token_pax1_s1\", opts0[0].token);",
                          "    pm.environment.set(\"baggage_token_pax2_s1\", opts1[0].token);",
                          "    const price1 = (opts0[0].price && opts0[0].price.amount) || 0;",
                          "    const price2 = (opts1[0].price && opts1[0].price.amount) || 0;",
                          "    pm.environment.set(\"baggage_ancillary_total\", price1 + price2);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}/slices/{{slice_id_1}}/baggage-options",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}",
                        "slices",
                        "{{slice_id_1}}",
                        "baggage-options"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "37ca2ad2-6758-4765-a809-74aac3803efc",
                  "name": "Select Baggage (ticketed — payment required)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"baggage selection successful\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.success, \"success\").to.be.true;",
                          "    pm.expect(body.ancillaries, \"ancillaries\").to.be.an(\"array\").and.not.empty;",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"slices\": [\n    {\n      \"slice_id\": \"{{slice_id_1}}\",\n      \"baggage_tokens\": [\"{{baggage_token_pax1_s1}}\", \"{{baggage_token_pax2_s1}}\"]\n    }\n  ],\n  \"payment\": {\n    \"fop_type\": \"CREDITCARD\",\n    \"total\": {{baggage_ancillary_total}},\n    \"passenger_ids\": {{passenger_ids}},\n    \"payment_card\": {\n      \"holder\": \"JOHN DOE\",\n      \"number\": \"5555555555554444\",\n      \"card_brand\": \"MASTERCARD\",\n      \"expire_date\": \"03/30\",\n      \"cvv\": \"737\"\n    }\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}/baggages",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}",
                        "baggages"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "b60eb65a-d3b5-4070-a9b9-3386849e3e36",
                  "name": "Get Booking (assert TICKETED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is TICKETED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"TICKETED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "271cfaaa-7717-406b-940b-2a09e1293599",
                  "name": "Delete Ticket (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                          "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                          "}",
                          "// On first iteration, save full list for the Get Ticket loop",
                          "const savedRaw = pm.environment.get('get_ticket_numbers');",
                          "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                          "if (saved.length === 0) {",
                          "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "} else {",
                          "    // proceed to the next request in the folder",
                          "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                          "}"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "6455b654-aec0-40c0-af83-4c3f6e5803fd",
                  "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                          "});",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "}"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "0f2d0c69-54f9-4779-a7f9-2a4fdbd48c52",
                  "name": "Cancel Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "id": "5e9c0b6c-25f9-448c-9383-0f9fffe1ba4c",
                  "name": "Get Booking (assert CANCELLED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is CANCELLED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                }
              ]
            }
          ],
          "id": "5479bb69-515e-475c-888f-755556ac96af"
        },
        {
          "name": "Booking Management",
          "item": [
            {
              "name": "Round-trip 2 ADT — Ticketfull (GOL) | Split Before Emission | Invoice",
              "description": "Round-trip 2 ADT GOL booking split before emission. John Doe (passengers[0]) is moved to the child booking. Both halves are invoiced and fully cancelled.",
              "item": [
                {
                  "name": "Auth - Access Token",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "const addDays = (n) => {",
                          "    const d = new Date();",
                          "    d.setDate(d.getDate() + n);",
                          "    return d.toISOString().split('T')[0];",
                          "};",
                          "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                          "pm.environment.set('date_2', addDays(19));  // inbound source",
                          "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                          "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves access_token and refresh_token\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"access_token\", body.access_token);",
                          "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/oauth/token",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Offers",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                          "    const offers = pm.response.json().offers;",
                          "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                          "    const journeys = offers[0].journeys;",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    const outbound = journeys[0].slices[0].token;",
                          "    const inbound  = journeys[1].slices[0].token;",
                          "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(inbound,  \"inbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"slice_token_1\", outbound);",
                          "    pm.environment.set(\"slice_token_2\", inbound);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers?adts=2&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers"
                      ],
                      "query": [
                        {
                          "key": "adts",
                          "value": "2"
                        },
                        {
                          "key": "chds",
                          "value": "0"
                        },
                        {
                          "key": "infs",
                          "value": "0"
                        },
                        {
                          "key": "provider_type",
                          "value": "GOL"
                        },
                        {
                          "key": "route",
                          "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Price Offer",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves priced tokens for Create Booking\", () => {",
                          "    const journeys = pm.response.json().offer.journeys || [];",
                          "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                          "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers",
                        "price"
                      ],
                      "query": [
                        {
                          "key": "slice_tokens",
                          "value": "{{slice_token_1}},{{slice_token_2}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves booking_id and locator\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"booking_id\", b.id);",
                          "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                          "});",
                          "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"55 11 999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515200\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves split_passenger_id\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    pm.expect(passengers.length, \"at least 2 passengers\").to.be.at.least(2);",
                          "    const id = passengers[0].id;",
                          "    pm.expect(id, \"passengers[0].id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"split_passenger_id\", id);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Split Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves child_booking_id and child_locator\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.child_booking_id, \"child_booking_id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(body.original_booking_id, \"original_booking_id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"child_booking_id\", body.child_booking_id);",
                          "    if (body.child_locator) pm.environment.set(\"child_locator\", body.child_locator);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"passenger_ids\": [\n    \"{{split_passenger_id}}\"\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}/split",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}",
                        "split"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (original — assert 1 passenger)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"original booking has 1 passenger after split\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.passengers.length, \"passengers\").to.equal(1);",
                          "});",
                          "pm.test(\"saves booking_total and passenger_ids for Create Ticket\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    const total = b && b.price && b.price.total;",
                          "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                          "    pm.environment.set(\"booking_total\", String(total));",
                          "    const ids = b.passengers.map(p => p.id).filter(Boolean);",
                          "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                          "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (child — assert 1 passenger)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"child booking has 1 passenger\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.passengers.length, \"passengers\").to.equal(1);",
                          "});",
                          "pm.test(\"saves child_booking_total and child_passenger_ids for Create Ticket\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    const total = b && b.price && b.price.total;",
                          "    pm.expect(total, \"child booking.price.total\").to.be.a(\"number\").and.above(0);",
                          "    pm.environment.set(\"child_booking_total\", String(total));",
                          "    const ids = b.passengers.map(p => p.id).filter(Boolean);",
                          "    pm.expect(ids.length, \"at least one child passenger id\").to.be.above(0);",
                          "    pm.environment.set(\"child_passenger_ids\", JSON.stringify(ids));",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{child_booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{child_booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Ticket (Invoice) — original",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves number for Delete Ticket\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets.length, \"tickets\").to.be.above(0);",
                          "    pm.expect(tickets[0].number, \"tickets[0].number\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"number\", tickets[0].number);",
                          "});",
                          "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert TICKETED) — original",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking_status is TICKETED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking_status\").to.equal(\"TICKETED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Ticket (Invoice) — child",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves child_number for Delete Ticket\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets.length, \"tickets\").to.be.above(0);",
                          "    pm.expect(tickets[0].number, \"tickets[0].number\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"child_number\", tickets[0].number);",
                          "});",
                          "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{child_booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{child_booking_total}},\n      \"passenger_ids\": {{child_passenger_ids}}\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert TICKETED) — child",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"child_booking_id\"));",
                          "});",
                          "pm.test(\"child booking_status is TICKETED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking_status\").to.equal(\"TICKETED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{child_booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{child_booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Delete Ticket — original",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Ticket (assert CANCELED) — original",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket_status is CANCELLED\", () => {",
                          "    pm.expect(pm.response.json().ticket_status, \"ticket_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Cancel Booking — original",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert CANCELLED) — original",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking_status is CANCELLED\", () => {",
                          "    pm.expect(pm.response.json().booking.booking_status, \"booking_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Delete Ticket — child",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{child_number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{child_number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Ticket (assert CANCELED) — child",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket_status is CANCELLED\", () => {",
                          "    pm.expect(pm.response.json().ticket_status, \"ticket_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{child_number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{child_number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Cancel Booking — child",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{child_booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{child_booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert CANCELLED) — child",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"child booking_status is CANCELLED\", () => {",
                          "    pm.expect(pm.response.json().booking.booking_status, \"booking_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{child_booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{child_booking_id}}"
                      ]
                    }
                  },
                  "response": []
                }
              ]
            },
            {
              "name": "Round-trip 2 ADT — Ticketfull (GOL) | Split After Emission | Invoice",
              "description": "Round-trip 2 ADT GOL booking split after emission. Tickets are issued for both ADTs first. John Doe (passengers[0]) is then moved to the child booking — his ticket is transferred. Both halves are cancelled.",
              "item": [
                {
                  "name": "Auth - Access Token",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "const addDays = (n) => {",
                          "    const d = new Date();",
                          "    d.setDate(d.getDate() + n);",
                          "    return d.toISOString().split('T')[0];",
                          "};",
                          "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                          "pm.environment.set('date_2', addDays(19));  // inbound source",
                          "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                          "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves access_token and refresh_token\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"access_token\", body.access_token);",
                          "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/oauth/token",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Offers",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                          "    const offers = pm.response.json().offers;",
                          "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                          "    const journeys = offers[0].journeys;",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    const outbound = journeys[0].slices[0].token;",
                          "    const inbound  = journeys[1].slices[0].token;",
                          "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(inbound,  \"inbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"slice_token_1\", outbound);",
                          "    pm.environment.set(\"slice_token_2\", inbound);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers?adts=2&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers"
                      ],
                      "query": [
                        {
                          "key": "adts",
                          "value": "2"
                        },
                        {
                          "key": "chds",
                          "value": "0"
                        },
                        {
                          "key": "infs",
                          "value": "0"
                        },
                        {
                          "key": "provider_type",
                          "value": "GOL"
                        },
                        {
                          "key": "route",
                          "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Price Offer",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves priced slice tokens\", () => {",
                          "    const journeys = pm.response.json().offer.journeys || [];",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    const token1 = journeys[0].slices[0].token;",
                          "    const token2 = journeys[1].slices[0].token;",
                          "    pm.expect(token1, \"journeys[0].slices[0].token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(token2, \"journeys[1].slices[0].token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"slice_token_1\", token1);",
                          "    pm.environment.set(\"slice_token_2\", token2);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers",
                        "price"
                      ],
                      "query": [
                        {
                          "key": "slice_tokens",
                          "value": "{{slice_token_1}},{{slice_token_2}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves booking_id and locator\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"booking_id\", b.id);",
                          "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                          "});",
                          "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"55 11 999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515200\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves booking_total and passenger_ids\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    const total = b && b.price && b.price.total;",
                          "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                          "    pm.environment.set(\"booking_total\", String(total));",
                          "    const ids = b.passengers.map(p => p.id).filter(Boolean);",
                          "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                          "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                          "});",
                          "pm.test(\"saves split_passenger_id\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    pm.expect(passengers.length, \"at least 2 passengers\").to.be.at.least(2);",
                          "    const splitId = passengers[0].id;",
                          "    pm.expect(splitId, \"passengers[0].id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"split_passenger_id\", splitId);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Ticket (Invoice)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"tickets issued for all passengers\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets.length, \"tickets\").to.be.above(0);",
                          "});",
                          "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert TICKETED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking_status is TICKETED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking_status\").to.equal(\"TICKETED\");",
                          "});",
                          "pm.test(\"all passengers have tickets\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    passengers.forEach((p, i) => {",
                          "        pm.expect((p.tickets || []).length, `passengers[${i}] tickets`).to.be.above(0);",
                          "    });",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Split Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves child_booking_id and child_locator\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.child_booking_id, \"child_booking_id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(body.original_booking_id, \"original_booking_id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"child_booking_id\", body.child_booking_id);",
                          "    if (body.child_locator) pm.environment.set(\"child_locator\", body.child_locator);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"passenger_ids\": [\n    \"{{split_passenger_id}}\"\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}/split",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}",
                        "split"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (original — assert TICKETED, 1 passenger)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"original booking is TICKETED with 1 passenger after split\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking_status\").to.equal(\"TICKETED\");",
                          "    pm.expect(b.passengers.length, \"passengers\").to.equal(1);",
                          "});",
                          "pm.test(\"saves number from original passenger ticket\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    const ticket = (b.passengers[0].tickets || [])[0];",
                          "    pm.expect(ticket, \"ticket\").to.be.an(\"object\");",
                          "    pm.expect(ticket.number, \"ticket.number\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"number\", ticket.number);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (child — assert TICKETED, 1 passenger)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"child_booking_id\"));",
                          "});",
                          "pm.test(\"child booking is TICKETED with 1 passenger\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking_status\").to.equal(\"TICKETED\");",
                          "    pm.expect(b.passengers.length, \"passengers\").to.equal(1);",
                          "});",
                          "pm.test(\"saves child_number from child passenger ticket\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    const ticket = (b.passengers[0].tickets || [])[0];",
                          "    pm.expect(ticket, \"ticket\").to.be.an(\"object\");",
                          "    pm.expect(ticket.number, \"ticket.number\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"child_number\", ticket.number);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{child_booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{child_booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Delete Ticket — original",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Ticket (assert CANCELED) — original",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket_status is CANCELLED\", () => {",
                          "    pm.expect(pm.response.json().ticket_status, \"ticket_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Cancel Booking — original",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert CANCELLED) — original",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking_status is CANCELLED\", () => {",
                          "    pm.expect(pm.response.json().booking.booking_status, \"booking_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Delete Ticket — child",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{child_number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{child_number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Ticket (assert CANCELED) — child",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket_status is CANCELLED\", () => {",
                          "    pm.expect(pm.response.json().ticket_status, \"ticket_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{child_number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{child_number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Cancel Booking — child",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{child_booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{child_booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert CANCELLED) — child",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"child booking_status is CANCELLED\", () => {",
                          "    pm.expect(pm.response.json().booking.booking_status, \"booking_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{child_booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{child_booking_id}}"
                      ]
                    }
                  },
                  "response": []
                }
              ]
            },
            {
              "name": "Round-trip 1 ADT (GOL) | Update Frequent Flyer | Otto Ouro",
              "description": "Round-trip 1 ADT GOL booking for Otto Ouro. After booking, adds frequent flyer G3/396648991 via PATCH /bookings/{id}/frequent-flyers and asserts the entry was persisted. No ticketing.",
              "item": [
                {
                  "name": "Auth - Access Token",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "const addDays = (n) => {",
                          "    const d = new Date();",
                          "    d.setDate(d.getDate() + n);",
                          "    return d.toISOString().split('T')[0];",
                          "};",
                          "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                          "pm.environment.set('date_2', addDays(19));  // inbound source",
                          "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                          "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves access_token and refresh_token\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"access_token\", body.access_token);",
                          "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/oauth/token",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Offers",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                          "    const offers = pm.response.json().offers;",
                          "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                          "    const journeys = offers[0].journeys;",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    const outbound = journeys[0].slices[0].token;",
                          "    const inbound  = journeys[1].slices[0].token;",
                          "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(inbound,  \"inbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"slice_token_1\", outbound);",
                          "    pm.environment.set(\"slice_token_2\", inbound);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers"
                      ],
                      "query": [
                        {
                          "key": "adts",
                          "value": "1"
                        },
                        {
                          "key": "chds",
                          "value": "0"
                        },
                        {
                          "key": "infs",
                          "value": "0"
                        },
                        {
                          "key": "provider_type",
                          "value": "GOL"
                        },
                        {
                          "key": "route",
                          "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Price Offer",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves priced tokens for Create Booking\", () => {",
                          "    const journeys = pm.response.json().offer.journeys || [];",
                          "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                          "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers",
                        "price"
                      ],
                      "query": [
                        {
                          "key": "slice_tokens",
                          "value": "{{slice_token_1}},{{slice_token_2}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves booking_id and locator\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"booking_id\", b.id);",
                          "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                          "});",
                          "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Otto\",\n      \"last_name\": \"Ouro\"\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (save passenger_id)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves passenger_id\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    pm.expect(passengers.length, \"at least 1 passenger\").to.be.at.least(1);",
                          "    const id = passengers[0].id;",
                          "    pm.expect(id, \"passengers[0].id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"passenger_id\", id);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Update Booking Frequent Flyer",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "PATCH",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"passengers\": [\n    {\n      \"passenger_id\": \"{{passenger_id}}\",\n      \"airline\": \"G3\",\n      \"code\": \"396648991\"\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}/frequent-flyers",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}",
                        "frequent-flyers"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert frequent flyer G3/396648991)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"passenger has frequent flyer G3 code 396648991\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    pm.expect(passengers.length, \"at least 1 passenger\").to.be.at.least(1);",
                          "    const ffs = passengers[0].frequent_flyers || [];",
                          "    pm.expect(ffs.length, \"frequent_flyers\").to.be.at.least(1);",
                          "    const ff = ffs[0];",
                          "    pm.expect(ff.airline, \"airline\").to.equal(\"G3\");",
                          "    pm.expect(ff.code, \"code\").to.equal(\"396648991\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Cancel Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert CANCELLED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking_status is CANCELLED\", () => {",
                          "    pm.expect(pm.response.json().booking.booking_status, \"booking_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                }
              ]
            },
            {
              "name": "Round-trip 1 ADT (GOL) | Update Passenger Info",
              "description": "Round-trip 1 ADT GOL booking created with mandatory fields only (pax_type, first_name, last_name). Full passenger info (gender, nationality, birth_date, email, phone, documents) is then added via PATCH /bookings/{id} and asserted on a subsequent GET. No ticketing.",
              "item": [
                {
                  "name": "Auth - Access Token",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "const addDays = (n) => {",
                          "    const d = new Date();",
                          "    d.setDate(d.getDate() + n);",
                          "    return d.toISOString().split('T')[0];",
                          "};",
                          "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                          "pm.environment.set('date_2', addDays(19));  // inbound source",
                          "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                          "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves access_token and refresh_token\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"access_token\", body.access_token);",
                          "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/oauth/token",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Offers",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                          "    const offers = pm.response.json().offers;",
                          "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                          "    const journeys = offers[0].journeys;",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    const outbound = journeys[0].slices[0].token;",
                          "    const inbound  = journeys[1].slices[0].token;",
                          "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(inbound,  \"inbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"slice_token_1\", outbound);",
                          "    pm.environment.set(\"slice_token_2\", inbound);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers"
                      ],
                      "query": [
                        {
                          "key": "adts",
                          "value": "1"
                        },
                        {
                          "key": "chds",
                          "value": "0"
                        },
                        {
                          "key": "infs",
                          "value": "0"
                        },
                        {
                          "key": "provider_type",
                          "value": "GOL"
                        },
                        {
                          "key": "route",
                          "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Price Offer",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves priced tokens for Create Booking\", () => {",
                          "    const journeys = pm.response.json().offer.journeys || [];",
                          "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                          "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers",
                        "price"
                      ],
                      "query": [
                        {
                          "key": "slice_tokens",
                          "value": "{{slice_token_1}},{{slice_token_2}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Booking (mandatory fields only)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves booking_id and locator\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"booking_id\", b.id);",
                          "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                          "});",
                          "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\"\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (save passenger_id)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves passenger_id\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    pm.expect(passengers.length, \"at least 1 passenger\").to.be.at.least(1);",
                          "    const id = passengers[0].id;",
                          "    pm.expect(id, \"passengers[0].id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"passenger_id\", id);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Update Booking Passenger Info",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"response contains updated booking\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b, \"booking\").to.be.an(\"object\");",
                          "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "PATCH",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_passengers_info\": [\n    {\n      \"passenger_id\": \"{{passenger_id}}\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"email\": \"john@mymail.com\",\n      \"phone\": \"55 11 999559999\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert passenger info updated)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"passenger info was updated\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    pm.expect(passengers.length, \"at least 1 passenger\").to.be.at.least(1);",
                          "    const p = passengers[0];",
                          "    pm.expect(p.gender_type, \"gender_type\").to.equal(\"MALE\");",
                          "    pm.expect(p.birth_date, \"birth_date\").to.equal(\"1990-05-12\");",
                          "    pm.expect(p.email, \"email\").to.equal(\"john@mymail.com\");",
                          "    pm.expect(p.phone_number, \"phone_number\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(p.nationality, \"nationality\").to.equal(\"BR\");",
                          "    const docs = p.documents || [];",
                          "    pm.expect(docs.length, \"documents\").to.be.at.least(1);",
                          "    pm.expect(docs[0].unique_identifier, \"documents[0].unique_identifier\").to.equal(\"7515199\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Cancel Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert CANCELLED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking_status is CANCELLED\", () => {",
                          "    pm.expect(pm.response.json().booking.booking_status, \"booking_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                }
              ]
            },
            {
              "name": "One-way 3 ADT — Ticketfull (GOL) | Partial Issue (2 then 1) | Invoice",
              "description": "AG-5605 — emissao parcial. One-way 3 ADT GOL, invoice. A primeira emissao cobre 2 passageiros (Ana e Bruno), a segunda cobre o terceiro (Carla). Depois os 3 bilhetes sao cancelados um a um e a reserva e cancelada, como nos demais flows ticketfull.\n\nA selecao trafega em form_of_payments[].passenger_ids, campo que o guruapi ja exigia antes desta feature (InputFormOfPayment, minItems 1) e mapeia para o gRPC em internal/core/converters_ticket.go:69. Emissao parcial e expressa apenas por QUAIS ids vao no array — nenhum endpoint ou campo novo.\n\nAsserção central: a emissao 1 exige tickets.length == 2. E o teste de fumaca do Critical em que o provider-gol emitia o PNR inteiro quando a selecao nao casava com a perna de infant; se vier 3, a correcao regrediu.\n\nAponte url para https://api.dev.agent.guru/rs/v1/flights: dev e o unico ambiente onde a feature e o guruapi coexistem (dev2 nao tem guruapi deployado, stg nao tem a feature).\n\nNao exercita o caminho CC+BT, que e onde o Critical vivia — para aquilo e preciso um FOP CREDITCARD_AND_INVOICE e uma reserva com infant.",
              "item": [
                {
                  "name": "Auth - Access Token",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "const addDays = (n) => {",
                          "    const d = new Date();",
                          "    d.setDate(d.getDate() + n);",
                          "    return d.toISOString().split('T')[0];",
                          "};",
                          "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                          "pm.environment.set('date_2', addDays(19));  // inbound source",
                          "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                          "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves access_token and refresh_token\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"access_token\", body.access_token);",
                          "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/oauth/token",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Offers",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves slice_token_1 (outbound)\", () => {",
                          "    const offers = pm.response.json().offers;",
                          "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                          "    const token = offers[0].journeys[0].slices[0].token;",
                          "    pm.expect(token, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"slice_token_1\", token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers?adts=3&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers"
                      ],
                      "query": [
                        {
                          "key": "adts",
                          "value": "3"
                        },
                        {
                          "key": "chds",
                          "value": "0"
                        },
                        {
                          "key": "infs",
                          "value": "0"
                        },
                        {
                          "key": "provider_type",
                          "value": "GOL"
                        },
                        {
                          "key": "route",
                          "value": "SAO,RIO,{{date_1}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Price Offer",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves priced tokens for Create Booking\", () => {",
                          "    // Price response mirrors the offer structure: one journey per slice direction.",
                          "    const journeys = pm.response.json().offer.journeys || [];",
                          "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                          "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers",
                        "price"
                      ],
                      "query": [
                        {
                          "key": "slice_tokens",
                          "value": "{{slice_token_1}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves booking_id and locator\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"booking_id\", b.id);",
                          "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                          "});",
                          "pm.test(\"booking has exactly 3 ADT passengers\", () => {",
                          "    const pax = pm.response.json().booking.passengers;",
                          "    pm.expect(pax, \"passengers\").to.be.an(\"array\").with.lengthOf(3);",
                          "    pax.forEach((p, i) => pm.expect(p.pax_type, `passengers[${i}].pax_type`).to.equal(\"ADT\"));",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "url": {
                      "raw": "{{url}}/bookings",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Ana\",\n      \"last_name\": \"Primeira\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1990-04-11\",\n      \"phone_number\": \"55 11 999550001\",\n      \"email\": \"ana.primeira@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515001\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Bruno\",\n      \"last_name\": \"Segundo\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1988-09-02\",\n      \"phone_number\": \"55 11 999550002\",\n      \"email\": \"bruno.segundo@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515002\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Carla\",\n      \"last_name\": \"Terceira\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1995-01-30\",\n      \"phone_number\": \"55 11 999550003\",\n      \"email\": \"carla.terceira@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515003\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert ONHOLD, prepare emission 1 of 2 pax)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const b = pm.response.json().booking;",
                          "",
                          "pm.test(\"booking.id matches\", () => {",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "",
                          "pm.test(\"booking is ONHOLD before any issuance\", () => {",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"ONHOLD\");",
                          "});",
                          "",
                          "pm.test(\"capability ticket is true, partial_issue is false before issuing\", () => {",
                          "    pm.expect(b.capabilities.ticket, \"capabilities.ticket\").to.equal(true);",
                          "    if (b.capabilities.partial_issue !== undefined) {",
                          "        pm.expect(b.capabilities.partial_issue, \"capabilities.partial_issue\").to.equal(false);",
                          "    }",
                          "});",
                          "",
                          "// ── Split the three passengers into the two emissions ──",
                          "pm.test(\"saves the two passenger groups and their totals\", () => {",
                          "    const pax = b.passengers;",
                          "    pm.expect(pax, \"passengers\").to.have.lengthOf(3);",
                          "    const ids = pax.map(p => p.id);",
                          "    ids.forEach((id, i) => pm.expect(id, `passengers[${i}].id`).to.be.a(\"string\").and.not.empty);",
                          "",
                          "    const totalOf = p => Number((p.price && p.price.total) || 0);",
                          "    pm.environment.set(\"pax_group_1\", JSON.stringify([ids[0], ids[1]]));",
                          "    pm.environment.set(\"pax_group_2\", JSON.stringify([ids[2]]));",
                          "    pm.environment.set(\"total_group_1\", String(totalOf(pax[0]) + totalOf(pax[1])));",
                          "    pm.environment.set(\"total_group_2\", String(totalOf(pax[2])));",
                          "",
                          "    // Create Ticket interpolates {{passenger_ids}} and {{booking_total}} straight",
                          "    // into its body, so point them at group 1 for the first emission.",
                          "    pm.environment.set(\"passenger_ids\", pm.environment.get(\"pax_group_1\"));",
                          "    pm.environment.set(\"booking_total\", pm.environment.get(\"total_group_1\"));",
                          "    // Reset the accumulator the cleanup loop consumes.",
                          "    pm.environment.set(\"ticket_numbers\", \"[]\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Ticket (Invoice) — emission 1 of 2 pax (PARTIAL)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "",
                          "pm.test(\"issued exactly 2 tickets, not the whole PNR\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    // Smoke test for the AG-5605 Critical: provider-gol used to issue every",
                          "    // passenger in the PNR when the selection did not match the infant leg.",
                          "    pm.expect(tickets.length, \"tickets.length (expected 2, not 3)\").to.equal(2);",
                          "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                          "});",
                          "",
                          "pm.test(\"accumulates ticket numbers for the cleanup loop\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    const acc = JSON.parse(pm.environment.get(\"ticket_numbers\") || \"[]\");",
                          "    tickets.forEach(t => acc.push(t.number));",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(acc.sort().reverse()));",
                          "    pm.environment.set(\"number\", tickets[0].number);",
                          "    pm.environment.set(\"tickets_emission_1\", JSON.stringify(tickets.map(t => t.number)));",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert PENDING + partial warning, prepare emission 2)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const b = pm.response.json().booking;",
                          "",
                          "pm.test(\"booking is PENDING after a partial emission\", () => {",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"PENDING\");",
                          "});",
                          "",
                          "pm.test(\"exactly 2 of the 3 passengers hold a ticket\", () => {",
                          "    const withTicket = b.passengers.filter(p => (p.tickets || []).length > 0);",
                          "    pm.expect(withTicket.length, \"passengers holding a ticket\").to.equal(2);",
                          "});",
                          "",
                          "pm.test(\"BOOKING_PARTIAL_ISSUED warning is present, with its action\", () => {",
                          "    const w = (b.warnings || []).find(x => String(x.type).includes(\"PARTIAL_ISSUED\"));",
                          "    pm.expect(w, \"partial issued warning\").to.not.be.undefined;",
                          "    // The action is what lets a client re-enter the issuance flow.",
                          "    pm.expect(JSON.stringify(w.actions || []), \"warning.actions\").to.include(\"PARTIAL_ISSUE\");",
                          "});",
                          "",
                          "pm.test(\"capability partial_issue unlocks re-entry\", () => {",
                          "    pm.expect(b.capabilities.partial_issue, \"capabilities.partial_issue\").to.equal(true);",
                          "});",
                          "",
                          "pm.test(\"points passenger_ids and booking_total at the remaining passenger\", () => {",
                          "    pm.environment.set(\"passenger_ids\", pm.environment.get(\"pax_group_2\"));",
                          "    pm.environment.set(\"booking_total\", pm.environment.get(\"total_group_2\"));",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Ticket (Invoice) — emission 2 of the remaining pax (COMPLETES)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "",
                          "pm.test(\"issued exactly 1 ticket, not a duplicate of emission 1\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets.length, \"tickets.length\").to.equal(1);",
                          "    const first = JSON.parse(pm.environment.get(\"tickets_emission_1\") || \"[]\");",
                          "    pm.expect(first, \"emission 1 ticket numbers\").to.not.include(tickets[0].number);",
                          "});",
                          "",
                          "pm.test(\"accumulates ticket numbers for the cleanup loop\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    const acc = JSON.parse(pm.environment.get(\"ticket_numbers\") || \"[]\");",
                          "    tickets.forEach(t => acc.push(t.number));",
                          "    pm.expect(acc.length, \"tickets accumulated across both emissions\").to.equal(3);",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(acc.sort().reverse()));",
                          "    pm.environment.set(\"number\", tickets[0].number);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert TICKETED, warning gone)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const b = pm.response.json().booking;",
                          "",
                          "pm.test(\"all 3 passengers hold a ticket\", () => {",
                          "    const withTicket = b.passengers.filter(p => (p.tickets || []).length > 0);",
                          "    pm.expect(withTicket.length, \"passengers holding a ticket\").to.equal(3);",
                          "});",
                          "",
                          "pm.test(\"booking is TICKETED once nobody is left without a ticket\", () => {",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                          "});",
                          "",
                          "pm.test(\"partial issued warning is gone\", () => {",
                          "    const w = (b.warnings || []).find(x => String(x.type).includes(\"PARTIAL_ISSUED\"));",
                          "    pm.expect(w, \"partial issued warning\").to.be.undefined;",
                          "});",
                          "",
                          "pm.test(\"capability partial_issue is false again\", () => {",
                          "    pm.expect(b.capabilities.partial_issue, \"capabilities.partial_issue\").to.equal(false);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Delete Ticket (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "exec": [
                          "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                          "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                          "}",
                          "// On first iteration, save full list for the Get Ticket loop",
                          "const savedRaw = pm.environment.get('get_ticket_numbers');",
                          "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                          "if (saved.length === 0) {",
                          "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                        ],
                        "type": "text/javascript"
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "} else {",
                          "    // proceed to the next request in the folder",
                          "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                          "}"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "exec": [
                          "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                        ],
                        "type": "text/javascript"
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                          "});",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "}"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Cancel Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert CANCELLED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is CANCELLED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                }
              ]
            },
            {
              "name": "One-way 2 ADT + 1 INF — Ticketfull (GOL) | Partial Issue (ADT+INF then ADT) | CC then Invoice",
              "description": "AG-5605 — emissao parcial. One-way 3 ADT GOL, invoice. A primeira emissao cobre 2 passageiros (Ana e Bruno), a segunda cobre o terceiro (Carla). Depois os 3 bilhetes sao cancelados um a um e a reserva e cancelada, como nos demais flows ticketfull.\n\nA selecao trafega em form_of_payments[].passenger_ids, campo que o guruapi ja exigia antes desta feature (InputFormOfPayment, minItems 1) e mapeia para o gRPC em internal/core/converters_ticket.go:69. Emissao parcial e expressa apenas por QUAIS ids vao no array — nenhum endpoint ou campo novo.\n\nAsserção central: a emissao 1 exige tickets.length == 2. E o teste de fumaca do Critical em que o provider-gol emitia o PNR inteiro quando a selecao nao casava com a perna de infant; se vier 3, a correcao regrediu.\n\nAponte url para https://api.dev.agent.guru/rs/v1/flights: dev e o unico ambiente onde a feature e o guruapi coexistem (dev2 nao tem guruapi deployado, stg nao tem a feature).\n\nNao exercita o caminho CC+BT, que e onde o Critical vivia — para aquilo e preciso um FOP CREDITCARD_AND_INVOICE e uma reserva com infant.",
              "item": [
                {
                  "name": "Auth - Access Token",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "const addDays = (n) => {",
                          "    const d = new Date();",
                          "    d.setDate(d.getDate() + n);",
                          "    return d.toISOString().split('T')[0];",
                          "};",
                          "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                          "pm.environment.set('date_2', addDays(19));  // inbound source",
                          "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                          "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves access_token and refresh_token\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"access_token\", body.access_token);",
                          "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/oauth/token",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Offers",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves slice_token_1 (outbound)\", () => {",
                          "    const offers = pm.response.json().offers;",
                          "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                          "    const token = offers[0].journeys[0].slices[0].token;",
                          "    pm.expect(token, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"slice_token_1\", token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers?adts=2&chds=0&infs=1&provider_type=GOL&route=SAO,RIO,{{date_1}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers"
                      ],
                      "query": [
                        {
                          "key": "adts",
                          "value": "2"
                        },
                        {
                          "key": "chds",
                          "value": "0"
                        },
                        {
                          "key": "infs",
                          "value": "1"
                        },
                        {
                          "key": "provider_type",
                          "value": "GOL"
                        },
                        {
                          "key": "route",
                          "value": "SAO,RIO,{{date_1}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Price Offer",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves priced tokens for Create Booking\", () => {",
                          "    // Price response mirrors the offer structure: one journey per slice direction.",
                          "    const journeys = pm.response.json().offer.journeys || [];",
                          "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                          "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers",
                        "price"
                      ],
                      "query": [
                        {
                          "key": "slice_tokens",
                          "value": "{{slice_token_1}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves booking_id and locator\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"booking_id\", b.id);",
                          "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                          "});",
                          "pm.test(\"booking has 2 ADT and 1 INF\", () => {",
                          "    const pax = pm.response.json().booking.passengers;",
                          "    pm.expect(pax, \"passengers\").to.be.an(\"array\").with.lengthOf(3);",
                          "    const byType = t => pax.filter(p => p.pax_type === t).length;",
                          "    pm.expect(byType(\"ADT\"), \"ADT count\").to.equal(2);",
                          "    pm.expect(byType(\"INF\"), \"INF count\").to.equal(1);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "url": {
                      "raw": "{{url}}/bookings",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Ana\",\n      \"last_name\": \"Primeira\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1990-04-11\",\n      \"phone_number\": \"55 11 999550001\",\n      \"email\": \"ana.primeira@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515101\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Bruno\",\n      \"last_name\": \"Segundo\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1988-09-02\",\n      \"phone_number\": \"55 11 999550002\",\n      \"email\": \"bruno.segundo@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515102\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"INF\",\n      \"first_name\": \"Caio\",\n      \"last_name\": \"Terceiro\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"2025-06-15\",\n      \"phone_number\": \"55 11 999550003\",\n      \"email\": \"caio.terceiro@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515103\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert ONHOLD, pair the infant with its adult)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const b = pm.response.json().booking;",
                          "",
                          "pm.test(\"booking.id matches\", () => {",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "",
                          "pm.test(\"booking is ONHOLD before any issuance\", () => {",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"ONHOLD\");",
                          "});",
                          "",
                          "pm.test(\"capability ticket is true, partial_issue is false before issuing\", () => {",
                          "    pm.expect(b.capabilities.ticket, \"capabilities.ticket\").to.equal(true);",
                          "    if (b.capabilities.partial_issue !== undefined) {",
                          "        pm.expect(b.capabilities.partial_issue, \"capabilities.partial_issue\").to.equal(false);",
                          "    }",
                          "});",
                          "",
                          "// The infant/adult association is NOT sent on Create Booking - the GDS assigns",
                          "// it. It reaches guruapi inverted: provider-gol fills",
                          "// AssociatedInfantProviderId on the INFANT with the ADULT's NameId, and",
                          "// api-booking converts it reading the field as if the adult carried it, so the",
                          "// adult comes out empty. guruapi normalizes that back to what the contract",
                          "// promises - \"the identifier of an associated infant if the passenger is an",
                          "// adult\" - in normalizeInfantAssociation.",
                          "//",
                          "// So this assertion covers two things at once: that the provider still returns",
                          "// the association at all, and that the normalization is in place. If it fails,",
                          "// read it as \"the pairing is missing\", not as a flow bug.",
                          "//",
                          "// NOTE the same inverted data still reaches api-ticketing over gRPC, where it",
                          "// silently defeats the adult-selected-without-its-infant guard. Not visible from",
                          "// this flow, which always selects both.",
                          "pm.test(\"the infant is associated with one of the two adults\", () => {",
                          "    const pax = b.passengers;",
                          "    pm.expect(pax, \"passengers\").to.have.lengthOf(3);",
                          "",
                          "    const infants = pax.filter(p => p.pax_type === \"INF\");",
                          "    const adults = pax.filter(p => p.pax_type === \"ADT\");",
                          "    pm.expect(infants.length, \"INF count\").to.equal(1);",
                          "    pm.expect(adults.length, \"ADT count\").to.equal(2);",
                          "",
                          "    const inf = infants[0];",
                          "    const pairedAdt = adults.find(a => a.associated_infant_id === inf.id);",
                          "    pm.expect(pairedAdt, \"the ADT whose associated_infant_id points at the INF\").to.not.be.undefined;",
                          "",
                          "    const loneAdt = adults.find(a => a.id !== pairedAdt.id);",
                          "    pm.expect(loneAdt, \"the ADT travelling without an infant\").to.not.be.undefined;",
                          "",
                          "    const totalOf = p => Number((p.price && p.price.total) || 0);",
                          "",
                          "    // Emission 1 takes the infant's adult AND the infant. api-ticketing refuses",
                          "    // a selection that takes one without the other (ErrAdultWithoutInfant /",
                          "    // ErrInfantWithoutAdult), and provider-gol needs both to scope the infant",
                          "    // leg of the AirTicketRQ.",
                          "    pm.environment.set(\"pax_group_1\", JSON.stringify([pairedAdt.id, inf.id]));",
                          "    pm.environment.set(\"pax_group_2\", JSON.stringify([loneAdt.id]));",
                          "    pm.environment.set(\"total_group_1\", String(totalOf(pairedAdt) + totalOf(inf)));",
                          "    pm.environment.set(\"total_group_2\", String(totalOf(loneAdt)));",
                          "",
                          "    // Kept so the later steps can assert the excluded adult was left untouched.",
                          "    pm.environment.set(\"pax_paired_adt\", pairedAdt.id);",
                          "    pm.environment.set(\"pax_infant\", inf.id);",
                          "    pm.environment.set(\"pax_lone_adt\", loneAdt.id);",
                          "",
                          "    // Create Ticket interpolates {{passenger_ids}} and {{booking_total}} straight",
                          "    // into its body, so point them at group 1 for the first emission.",
                          "    pm.environment.set(\"passenger_ids\", pm.environment.get(\"pax_group_1\"));",
                          "    pm.environment.set(\"booking_total\", pm.environment.get(\"total_group_1\"));",
                          "    // Reset the accumulator the cleanup loop consumes.",
                          "    pm.environment.set(\"ticket_numbers\", \"[]\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Installments (credit card plan for emission 1)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// /installments takes passenger_ids as a comma-separated list (style: form,",
                          "// explode: false), while {{passenger_ids}} is a JSON array because Create Ticket",
                          "// interpolates it straight into its body. Derive the CSV form here instead of",
                          "// keeping two variables in sync by hand.",
                          "const raw = pm.environment.get(\"passenger_ids\");",
                          "if (!raw) {",
                          "    throw new Error(\"passenger_ids is empty - run the Get Booking step that pairs the infant first.\");",
                          "}",
                          "pm.environment.set(\"passenger_ids_csv\", JSON.parse(raw).join(\",\"));"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const body = pm.response.json();",
                          "",
                          "pm.test(\"saves plan_token for the single-installment plan\", () => {",
                          "    const plans = body.installment_plans || [];",
                          "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                          "    // 1 installment (a vista) carries no interest. Interest rides inside the",
                          "    // plan_token, so a multi-installment plan is only safe once the plan itself",
                          "    // is scoped to the selection - which is what passenger_ids now does.",
                          "    const plan1 = plans.find(p => p.installment === 1) || plans[0];",
                          "    pm.expect(plan1.plan_token, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"plan_token\", plan1.plan_token);",
                          "    pm.environment.set(\"plan_installment\", String(plan1.installment));",
                          "    pm.environment.set(\"plan_total\", String(plan1.total));",
                          "});",
                          "",
                          "// The point of sending passenger_ids: without it guruapi took the ids from the",
                          "// booking and the plan covered every passenger, so the plan_token carried",
                          "// discount and OB fee for an amount nobody was about to charge - and api-order",
                          "// rejected the order with \"total amount is invalid\".",
                          "//",
                          "// This equality holds here because the flow books no ancillaries. guruapi still",
                          "// sends every ancillary of the booking to api-payment regardless of the",
                          "// selection (convertToAncillaries), so on a booking with ancillaries for a",
                          "// passenger left out of the emission the plan total would exceed the selection",
                          "// and this assertion would fail - correctly, and for a cause that is still open.",
                          "pm.test(\"the plan covers the selection, not the whole booking\", () => {",
                          "    const plans = body.installment_plans || [];",
                          "    const plan1 = plans.find(p => p.installment === 1) || plans[0];",
                          "    const selectionTotal = Number(pm.environment.get(\"total_group_1\"));",
                          "    pm.expect(selectionTotal, \"total_group_1\").to.be.above(0);",
                          "    // Same tolerance api-order applies (roundingLimit = 0.1).",
                          "    pm.expect(Math.abs(Number(plan1.total) - selectionTotal),",
                          "        `plan.total ${plan1.total} vs selection total ${selectionTotal}`).to.be.at.most(0.1);",
                          "});",
                          "",
                          "pm.test(\"plan carries no discount or ob fee beyond the selection\", () => {",
                          "    pm.expect(Number(body.discount || 0), \"installments.discount\").to.equal(0);",
                          "    pm.expect(Number(body.obfee || 0), \"installments.obfee\").to.equal(0);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/installments?creditcard_bin=555544&booking_id={{booking_id}}&passenger_ids={{passenger_ids_csv}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "installments"
                      ],
                      "query": [
                        {
                          "key": "creditcard_bin",
                          "value": "555544"
                        },
                        {
                          "key": "booking_id",
                          "value": "{{booking_id}}"
                        },
                        {
                          "key": "passenger_ids",
                          "value": "{{passenger_ids_csv}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Ticket (Credit Card) — emission 1: the infant's adult + the infant (PARTIAL)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "",
                          "// This is where the AG-5605 Critical lived: provider-gol built the AirTicketRQ",
                          "// with no NameSelect when the selection did not match the infant leg, and Sabre",
                          "// reads a missing NameSelect as \"issue the ENTIRE PNR\". The 3-ADT invoice flow",
                          "// never reaches this path — it takes a credit card FOP plus an infant to get",
                          "// here.",
                          "pm.test(\"did not issue the whole PNR\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets.length, \"tickets.length\").to.be.above(0);",
                          "    // Two passengers were selected (adult + infant). Whether GOL returns one",
                          "    // ticket or two depends on the infant carrying its own document, so the",
                          "    // count is bounded instead of fixed. Three would mean the excluded adult",
                          "    // was issued as well — the regression this flow exists to catch. The",
                          "    // per-passenger check in the next request is the precise assertion.",
                          "    pm.expect(tickets.length, \"tickets.length (3 would mean the whole PNR)\").to.be.at.most(2);",
                          "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                          "});",
                          "",
                          "pm.test(\"accumulates ticket numbers for the cleanup loop\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    const acc = JSON.parse(pm.environment.get(\"ticket_numbers\") || \"[]\");",
                          "    tickets.forEach(t => acc.push(t.number));",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(acc.sort().reverse()));",
                          "    pm.environment.set(\"number\", tickets[0].number);",
                          "    pm.environment.set(\"tickets_emission_1\", JSON.stringify(tickets.map(t => t.number)));",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555444433331111\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{plan_token}}\"\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert PENDING + partial warning, prepare emission 2)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const b = pm.response.json().booking;",
                          "",
                          "pm.test(\"booking is PENDING after a partial emission\", () => {",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"PENDING\");",
                          "});",
                          "",
                          "// The precise form of the Critical check: not \"how many tickets came back\" but",
                          "// \"was the passenger nobody paid for left alone\".",
                          "pm.test(\"the excluded adult holds no ticket\", () => {",
                          "    const loneAdtId = pm.environment.get(\"pax_lone_adt\");",
                          "    const loneAdt = b.passengers.find(p => p.id === loneAdtId);",
                          "    pm.expect(loneAdt, \"the adult left out of emission 1\").to.not.be.undefined;",
                          "    pm.expect((loneAdt.tickets || []).length, \"tickets of the excluded adult\").to.equal(0);",
                          "});",
                          "",
                          "pm.test(\"the infant's adult holds a ticket\", () => {",
                          "    const pairedId = pm.environment.get(\"pax_paired_adt\");",
                          "    const paired = b.passengers.find(p => p.id === pairedId);",
                          "    pm.expect(paired, \"the infant's adult\").to.not.be.undefined;",
                          "    pm.expect((paired.tickets || []).length, \"tickets of the infant's adult\").to.be.above(0);",
                          "});",
                          "",
                          "pm.test(\"BOOKING_PARTIAL_ISSUED warning is present, with its action\", () => {",
                          "    const w = (b.warnings || []).find(x => String(x.type).includes(\"PARTIAL_ISSUED\"));",
                          "    pm.expect(w, \"partial issued warning\").to.not.be.undefined;",
                          "    // The action is what lets a client re-enter the issuance flow.",
                          "    pm.expect(JSON.stringify(w.actions || []), \"warning.actions\").to.include(\"PARTIAL_ISSUE\");",
                          "});",
                          "",
                          "pm.test(\"capability partial_issue unlocks re-entry\", () => {",
                          "    pm.expect(b.capabilities.partial_issue, \"capabilities.partial_issue\").to.equal(true);",
                          "});",
                          "",
                          "// api-booking derives PENDING while any passenger lacks a ticket, so ticket had",
                          "// to stop meaning \"is ONHOLD\". With ticket=false the order dies inside the",
                          "// GetBooking retry of oms-order-validation (bookingProviderError treats",
                          "// ticket=false plus a warning as a broken booking) before any validation runs.",
                          "pm.test(\"capability ticket still allows the second emission\", () => {",
                          "    pm.expect(b.capabilities.ticket, \"capabilities.ticket\").to.equal(true);",
                          "});",
                          "",
                          "pm.test(\"points passenger_ids and booking_total at the remaining adult\", () => {",
                          "    pm.environment.set(\"passenger_ids\", pm.environment.get(\"pax_group_2\"));",
                          "    pm.environment.set(\"booking_total\", pm.environment.get(\"total_group_2\"));",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Ticket (Invoice) — emission 2: the remaining adult (COMPLETES)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "",
                          "// A different FOP from emission 1 on purpose: the two emissions of one booking",
                          "// are independent orders, and nothing should force them onto the same payment",
                          "// method.",
                          "pm.test(\"issued exactly 1 ticket for the remaining adult\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets.length, \"tickets.length\").to.equal(1);",
                          "    pm.expect(tickets[0].number, \"tickets[0].number\").to.be.a(\"string\").and.not.empty;",
                          "});",
                          "",
                          "pm.test(\"the second emission is not a duplicate of the first\", () => {",
                          "    const issued = (pm.response.json().tickets || []).map(t => t.number);",
                          "    const first = JSON.parse(pm.environment.get(\"tickets_emission_1\") || \"[]\");",
                          "    issued.forEach(n => pm.expect(first, \"numbers issued by emission 1\").to.not.include(n));",
                          "});",
                          "",
                          "pm.test(\"accumulates ticket numbers for the cleanup loop\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    const acc = JSON.parse(pm.environment.get(\"ticket_numbers\") || \"[]\");",
                          "    tickets.forEach(t => acc.push(t.number));",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(acc.sort().reverse()));",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert TICKETED, warning gone)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const b = pm.response.json().booking;",
                          "",
                          "pm.test(\"booking is TICKETED once every passenger holds a ticket\", () => {",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                          "});",
                          "",
                          "pm.test(\"every passenger holds a ticket\", () => {",
                          "    const without = b.passengers.filter(p => (p.tickets || []).length === 0);",
                          "    pm.expect(without.map(p => p.id), \"passengers still without a ticket\").to.be.empty;",
                          "});",
                          "",
                          "pm.test(\"BOOKING_PARTIAL_ISSUED warning is gone\", () => {",
                          "    const w = (b.warnings || []).find(x => String(x.type).includes(\"PARTIAL_ISSUED\"));",
                          "    pm.expect(w, \"partial issued warning\").to.be.undefined;",
                          "});",
                          "",
                          "pm.test(\"capability partial_issue is back to false\", () => {",
                          "    pm.expect(b.capabilities.partial_issue, \"capabilities.partial_issue\").to.equal(false);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Delete Ticket (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "exec": [
                          "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                          "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                          "}",
                          "// On first iteration, save full list for the Get Ticket loop",
                          "const savedRaw = pm.environment.get('get_ticket_numbers');",
                          "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                          "if (saved.length === 0) {",
                          "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                        ],
                        "type": "text/javascript"
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "} else {",
                          "    // proceed to the next request in the folder",
                          "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                          "}"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "exec": [
                          "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                        ],
                        "type": "text/javascript"
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                          "});",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "}"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Cancel Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert CANCELLED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is CANCELLED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                }
              ]
            },
            {
              "name": "Round-trip 3 ADT — Ticketfull (GOL) | Full Issue, Cancel One Ticket, Issue That One Again | Credit Card",
              "item": [
                {
                  "name": "Auth - Access Token",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "const addDays = (n) => {",
                          "    const d = new Date();",
                          "    d.setDate(d.getDate() + n);",
                          "    return d.toISOString().split('T')[0];",
                          "};",
                          "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                          "pm.environment.set('date_2', addDays(19));  // inbound source",
                          "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                          "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves access_token and refresh_token\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"access_token\", body.access_token);",
                          "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/oauth/token",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Offers",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                          "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                          "    // The first slice of each journey carries the token we need.",
                          "    const offers = pm.response.json().offers;",
                          "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                          "    const journeys = offers[0].journeys;",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    const outbound = journeys[0].slices[0].token;",
                          "    const inbound = journeys[1].slices[0].token;",
                          "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(inbound, \"inbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"slice_token_1\", outbound);",
                          "    pm.environment.set(\"slice_token_2\", inbound);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers?adts=3&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers"
                      ],
                      "query": [
                        {
                          "key": "adts",
                          "value": "3"
                        },
                        {
                          "key": "chds",
                          "value": "0"
                        },
                        {
                          "key": "infs",
                          "value": "0"
                        },
                        {
                          "key": "provider_type",
                          "value": "GOL"
                        },
                        {
                          "key": "route",
                          "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Price Offer",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves priced tokens for Create Booking\", () => {",
                          "    // Price response mirrors the offer structure: one journey per slice direction.",
                          "    const journeys = pm.response.json().offer.journeys || [];",
                          "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                          "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers",
                        "price"
                      ],
                      "query": [
                        {
                          "key": "slice_tokens",
                          "value": "{{slice_token_1}},{{slice_token_2}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves booking_id and locator\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"booking_id\", b.id);",
                          "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                          "});",
                          "pm.test(\"booking has 3 ADT on a round trip\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.passengers, \"passengers\").to.be.an(\"array\").with.lengthOf(3);",
                          "    b.passengers.forEach((p, i) => pm.expect(p.pax_type, `passengers[${i}].pax_type`).to.equal(\"ADT\"));",
                          "    pm.expect((b.slices || []).length, \"slices (round trip)\").to.equal(2);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "url": {
                      "raw": "{{url}}/bookings",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Ana\",\n      \"last_name\": \"Primeira\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1990-04-11\",\n      \"phone_number\": \"55 11 999550001\",\n      \"email\": \"ana.primeira@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515201\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Bruno\",\n      \"last_name\": \"Segundo\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1988-09-02\",\n      \"phone_number\": \"55 11 999550002\",\n      \"email\": \"bruno.segundo@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515202\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Carla\",\n      \"last_name\": \"Terceira\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1995-01-30\",\n      \"phone_number\": \"55 11 999550003\",\n      \"email\": \"carla.terceira@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515203\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert ONHOLD, prepare the full issuance)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const b = pm.response.json().booking;",
                          "",
                          "pm.test(\"booking.id matches\", () => {",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "",
                          "pm.test(\"booking is ONHOLD before any issuance\", () => {",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"ONHOLD\");",
                          "});",
                          "",
                          "pm.test(\"capability ticket is true, partial_issue is false before issuing\", () => {",
                          "    pm.expect(b.capabilities.ticket, \"capabilities.ticket\").to.equal(true);",
                          "    if (b.capabilities.partial_issue !== undefined) {",
                          "        pm.expect(b.capabilities.partial_issue, \"capabilities.partial_issue\").to.equal(false);",
                          "    }",
                          "});",
                          "",
                          "// Emissao TOTAL: todos os passageiros num unico FOP de cartao.",
                          "pm.test(\"points passenger_ids and booking_total at every passenger\", () => {",
                          "    const pax = b.passengers;",
                          "    pm.expect(pax, \"passengers\").to.have.lengthOf(3);",
                          "    const ids = pax.map(p => p.id);",
                          "    ids.forEach((id, i) => pm.expect(id, `passengers[${i}].id`).to.be.a(\"string\").and.not.empty);",
                          "",
                          "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                          "    const total = b.price && b.price.total;",
                          "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                          "    pm.environment.set(\"booking_total\", String(total));",
                          "",
                          "    // O passageiro do meio e o que tera o bilhete cancelado. Escolhido no meio",
                          "    // de proposito: primeiro ou ultimo mascarariam erro de indice em quem",
                          "    // percorre a lista.",
                          "    const target = pax[1];",
                          "    pm.environment.set(\"pax_to_cancel\", target.id);",
                          "    pm.environment.set(\"pax_to_cancel_name\", target.first_name);",
                          "    const targetTotal = (target.price && target.price.total) || 0;",
                          "    pm.expect(targetTotal, \"preco do passageiro alvo\").to.be.above(0);",
                          "    pm.environment.set(\"pax_to_cancel_total\", String(targetTotal));",
                          "",
                          "    pm.environment.set(\"ticket_numbers\", \"[]\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Ticket (Credit Card) — full issuance of all 3 passengers",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "",
                          "pm.test(\"issued exactly 3 tickets, one per passenger\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets.length, \"tickets.length\").to.equal(3);",
                          "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                          "});",
                          "",
                          "pm.test(\"records the ticket of the passenger that will be cancelled\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    const targetName = pm.environment.get(\"pax_to_cancel_name\");",
                          "    const target = tickets.find(t => t.passenger && t.passenger.first_name === targetName);",
                          "    pm.expect(target, `bilhete de ${targetName}`).to.not.be.undefined;",
                          "    pm.environment.set(\"cancelled_ticket_number\", target.number);",
                          "    pm.environment.set(\"number\", target.number);",
                          "",
                          "    // Acumulador da limpeza: os dois que NAO serao cancelados aqui. O bilhete",
                          "    // do alvo entra depois, na nova emissao, com o numero novo.",
                          "    const others = tickets.filter(t => t.number !== target.number).map(t => t.number);",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(others.sort().reverse()));",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      }\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert TICKETED before the cancellation)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const b = pm.response.json().booking;",
                          "",
                          "pm.test(\"booking is TICKETED after the full issuance\", () => {",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                          "});",
                          "",
                          "pm.test(\"every passenger holds a ticket\", () => {",
                          "    const without = b.passengers.filter(p => (p.tickets || []).length === 0);",
                          "    pm.expect(without.map(p => p.id), \"passengers without a ticket\").to.be.empty;",
                          "});",
                          "",
                          "pm.test(\"no partial issue warning while the booking is whole\", () => {",
                          "    const w = (b.warnings || []).find(x => String(x.type).includes(\"PARTIAL_ISSUED\"));",
                          "    pm.expect(w, \"partial issued warning\").to.be.undefined;",
                          "    pm.expect(b.capabilities.partial_issue, \"capabilities.partial_issue\").to.equal(false);",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Delete Ticket (cancels ONLY the middle passenger's ticket)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "exec": [
                          "// Ao contrario do loop de limpeza no fim do flow, aqui e um cancelamento",
                          "// unico e deliberado: o bilhete do passageiro do meio. E o que devolve a",
                          "// reserva ao estado parcialmente emitido.",
                          "const number = pm.environment.get(\"cancelled_ticket_number\");",
                          "if (!number) {",
                          "    throw new Error(\"cancelled_ticket_number vazio - a emissao total nao registrou o bilhete alvo.\");",
                          "}",
                          "pm.environment.set(\"number\", number);"
                        ],
                        "type": "text/javascript"
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Ticket (assert the cancelled one is CANCELLED)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "exec": [
                          "pm.environment.set(\"number\", pm.environment.get(\"cancelled_ticket_number\"));"
                        ],
                        "type": "text/javascript"
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] is CANCELLED\", () => {",
                          "    pm.expect(pm.response.json().ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert PENDING + partial warning after the cancellation)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const b = pm.response.json().booking;",
                          "",
                          "// Este e o passo que o cenario existe para exercitar. Cancelar UM bilhete de",
                          "// uma reserva TICKETED tem que devolve-la ao estado parcialmente emitido — o",
                          "// api-booking chega nisso filtrando os bilhetes por confirmedTktStatus em",
                          "// defineFlightBookingStatus, e nao contando quantos bilhetes existem.",
                          "pm.test(\"booking went back to PENDING after one ticket was cancelled\", () => {",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"PENDING\");",
                          "});",
                          "",
                          "pm.test(\"BOOKING_PARTIAL_ISSUED warning is back, with its action\", () => {",
                          "    const w = (b.warnings || []).find(x => String(x.type).includes(\"PARTIAL_ISSUED\"));",
                          "    pm.expect(w, \"partial issued warning\").to.not.be.undefined;",
                          "    pm.expect(JSON.stringify(w.actions || []), \"warning.actions\").to.include(\"PARTIAL_ISSUE\");",
                          "});",
                          "",
                          "pm.test(\"capability partial_issue unlocks a new issuance for that passenger\", () => {",
                          "    pm.expect(b.capabilities.partial_issue, \"capabilities.partial_issue\").to.equal(true);",
                          "});",
                          "",
                          "// A reserva esta em PENDING, entao isOnHold e falso. Sem o OR com partialIssue",
                          "// na capability Ticket, o api-order recusaria a ordem — e antes disso morreria",
                          "// no retry do GetBooking, porque bookingProviderError trata ticket=false com",
                          "// warning presente como reserva defeituosa.",
                          "pm.test(\"capability ticket still allows a new issuance\", () => {",
                          "    pm.expect(b.capabilities.ticket, \"capabilities.ticket\").to.equal(true);",
                          "});",
                          "",
                          "// NOTA: PaxTicket nao expoe status no contrato REST, entao a resposta da",
                          "// reserva NAO permite distinguir bilhete cancelado de valido — o passageiro",
                          "// alvo continua listando o bilhete cancelado em tickets[]. Quem precisa do",
                          "// status tem que chamar GET /tickets/{number}, como o passo anterior faz. E a",
                          "// mesma lacuna do Passenger.Ticket.ticket_status registrada no api-ticketing.",
                          "pm.test(\"the target passenger still lists the cancelled ticket (status is not exposed here)\", () => {",
                          "    const target = b.passengers.find(p => p.id === pm.environment.get(\"pax_to_cancel\"));",
                          "    pm.expect(target, \"passageiro alvo\").to.not.be.undefined;",
                          "    const numbers = (target.tickets || []).map(t => t.number);",
                          "    pm.expect(numbers, \"tickets do alvo\").to.include(pm.environment.get(\"cancelled_ticket_number\"));",
                          "});",
                          "",
                          "pm.test(\"points passenger_ids and booking_total at the cancelled passenger\", () => {",
                          "    pm.environment.set(\"passenger_ids\", JSON.stringify([pm.environment.get(\"pax_to_cancel\")]));",
                          "    pm.environment.set(\"booking_total\", pm.environment.get(\"pax_to_cancel_total\"));",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Ticket (Credit Card) — issue the cancelled passenger again",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "",
                          "pm.test(\"issued exactly 1 ticket, for the cancelled passenger only\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets.length, \"tickets.length\").to.equal(1);",
                          "    const targetName = pm.environment.get(\"pax_to_cancel_name\");",
                          "    pm.expect(tickets[0].passenger.first_name, \"passageiro do bilhete novo\").to.equal(targetName);",
                          "});",
                          "",
                          "// O bilhete cancelado nao pode ser reaproveitado: a companhia emite documento",
                          "// novo. Se vier igual, alguem devolveu o bilhete antigo em vez de emitir.",
                          "pm.test(\"the new ticket number differs from the cancelled one\", () => {",
                          "    const issued = pm.response.json().tickets[0].number;",
                          "    pm.expect(issued).to.not.equal(pm.environment.get(\"cancelled_ticket_number\"));",
                          "    const acc = JSON.parse(pm.environment.get(\"ticket_numbers\") || \"[]\");",
                          "    acc.push(issued);",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(acc.sort().reverse()));",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      }\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert TICKETED again, warning gone)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const b = pm.response.json().booking;",
                          "",
                          "pm.test(\"booking is TICKETED again after the new issuance\", () => {",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                          "});",
                          "",
                          "pm.test(\"BOOKING_PARTIAL_ISSUED warning is gone\", () => {",
                          "    const w = (b.warnings || []).find(x => String(x.type).includes(\"PARTIAL_ISSUED\"));",
                          "    pm.expect(w, \"partial issued warning\").to.be.undefined;",
                          "    pm.expect(b.capabilities.partial_issue, \"capabilities.partial_issue\").to.equal(false);",
                          "});",
                          "",
                          "// O passageiro emitido de novo carrega DOIS documentos: o cancelado e o novo. Os",
                          "// outros dois seguem com um. E a checagem que distingue \"emitiu de novo\" de",
                          "// \"reaproveitou o bilhete antigo\".",
                          "pm.test(\"the passenger issued again holds two tickets, the others one\", () => {",
                          "    const targetId = pm.environment.get(\"pax_to_cancel\");",
                          "    b.passengers.forEach(p => {",
                          "        const n = (p.tickets || []).length;",
                          "        if (p.id === targetId) {",
                          "            pm.expect(n, `tickets de ${p.first_name} (cancelado + o novo)`).to.equal(2);",
                          "        } else {",
                          "            pm.expect(n, `tickets de ${p.first_name}`).to.equal(1);",
                          "        }",
                          "    });",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Delete Ticket (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "exec": [
                          "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                          "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                          "}",
                          "// On first iteration, save full list for the Get Ticket loop",
                          "const savedRaw = pm.environment.get('get_ticket_numbers');",
                          "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                          "if (saved.length === 0) {",
                          "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                        ],
                        "type": "text/javascript"
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "} else {",
                          "    // proceed to the next request in the folder",
                          "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                          "}"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "exec": [
                          "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                        ],
                        "type": "text/javascript"
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                          "});",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "}"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Cancel Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert CANCELLED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is CANCELLED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"CANCELLED\");",
                          "});"
                        ],
                        "type": "text/javascript"
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                }
              ]
            },
            {
              "name": "Round-trip 2 ADT — Ticketfull (GOL) | Seat On-Hold + Partial Issue (1 then 1) | Credit Card",
              "item": [
                {
                  "name": "Auth - Access Token",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "const addDays = (n) => {",
                          "    const d = new Date();",
                          "    d.setDate(d.getDate() + n);",
                          "    return d.toISOString().split('T')[0];",
                          "};",
                          "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                          "pm.environment.set('date_2', addDays(19));  // inbound source",
                          "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                          "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves access_token and refresh_token\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.access_token, \"access_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"access_token\", body.access_token);",
                          "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/oauth/token",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "oauth",
                        "token"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Offers",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves slice_token_1 (outbound) and slice_token_2 (return)\", () => {",
                          "    // Round-trip offers have 2 journeys: [0] = outbound, [1] = return.",
                          "    // The first slice of each journey carries the token we need.",
                          "    const offers = pm.response.json().offers;",
                          "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                          "    const journeys = offers[0].journeys;",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    const outbound = journeys[0].slices[0].token;",
                          "    const inbound  = journeys[1].slices[0].token;",
                          "    pm.expect(outbound, \"outbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.expect(inbound,  \"inbound token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"slice_token_1\", outbound);",
                          "    pm.environment.set(\"slice_token_2\", inbound);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers?adts=2&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers"
                      ],
                      "query": [
                        {
                          "key": "adts",
                          "value": "2"
                        },
                        {
                          "key": "chds",
                          "value": "0"
                        },
                        {
                          "key": "infs",
                          "value": "0"
                        },
                        {
                          "key": "provider_type",
                          "value": "GOL"
                        },
                        {
                          "key": "route",
                          "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                        }
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Price Offer",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"saves priced tokens for Create Booking\", () => {",
                          "    const journeys = pm.response.json().offer.journeys || [];",
                          "    pm.expect(journeys.length, \"at least one journey\").to.be.above(0);",
                          "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                          "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                          "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "offers",
                        "price?slice_tokens={{slice_token_1}},{{slice_token_2}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "pm.test(\"saves booking_id and locator\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"booking_id\", b.id);",
                          "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"Jane\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"1992-03-20\",\n      \"phone_number\": \"55 11 999559998\",\n      \"email\": \"jane@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515200\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert ONHOLD, save pax and legs)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is ONHOLD\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"ONHOLD\");",
                          "});",
                          "// ── Save everything Create Ticket needs, so its request body stays explicit ──",
                          "pm.test(\"saves booking_total from booking.price.total\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    const total = b && b.price && b.price.total;",
                          "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                          "    pm.environment.set(\"booking_total\", String(total));",
                          "});",
                          "pm.test(\"saves passenger_ids as JSON array for inline body substitution\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    const ids = passengers.map(p => p.id).filter(Boolean);",
                          "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                          "    // Store as a JSON array literal so {{passenger_ids}} expands inline in the request body.",
                          "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                          "});",
                          "pm.test(\"saves ticket_numbers for Delete Ticket steps\", () => {",
                          "    const passengers = pm.response.json().booking.passengers || [];",
                          "    const numbers = [];",
                          "    passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                          "    numbers.sort().reverse();",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                          "    if (numbers.length > 0) pm.environment.set(\"number\", numbers[0]);",
                          "});",
                          "pm.test(\"saves slice and leg ids for ancillary requests\", () => {",
                          "    const slices = pm.response.json().booking.slices || [];",
                          "    pm.expect(slices.length, \"round-trip must have 2 slices\").to.be.at.least(2);",
                          "    pm.environment.set(\"slice_id_1\", slices[0].id);",
                          "    pm.environment.set(\"slice_id_2\", slices[1].id);",
                          "    pm.expect(slices[0].legs, \"outbound legs\").to.be.an(\"array\").and.not.empty;",
                          "    pm.expect(slices[1].legs, \"return legs\").to.be.an(\"array\").and.not.empty;",
                          "    pm.environment.set(\"leg_id_1\", slices[0].legs[0].id);",
                          "    pm.environment.set(\"leg_id_2\", slices[1].legs[0].id);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Seat Map",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "// Este cenario existe para exercitar emissao parcial COM ancillary pago, entao",
                          "// assento sem preco nao serve. Sem esta exigencia o flow seguia adiante,",
                          "// selecionava assento gratuito e terminava verde sem ter testado nada de",
                          "// ancillary: a reserva chegava na emissao sem extras e o ChargeSeat nem era",
                          "// chamado.",
                          "//",
                          "// Quando falhar, o motivo costuma estar no itinerario, nao no codigo. Mapa de",
                          "// assento e recusado em voo codeshare (marketing != operating carrier, ver",
                          "// validateGetSeatMapRequest no api-extras), e ha rota que simplesmente nao",
                          "// vende assento. Troque a rota do Get Offers.",
                          "pm.test(\"saves paid seat tokens: one per passenger\", () => {",
                          "    const cabins = (pm.response.json().seat_map || {}).cabins || [];",
                          "    pm.expect(cabins, \"cabins\").to.be.an(\"array\").and.not.empty;",
                          "",
                          "    const elements = [];",
                          "    for (const cabin of cabins)",
                          "        for (const row of cabin.rows || [])",
                          "            for (const section of row.sections || [])",
                          "                for (const elem of section.elements || [])",
                          "                    if ((elem.available_services || []).length > 0)",
                          "                        elements.push(elem);",
                          "",
                          "    // passenger_ids foi salvo pelo Get Booking (assert ONHOLD) como array JSON.",
                          "    const paxIds = JSON.parse(pm.environment.get(\"passenger_ids\") || \"[]\");",
                          "    pm.expect(paxIds.length, \"passenger_ids\").to.equal(2);",
                          "",
                          "    // Cada elemento carrega um service por passageiro; o preco vive no service.",
                          "    const paidServiceFor = (elem, paxId) => (elem.available_services || [])",
                          "        .find(s => s.passenger_id === paxId && s.price && Number(s.price.amount) > 0);",
                          "",
                          "    const elem1 = elements.find(e => paidServiceFor(e, paxIds[0]));",
                          "    const elem2 = elements.find(e => e !== elem1 && paidServiceFor(e, paxIds[1]));",
                          "",
                          "    pm.expect(elem1, \"assento pago para o passageiro 1 (itinerario sem assento pago?)\").to.exist;",
                          "    pm.expect(elem2, \"assento pago para o passageiro 2 (itinerario sem assento pago?)\").to.exist;",
                          "",
                          "    const svc1 = paidServiceFor(elem1, paxIds[0]);",
                          "    const svc2 = paidServiceFor(elem2, paxIds[1]);",
                          "",
                          "    pm.environment.set(\"seat_token_pax1_leg1\", svc1.token);",
                          "    pm.environment.set(\"seat_token_pax2_leg1\", svc2.token);",
                          "    pm.environment.set(\"seat_ancillary_total\", Number(svc1.price.amount) + Number(svc2.price.amount));",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}/legs/{{leg_id_1}}/seat-map",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}",
                        "legs",
                        "{{leg_id_1}}",
                        "seat-map"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Select Seat (both passengers, on-hold)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "",
                          "pm.test(\"seat selection successful for both passengers\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.success, \"success\").to.be.true;",
                          "    pm.expect(body.seat_ancillaries, \"seat_ancillaries\").to.be.an(\"array\").and.not.empty;",
                          "});",
                          "",
                          "// O preco do assento por passageiro so aparece AQUI. A reserva expoe",
                          "// price.total_extras agregado e nada por passageiro, entao sem guardar agora",
                          "// nao ha como montar o total de cada emissao parcial mais adiante.",
                          "pm.test(\"saves the seat price of each passenger\", () => {",
                          "    const anc = pm.response.json().seat_ancillaries || [];",
                          "    const paxIds = JSON.parse(pm.environment.get(\"passenger_ids\") || \"[]\");",
                          "    pm.expect(paxIds.length, \"passenger_ids\").to.equal(2);",
                          "",
                          "    paxIds.forEach((id, i) => {",
                          "        const mine = anc.filter(a => a.passenger_id === id);",
                          "        pm.expect(mine.length, `assentos do passageiro ${i + 1}`).to.be.above(0);",
                          "        const total = mine.reduce((sum, a) => sum + Number((a.price || {}).amount || 0), 0);",
                          "        pm.expect(total, `preco do assento do passageiro ${i + 1}`).to.be.above(0);",
                          "        pm.environment.set(`seat_total_pax_${i + 1}`, String(total));",
                          "    });",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "POST",
                    "header": [],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"legs\": [\n    {\n      \"leg_id\": \"{{leg_id_1}}\",\n      \"seat_tokens\": [\"{{seat_token_pax1_leg1}}\", \"{{seat_token_pax2_leg1}}\"]\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    },
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}/seats",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}",
                        "seats"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert extras > 0, split into two emission groups)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const b = pm.response.json().booking;",
                          "",
                          "pm.test(\"booking.price.total_extras is greater than 0 after seat selection\", () => {",
                          "    pm.expect((b.price || {}).total_extras, \"booking.price.total_extras\").to.be.a(\"number\").and.above(0);",
                          "});",
                          "",
                          "pm.test(\"capability ticket is true, partial_issue is false before issuing\", () => {",
                          "    pm.expect(b.capabilities.ticket, \"capabilities.ticket\").to.equal(true);",
                          "    if (b.capabilities.partial_issue !== undefined) {",
                          "        pm.expect(b.capabilities.partial_issue, \"capabilities.partial_issue\").to.equal(false);",
                          "    }",
                          "});",
                          "",
                          "// O assento marcado tem que aparecer no extras do passageiro. E este numero",
                          "// que entra em price.total logo abaixo, entao se ele nao chegar aqui o total",
                          "// da emissao sai sem o assento e o api-order recusa a ordem.",
                          "pm.test(\"each passenger carries the price of its own seat in extras\", () => {",
                          "    const pax = b.passengers || [];",
                          "    pm.expect(pax, \"passengers\").to.have.lengthOf(2);",
                          "",
                          "    pax.forEach((p, i) => {",
                          "        const seat = Number(pm.environment.get(`seat_total_pax_${i + 1}`));",
                          "        pm.expect(Number((p.price || {}).extras), `extras do passageiro ${i + 1}`).to.be.closeTo(seat, 0.02);",
                          "    });",
                          "});",
                          "",
                          "// Cada emissao paga UM passageiro. O total do FOP e o price.total dele, que JA",
                          "// contempla os extras — somar o assento de novo aqui cobraria em dobro. O",
                          "// numero sem extras e o price_per_pax[].total, que nao serve para este fim.",
                          "pm.test(\"splits the booking into two single-passenger emission groups\", () => {",
                          "    const pax = b.passengers || [];",
                          "    const ids = pax.map(p => p.id);",
                          "    ids.forEach((id, i) => pm.expect(id, `passengers[${i}].id`).to.be.a(\"string\").and.not.empty);",
                          "",
                          "    const total1 = Number((pax[0].price || {}).total);",
                          "    const total2 = Number((pax[1].price || {}).total);",
                          "    pm.expect(total1, \"price.total do passageiro 1\").to.be.above(0);",
                          "    pm.expect(total2, \"price.total do passageiro 2\").to.be.above(0);",
                          "",
                          "    pm.environment.set(\"group_1_ids\", JSON.stringify([ids[0]]));",
                          "    pm.environment.set(\"group_2_ids\", JSON.stringify([ids[1]]));",
                          "    pm.environment.set(\"pax_1_id\", ids[0]);",
                          "    pm.environment.set(\"pax_2_id\", ids[1]);",
                          "    pm.environment.set(\"total_group_1\", String(total1));",
                          "    pm.environment.set(\"total_group_2\", String(total2));",
                          "",
                          "    // A primeira emissao comeca apontada para o grupo 1.",
                          "    pm.environment.set(\"passenger_ids\", pm.environment.get(\"group_1_ids\"));",
                          "    pm.environment.set(\"ticket_numbers\", \"[]\");",
                          "});",
                          "",
                          "// Rede de seguranca: os dois grupos tem que fechar o total da reserva. Foi",
                          "// esta assercao que denunciaria o assento contado duas vezes.",
                          "pm.test(\"the two groups add up to the booking total\", () => {",
                          "    const sum = Number(pm.environment.get(\"total_group_1\")) + Number(pm.environment.get(\"total_group_2\"));",
                          "    pm.expect(sum, \"soma dos dois grupos\").to.be.closeTo(Number((b.price || {}).total), 0.02);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Installments (plan for emission 1 — passenger 1 only)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// /installments recebe passenger_ids como lista separada por virgula, enquanto",
                          "// {{passenger_ids}} e um array JSON porque o Create Ticket o interpola direto no",
                          "// corpo. A forma CSV e derivada aqui para nao manter duas variaveis na mao.",
                          "const raw = pm.environment.get(\"passenger_ids\");",
                          "if (!raw) {",
                          "    throw new Error(\"passenger_ids esta vazio - rode o passo que divide os grupos de emissao antes.\");",
                          "}",
                          "pm.environment.set(\"passenger_ids_csv\", JSON.parse(raw).join(\",\"));"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const plans = pm.response.json().installment_plans || [];",
                          "",
                          "pm.test(\"saves plan_token for the single-installment plan\", () => {",
                          "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                          "    const plan1 = plans.find(p => p.installment === 1) || plans[0];",
                          "    pm.expect(plan1.plan_token, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"plan_token\", plan1.plan_token);",
                          "});",
                          "",
                          "// Este e o ponto que este cenario existe para exercitar, e a regressao que ele",
                          "// guarda.",
                          "//",
                          "// O guruapi mandava ao api-payment todos os ancillaries da reserva",
                          "// independente da selecao (convertToAncillaries). Com assento para os DOIS",
                          "// passageiros e emissao de so UM, o plano cobria tambem o assento de quem",
                          "// ficou de fora e o total do plano passava do total da selecao — e o",
                          "// plan_token levava desconto e OB fee de um valor que ninguem ia cobrar, com",
                          "// o api-order recusando a ordem em seguida.",
                          "//",
                          "// Agora os ancillaries seguem a mesma selecao dos passageiros. Se esta",
                          "// assercao voltar a falhar, o filtro se perdeu.",
                          "pm.test(\"the plan covers only the selection, not the whole booking\", () => {",
                          "    const plan1 = plans.find(p => p.installment === 1) || plans[0];",
                          "    const selectionTotal = Number(pm.environment.get(\"total_group_1\"));",
                          "    pm.expect(Number(plan1.total), \"installment_plans[].total\").to.be.closeTo(selectionTotal, 0.02);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/installments?creditcard_bin=555544&booking_id={{booking_id}}&passenger_ids={{passenger_ids_csv}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "installments"
                      ],
                      "query": [
                        {
                          "key": "creditcard_bin",
                          "value": "555544"
                        },
                        {
                          "key": "booking_id",
                          "value": "{{booking_id}}"
                        },
                        {
                          "key": "passenger_ids",
                          "value": "{{passenger_ids_csv}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Ticket (Credit Card) — emission 1: passenger 1 only (PARTIAL)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "",
                          "// A reserva tem assento para os dois passageiros, mas so um esta sendo pago.",
                          "// Dois bilhetes aqui significariam que o provider ignorou a selecao e emitiu o",
                          "// PNR inteiro.",
                          "pm.test(\"issued exactly 1 ticket, for passenger 1\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets.length, \"tickets.length (2 significaria PNR inteiro)\").to.equal(1);",
                          "    pm.expect(tickets[0].number, \"tickets[0].number\").to.be.a(\"string\").and.not.empty;",
                          "});",
                          "",
                          "pm.test(\"accumulates ticket numbers for the cleanup loop\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    const acc = JSON.parse(pm.environment.get(\"ticket_numbers\") || \"[]\");",
                          "    tickets.forEach(t => acc.push(t.number));",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(acc.sort().reverse()));",
                          "    pm.environment.set(\"number\", tickets[0].number);",
                          "    pm.environment.set(\"tickets_emission_1\", JSON.stringify(tickets.map(t => t.number)));",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{total_group_1}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555444433331111\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{plan_token}}\"\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert PENDING + partial warning, prepare emission 2)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const b = pm.response.json().booking;",
                          "",
                          "pm.test(\"booking is PENDING after a partial emission\", () => {",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"PENDING\");",
                          "});",
                          "",
                          "pm.test(\"passenger 1 holds a ticket and passenger 2 does not\", () => {",
                          "    const p1 = b.passengers.find(p => p.id === pm.environment.get(\"pax_1_id\"));",
                          "    const p2 = b.passengers.find(p => p.id === pm.environment.get(\"pax_2_id\"));",
                          "    pm.expect(p1, \"passageiro 1\").to.not.be.undefined;",
                          "    pm.expect(p2, \"passageiro 2\").to.not.be.undefined;",
                          "    pm.expect((p1.tickets || []).length, \"bilhetes do passageiro 1\").to.be.above(0);",
                          "    pm.expect((p2.tickets || []).length, \"bilhetes do passageiro 2\").to.equal(0);",
                          "});",
                          "",
                          "// O assento do passageiro 2 nao pode sumir porque o bilhete dele ainda nao foi",
                          "// emitido: ele foi marcado com a reserva on-hold e sobrevive a emissao parcial.",
                          "pm.test(\"the extras of both passengers survive the partial emission\", () => {",
                          "    pm.expect((b.price || {}).total_extras, \"booking.price.total_extras\").to.be.a(\"number\").and.above(0);",
                          "});",
                          "",
                          "pm.test(\"BOOKING_PARTIAL_ISSUED warning is present, with its action\", () => {",
                          "    const w = (b.warnings || []).find(x => String(x.type).includes(\"PARTIAL_ISSUED\"));",
                          "    pm.expect(w, \"partial issued warning\").to.not.be.undefined;",
                          "    pm.expect(JSON.stringify(w.actions || []), \"warning.actions\").to.include(\"PARTIAL_ISSUE\");",
                          "});",
                          "",
                          "pm.test(\"capabilities allow re-entering the issuance\", () => {",
                          "    pm.expect(b.capabilities.partial_issue, \"capabilities.partial_issue\").to.equal(true);",
                          "    pm.expect(b.capabilities.ticket, \"capabilities.ticket\").to.equal(true);",
                          "});",
                          "",
                          "// Aponta a proxima emissao para o grupo 2.",
                          "pm.test(\"points the next emission at passenger 2\", () => {",
                          "    pm.environment.set(\"passenger_ids\", pm.environment.get(\"group_2_ids\"));",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Installments (plan for emission 2 — passenger 2 only)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// /installments recebe passenger_ids como lista separada por virgula, enquanto",
                          "// {{passenger_ids}} e um array JSON porque o Create Ticket o interpola direto no",
                          "// corpo. A forma CSV e derivada aqui para nao manter duas variaveis na mao.",
                          "const raw = pm.environment.get(\"passenger_ids\");",
                          "if (!raw) {",
                          "    throw new Error(\"passenger_ids esta vazio - rode o passo que divide os grupos de emissao antes.\");",
                          "}",
                          "pm.environment.set(\"passenger_ids_csv\", JSON.parse(raw).join(\",\"));"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const plans = pm.response.json().installment_plans || [];",
                          "",
                          "pm.test(\"saves plan_token for the single-installment plan\", () => {",
                          "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                          "    const plan1 = plans.find(p => p.installment === 1) || plans[0];",
                          "    pm.expect(plan1.plan_token, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                          "    pm.environment.set(\"plan_token\", plan1.plan_token);",
                          "});",
                          "",
                          "// Este e o ponto que este cenario existe para exercitar, e a regressao que ele",
                          "// guarda.",
                          "//",
                          "// O guruapi mandava ao api-payment todos os ancillaries da reserva",
                          "// independente da selecao (convertToAncillaries). Com assento para os DOIS",
                          "// passageiros e emissao de so UM, o plano cobria tambem o assento de quem",
                          "// ficou de fora e o total do plano passava do total da selecao — e o",
                          "// plan_token levava desconto e OB fee de um valor que ninguem ia cobrar, com",
                          "// o api-order recusando a ordem em seguida.",
                          "//",
                          "// Agora os ancillaries seguem a mesma selecao dos passageiros. Se esta",
                          "// assercao voltar a falhar, o filtro se perdeu.",
                          "pm.test(\"the plan covers only the selection, not the whole booking\", () => {",
                          "    const plan1 = plans.find(p => p.installment === 1) || plans[0];",
                          "    const selectionTotal = Number(pm.environment.get(\"total_group_2\"));",
                          "    pm.expect(Number(plan1.total), \"installment_plans[].total\").to.be.closeTo(selectionTotal, 0.02);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/installments?creditcard_bin=555544&booking_id={{booking_id}}&passenger_ids={{passenger_ids_csv}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "installments"
                      ],
                      "query": [
                        {
                          "key": "creditcard_bin",
                          "value": "555544"
                        },
                        {
                          "key": "booking_id",
                          "value": "{{booking_id}}"
                        },
                        {
                          "key": "passenger_ids",
                          "value": "{{passenger_ids_csv}}"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Create Ticket (Credit Card) — emission 2: passenger 2 (COMPLETES)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                          "",
                          "// Cartao de credito nas duas emissoes de proposito: o cenario anterior ja cobre",
                          "// a troca de forma de pagamento entre elas, aqui o que interessa e o cartao",
                          "// duas vezes na mesma reserva, cada um rateado sobre a sua propria selecao.",
                          "pm.test(\"issued exactly 1 ticket, for passenger 2\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    pm.expect(tickets.length, \"tickets.length\").to.equal(1);",
                          "    pm.expect(tickets[0].number, \"tickets[0].number\").to.be.a(\"string\").and.not.empty;",
                          "});",
                          "",
                          "// O CreateTicket tem que devolver SO o bilhete novo. Devolver tambem o da",
                          "// primeira emissao faz o backoffice recusar com \"ticket already exists in",
                          "// backoffice\" — foi o defeito da GOL (d9pq58ja0tec738lr52g) e do Amadeus",
                          "// (d9tnk5ra0tec738lsdt0).",
                          "pm.test(\"the second emission returns only the new ticket\", () => {",
                          "    const issued = (pm.response.json().tickets || []).map(t => t.number);",
                          "    const first = JSON.parse(pm.environment.get(\"tickets_emission_1\") || \"[]\");",
                          "    issued.forEach(n => pm.expect(first, \"numeros emitidos pela emissao 1\").to.not.include(n));",
                          "});",
                          "",
                          "pm.test(\"accumulates ticket numbers for the cleanup loop\", () => {",
                          "    const tickets = pm.response.json().tickets || [];",
                          "    const acc = JSON.parse(pm.environment.get(\"ticket_numbers\") || \"[]\");",
                          "    tickets.forEach(t => acc.push(t.number));",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(acc.sort().reverse()));",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    },
                    "method": "POST",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json",
                        "type": "text"
                      }
                    ],
                    "url": {
                      "raw": "{{url}}/tickets",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets"
                      ]
                    },
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{total_group_2}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555444433331111\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{plan_token}}\"\n    }\n  ]\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert TICKETED, warning gone)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "",
                          "const b = pm.response.json().booking;",
                          "",
                          "pm.test(\"booking is TICKETED once every passenger holds a ticket\", () => {",
                          "    pm.expect(b.booking_status, \"booking.status\").to.equal(\"TICKETED\");",
                          "});",
                          "",
                          "pm.test(\"the partial issue warning is gone\", () => {",
                          "    const w = (b.warnings || []).find(x => String(x.type).includes(\"PARTIAL_ISSUED\"));",
                          "    pm.expect(w, \"partial issued warning\").to.be.undefined;",
                          "});",
                          "",
                          "pm.test(\"capability partial_issue is back to false\", () => {",
                          "    pm.expect(b.capabilities.partial_issue, \"capabilities.partial_issue\").to.equal(false);",
                          "});",
                          "",
                          "// Cada passageiro sai com DOIS documentos: o bilhete do trecho e o documento",
                          "// do assento que ele comprou. Contar so o total mascararia o caso ruim — duas",
                          "// emissoes do mesmo passageiro tambem dariam 4 — entao a conferencia e por",
                          "// tipo.",
                          "pm.test(\"each passenger holds one flight ticket and one ancillary document\", () => {",
                          "    b.passengers.forEach((p, i) => {",
                          "        const tickets = p.tickets || [];",
                          "        const flightTickets = tickets.filter(t => String(t.ticket_type) === \"TICKET\");",
                          "        const ancillaryTickets = tickets.filter(t => String(t.ticket_type) !== \"TICKET\");",
                          "",
                          "        pm.expect(flightTickets.length, `bilhete de voo do passageiro ${i + 1}`).to.equal(1);",
                          "        pm.expect(ancillaryTickets.length, `documento de assento do passageiro ${i + 1}`).to.equal(1);",
                          "    });",
                          "});",
                          "",
                          "pm.test(\"collects every document for the cleanup loop\", () => {",
                          "    const numbers = [];",
                          "    b.passengers.forEach(p => (p.tickets || []).forEach(t => { if (t.number) numbers.push(t.number); }));",
                          "    pm.expect(numbers.length, \"total de documentos (2 voos + 2 assentos)\").to.equal(4);",
                          "    numbers.sort().reverse();",
                          "    pm.environment.set(\"ticket_numbers\", JSON.stringify(numbers));",
                          "    pm.environment.set(\"number\", numbers[0]);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Delete Ticket (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// Iterates ticket_numbers and cancels one ticket per iteration via setNextRequest.",
                          "// ticket_numbers is a JSON array populated by Get Booking / Create Ticket (descending order).",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('ticket_numbers is empty — ensure Get Booking/Create Ticket ran first.');",
                          "}",
                          "// On first iteration, save full list for the Get Ticket loop",
                          "const savedRaw = pm.environment.get('get_ticket_numbers');",
                          "const saved = savedRaw ? JSON.parse(savedRaw) : [];",
                          "if (saved.length === 0) {",
                          "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "} else {",
                          "    // proceed to the next request in the folder",
                          "    pm.execution.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                          "}"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// Iterates get_ticket_numbers and checks each ticket is CANCELED.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length === 0) {",
                          "    throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                          "}",
                          "const next = remaining.shift();",
                          "pm.environment.set('number', next);",
                          "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                          "    const body = pm.response.json();",
                          "    pm.expect(body.ticket_status, \"ticket.status\").to.equal(\"CANCELLED\");",
                          "});",
                          "// Loop: if there are still tickets left, repeat this request.",
                          "const raw = pm.environment.get('get_ticket_numbers');",
                          "const remaining = raw ? JSON.parse(raw) : [];",
                          "if (remaining.length > 0) {",
                          "    pm.execution.setNextRequest(pm.info.requestName);",
                          "}"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/tickets/{{number}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "tickets",
                        "{{number}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Cancel Booking",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                          "pm.test(\"response body is empty\", () => pm.expect(pm.response.text()).to.be.empty);"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "DELETE",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                },
                {
                  "name": "Get Booking (assert CANCELLED)",
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                          "pm.test(\"booking.id matches\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.id).to.equal(pm.environment.get(\"booking_id\"));",
                          "});",
                          "pm.test(\"booking status is CANCELLED\", () => {",
                          "    const b = pm.response.json().booking;",
                          "    pm.expect(b.booking_status, \"booking.booking_status\").to.equal(\"CANCELLED\");",
                          "});"
                        ]
                      }
                    }
                  ],
                  "request": {
                    "method": "GET",
                    "header": [],
                    "url": {
                      "raw": "{{url}}/bookings/{{booking_id}}",
                      "host": [
                        "{{url}}"
                      ],
                      "path": [
                        "bookings",
                        "{{booking_id}}"
                      ]
                    },
                    "auth": {
                      "type": "bearer",
                      "bearer": [
                        {
                          "key": "token",
                          "value": "{{access_token}}",
                          "type": "string"
                        }
                      ]
                    }
                  },
                  "response": []
                }
              ]
            }
          ],
          "id": "53022475-7423-4607-9795-8cdee5f3d4f2"
        },
        {
          "name": "Exchange",
          "item": [
            {
              "name": "new booking",
              "item": [
                {
                  "name": "Round-trip 1 ADT (GOL) | Exchange — new booking | Invoice",
                  "description": "Full exchange into new booking — Round-trip 1 ADT (GOL) issued via Invoice.\n\nFlow: creates and issues the SOURCE booking (SAO↔RIO, Jun-26) to obtain the tickets. Then creates a new booking booking (SAO↔RIO, Jul-26). POST /exchange/estimate obtains the new_slice_tokens and price breakdown. POST /exchange reissues the source tickets into the new booking. Cleanup: cancels source booking (source tickets become EXCHANGED after reissue).",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token).to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers (source: SAO→RIO + RIO→SAO)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 and slice_token_2 (fonte: SAO→RIO 2026-06-15 + RIO→SAO 2026-06-22)\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const journeys = offers[0].journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_3}}+RIO,SAO,{{date_4}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_3}}+RIO,SAO,{{date_4}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer (source)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens (fonte)\", () => {",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length).to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking (source)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves source_booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"source_booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});",
                              "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (source — save booking_total, passenger_ids)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves booking_total\", () => {",
                              "    const total = pm.response.json().booking?.price?.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids\", () => {",
                              "    const ids = (pm.response.json().booking.passengers || []).map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/bookings/{{source_booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{source_booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Ticket — Invoice (source)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets with numbers — saves ticket_numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // descending order: newer (higher) numbers must be cancelled first on reissue",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(tickets.map(t => t.number).sort().reverse()));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{source_booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}}\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (source — assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"TICKETED\");",
                              "});",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers (new booking: SAO→RIO + RIO→SAO)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"picks a round-trip offer more expensive than the source fare\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "",
                              "    const sourceTotal = Number(pm.environment.get(\"booking_total\")) || 0;",
                              "",
                              "    // resolve an offer's total price (defensive against response shape variations)",
                              "    const offerTotal = (o) => {",
                              "        if (o.price && typeof o.price.total === \"number\") return o.price.total;",
                              "        let sum = 0;",
                              "        (o.journeys || []).forEach(j => (j.slices || []).forEach(s => {",
                              "            if (s.price && typeof s.price.total === \"number\") sum += s.price.total;",
                              "        }));",
                              "        return sum;",
                              "    };",
                              "",
                              "    // round-trip offers only, sorted ascending by price",
                              "    const candidates = offers",
                              "        .filter(o => (o.journeys || []).length >= 2)",
                              "        .sort((a, b) => offerTotal(a) - offerTotal(b));",
                              "    pm.expect(candidates.length, \"round-trip offers\").to.be.above(0);",
                              "",
                              "    // cheapest offer strictly more expensive than the source fare,",
                              "    // so the reissue always yields a positive balance to charge",
                              "    const chosen = candidates.find(o => offerTotal(o) > sourceTotal);",
                              "    pm.expect(chosen, `an offer more expensive than source (${sourceTotal})`).to.not.be.undefined;",
                              "",
                              "    const journeys = chosen.journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer (new booking)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens (novo loc)\", () => {",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length).to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking (new booking)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});",
                              "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));",
                              "pm.test(\"saves new_booking_passenger_ids\", () => {",
                              "    const ids = (pm.response.json().booking.passengers || []).map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    pm.environment.set(\"new_booking_passenger_ids\", JSON.stringify(ids));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Exchange Estimate",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"response has an offer\", () => {",
                              "    pm.expect(pm.response.json().offer, \"offer\").to.be.an(\"object\");",
                              "});",
                              "pm.test(\"offer has id and expires_at\", () => {",
                              "    const o = pm.response.json().offer;",
                              "    pm.expect(o.id, \"offer.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.expect(o.expires_at, \"offer.expires_at\").to.be.a(\"string\").and.not.empty;",
                              "});",
                              "pm.test(\"offer has balance_price with total\", () => {",
                              "    const price = pm.response.json().offer.balance_price;",
                              "    pm.expect(price, \"balance_price\").to.be.an(\"object\");",
                              "    pm.expect(price.total, \"balance_price.total\").to.be.a(\"number\");",
                              "});",
                              "pm.test(\"offer has journeys array\", () => {",
                              "    pm.expect(pm.response.json().offer.journeys, \"offer.journeys\").to.be.an(\"array\").and.not.empty;",
                              "});",
                              "pm.test(\"saves new_slice_tokens from all slices\", () => {",
                              "    const offer = pm.response.json().offer;",
                              "    const tokens = [];",
                              "    (offer.journeys || []).forEach(j => {",
                              "        (j.slices || []).forEach(s => {",
                              "            if (s.balance_token) tokens.push(s.balance_token);",
                              "        });",
                              "    });",
                              "    pm.expect(tokens.length, \"at least one balance_token\").to.be.above(0);",
                              "    pm.environment.set(\"new_slice_tokens\", JSON.stringify(tokens));",
                              "});",
                              "pm.test(\"saves balance_price_total and total_tickets_credit_amount\", () => {",
                              "    const offer = pm.response.json().offer;",
                              "    pm.expect(offer.balance_price, \"balance_price\").to.be.an(\"object\");",
                              "    pm.environment.set(\"balance_price_total\", String(offer.balance_price.total));",
                              "    pm.expect(offer.total_tickets_credit_amount, \"total_tickets_credit_amount\").to.be.a(\"number\");",
                              "    pm.environment.set(\"total_tickets_credit_amount\", String(offer.total_tickets_credit_amount));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"ticket_numbers\": {{ticket_numbers}}\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/exchange/estimate",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "exchange",
                            "estimate"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Reissue Airline Tickets (POST /exchange)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns reissued tickets\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"reissued_number\", tickets[0].number);",
                              "    pm.environment.set(\"reissued_ticket_numbers\", JSON.stringify(tickets.map(t => t.number).sort().reverse()));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"new_slice_tokens\": {{new_slice_tokens}},\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"TICKET\",\n      \"tickets\": {{ticket_numbers}},\n      \"total\": {{total_tickets_credit_amount}},\n      \"passenger_ids\": {{new_booking_passenger_ids}}\n    },\n    {\n      \"fop_type\": \"INVOICE\",\n      \"total\": {{balance_price_total}},\n      \"passenger_ids\": {{new_booking_passenger_ids}}\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/exchange",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "exchange"
                          ]
                        },
                        "description": "Reissues tickets from source booking into the new booking booking. Uses new_slice_tokens and total_tickets_credit_amount from the Exchange Estimate step."
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (reissued — assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/tickets/{{reissued_number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{reissued_number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "id": "c28b5421-7b2c-488e-a72c-eea65d8b4836",
                      "name": "Delete Ticket — new booking (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const raw = pm.environment.get('reissued_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) throw new Error('reissued_ticket_numbers is empty — ensure Reissue ran first.');",
                              "const savedRaw = pm.environment.get('get_reissued_ticket_numbers');",
                              "if (!savedRaw || JSON.parse(savedRaw).length === 0) {",
                              "    pm.environment.set('get_reissued_ticket_numbers', JSON.stringify([...remaining]));",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('reissued_ticket_numbers', JSON.stringify(remaining));"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "const remaining = JSON.parse(pm.environment.get('reissued_ticket_numbers') || '[]');",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "} else {",
                              "    pm.execution.setNextRequest(\"Get Ticket — new booking (assert CANCELED) (loop per ticket — descending order)\");",
                              "}"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "id": "a4dcc2c9-8b20-4a01-a35b-d1c341704fa6",
                      "name": "Get Ticket — new booking (assert CANCELED) (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const raw = pm.environment.get('get_reissued_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) throw new Error('get_reissued_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('get_reissued_ticket_numbers', JSON.stringify(remaining));"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"CANCELLED\");",
                              "});",
                              "const remaining = JSON.parse(pm.environment.get('get_reissued_ticket_numbers') || '[]');",
                              "if (remaining.length > 0) pm.execution.setNextRequest(pm.info.requestName);"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "id": "58a7b1db-b9eb-4310-ba08-9233291dd226",
                      "name": "Cancel Booking (new booking)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "id": "0a731c95-0092-43fa-9bb2-25c79fb96edc",
                      "name": "Get Booking (new booking — assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking_status is CANCELLED\", () => {",
                              "    pm.expect(pm.response.json().booking.booking_status, \"booking_status\").to.equal(\"CANCELLED\");",
                              "});"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Delete Ticket — source (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) throw new Error('ticket_numbers is empty — ensure Create Ticket ran first.');",
                              "const savedRaw = pm.environment.get('get_ticket_numbers');",
                              "if (!savedRaw || JSON.parse(savedRaw).length === 0) {",
                              "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "const remaining = JSON.parse(pm.environment.get('ticket_numbers') || '[]');",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "} else {",
                              "    pm.execution.setNextRequest(\"Get Ticket — source (assert CANCELED) (loop per ticket — descending order)\");",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "DELETE",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket — source (assert CANCELED) (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"CANCELLED\");",
                              "});",
                              "const remaining = JSON.parse(pm.environment.get('get_ticket_numbers') || '[]');",
                              "if (remaining.length > 0) pm.execution.setNextRequest(pm.info.requestName);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking (source)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "DELETE",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/bookings/{{source_booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{source_booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (source — assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking_status is CANCELLED\", () => {",
                              "    pm.expect(pm.response.json().booking.booking_status, \"booking_status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/bookings/{{source_booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{source_booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ]
                },
                {
                  "name": "Round-trip 1 ADT 1 CHD 1 INF (GOL) | Exchange  — new booking | Credit Card",
                  "description": "Full exchange into new booking — Round-trip 1 ADT (GOL) issued via Invoice.\n\nFlow: creates and issues the SOURCE booking (SAO↔RIO, Jun-26) to obtain the tickets. Then creates a new booking booking (SAO↔RIO, Jul-26). POST /exchange/estimate obtains the new_slice_tokens and price breakdown. POST /exchange reissues the source tickets into the new booking. Cleanup: cancels source booking (source tickets become EXCHANGED after reissue).",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves access_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token).to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers (source: SAO→RIO + RIO→SAO)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves slice_token_1 and slice_token_2 (fonte: SAO→RIO 2026-06-15 + RIO→SAO 2026-06-22)\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const journeys = offers[0].journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=1&infs=1&provider_type=GOL&route=SAO,RIO,{{date_3}}+RIO,SAO,{{date_4}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "1"
                            },
                            {
                              "key": "infs",
                              "value": "1"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_3}}+RIO,SAO,{{date_4}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer (source)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens (fonte)\", () => {",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length).to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking (source)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves source_booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"source_booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});",
                              "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"CHD\",\n      \"first_name\": \"Alice\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"2018-07-10\",\n      \"phone_number\": \"55 11 999559998\",\n      \"email\": \"alice@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"39053344705\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"INF\",\n      \"first_name\": \"Sam\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"2024-11-01\",\n      \"phone_number\": \"55 11 999559997\",\n      \"email\": \"sam@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"24843803480\",\n          \"type\": \"CPF\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (source — save booking_total, passenger_ids)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves booking_total\", () => {",
                              "    const total = pm.response.json().booking?.price?.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids\", () => {",
                              "    const ids = (pm.response.json().booking.passengers || []).map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves booking_token (CSV of slice tokens) for Get Installments\", () => {",
                              "    const slices = pm.response.json().booking.slices || [];",
                              "    const tokens = slices.map(s => s.token).filter(Boolean);",
                              "    pm.expect(tokens.length, \"at least one slice token\").to.be.above(0);",
                              "    pm.environment.set(\"booking_token\", tokens.join(\",\"));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/bookings/{{source_booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{source_booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "id": "286e8193-e7b5-42b2-bb19-7eaaaefd874e",
                      "name": "Get Installments — source (3x)",
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/installments?creditcard_bin=555555&selected_tokens={{booking_token}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "installments"
                          ],
                          "query": [
                            {
                              "key": "creditcard_bin",
                              "value": "555555"
                            },
                            {
                              "key": "selected_tokens",
                              "value": "{{booking_token}}"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves plan_token for 3 installments (source slice token)\", () => {",
                              "    const plans = pm.response.json().installment_plans || [];",
                              "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                              "    const plan3 = plans.find(p => p.installment === 3);",
                              "    const planToken = plan3 ? plan3.plan_token : plans[0].plan_token;",
                              "    pm.expect(planToken, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"plan_token\", planToken);",
                              "});"
                            ]
                          }
                        }
                      ],
                      "response": []
                    },
                    {
                      "name": "Create Ticket — Credit Card (source)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns tickets with numbers — saves ticket_numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    // descending order: newer (higher) numbers must be cancelled first on reissue",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(tickets.map(t => t.number).sort().reverse()));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{source_booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{plan_token}}\"\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (source — assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"TICKETED\");",
                              "});",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Offers (new booking: SAO→RIO + RIO→SAO)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"picks a round-trip offer more expensive than the source fare\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "",
                              "    const sourceTotal = Number(pm.environment.get(\"booking_total\")) || 0;",
                              "",
                              "    // resolve an offer's total price (defensive against response shape variations)",
                              "    const offerTotal = (o) => {",
                              "        if (o.price && typeof o.price.total === \"number\") return o.price.total;",
                              "        let sum = 0;",
                              "        (o.journeys || []).forEach(j => (j.slices || []).forEach(s => {",
                              "            if (s.price && typeof s.price.total === \"number\") sum += s.price.total;",
                              "        }));",
                              "        return sum;",
                              "    };",
                              "",
                              "    // round-trip offers only, sorted ascending by price",
                              "    const candidates = offers",
                              "        .filter(o => (o.journeys || []).length >= 2)",
                              "        .sort((a, b) => offerTotal(a) - offerTotal(b));",
                              "    pm.expect(candidates.length, \"round-trip offers\").to.be.above(0);",
                              "",
                              "    // cheapest offer strictly more expensive than the source fare,",
                              "    // so the reissue always yields a positive balance to charge",
                              "    const chosen = candidates.find(o => offerTotal(o) > sourceTotal);",
                              "    pm.expect(chosen, `an offer more expensive than source (${sourceTotal})`).to.not.be.undefined;",
                              "",
                              "    const journeys = chosen.journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=1&infs=1&provider_type=GOL&route=SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "1"
                            },
                            {
                              "key": "infs",
                              "value": "1"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}+RIO,SAO,{{date_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Price Offer (new booking)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves priced tokens (novo loc)\", () => {",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length).to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Create Booking (new booking)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"saves booking_id and locator\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "    if (b.provider && b.provider.locator) pm.environment.set(\"loc\", b.provider.locator);",
                              "});",
                              "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));",
                              "pm.test(\"saves new_booking_passenger_ids\", () => {",
                              "    const ids = (pm.response.json().booking.passengers || []).map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    pm.environment.set(\"new_booking_passenger_ids\", JSON.stringify(ids));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"7515199\",\n          \"type\": \"PASSPORT\",\n          \"issuing_country_code\": \"BR\",\n          \"created_at\": \"2019-08-24\",\n          \"expires_at\": \"2033-08-24\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"CHD\",\n      \"first_name\": \"Alice\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"FEMALE\",\n      \"birth_date\": \"2018-07-10\",\n      \"phone_number\": \"55 11 999559998\",\n      \"email\": \"alice@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"39053344705\",\n          \"type\": \"CPF\"\n        }\n      ]\n    },\n    {\n      \"pax_type\": \"INF\",\n      \"first_name\": \"Sam\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"2024-11-01\",\n      \"phone_number\": \"55 11 999559997\",\n      \"email\": \"sam@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"24843803480\",\n          \"type\": \"CPF\"\n        }\n      ]\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Exchange Estimate",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"response has an offer\", () => {",
                              "    pm.expect(pm.response.json().offer, \"offer\").to.be.an(\"object\");",
                              "});",
                              "pm.test(\"offer has id and expires_at\", () => {",
                              "    const o = pm.response.json().offer;",
                              "    pm.expect(o.id, \"offer.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.expect(o.expires_at, \"offer.expires_at\").to.be.a(\"string\").and.not.empty;",
                              "});",
                              "pm.test(\"offer has balance_price with total\", () => {",
                              "    const price = pm.response.json().offer.balance_price;",
                              "    pm.expect(price, \"balance_price\").to.be.an(\"object\");",
                              "    pm.expect(price.total, \"balance_price.total\").to.be.a(\"number\");",
                              "});",
                              "pm.test(\"offer has journeys array\", () => {",
                              "    pm.expect(pm.response.json().offer.journeys, \"offer.journeys\").to.be.an(\"array\").and.not.empty;",
                              "});",
                              "pm.test(\"saves new_slice_tokens from all slices\", () => {",
                              "    const offer = pm.response.json().offer;",
                              "    const tokens = [];",
                              "    (offer.journeys || []).forEach(j => {",
                              "        (j.slices || []).forEach(s => {",
                              "            if (s.balance_token) tokens.push(s.balance_token);",
                              "        });",
                              "    });",
                              "    pm.expect(tokens.length, \"at least one balance_token\").to.be.above(0);",
                              "    pm.environment.set(\"new_slice_tokens\", JSON.stringify(tokens));",
                              "    pm.environment.set(\"new_slice_tokens_csv\", tokens.join(\",\"));",
                              "});",
                              "pm.test(\"saves balance_price_total and total_tickets_credit_amount\", () => {",
                              "    const offer = pm.response.json().offer;",
                              "    pm.expect(offer.balance_price, \"balance_price\").to.be.an(\"object\");",
                              "    pm.environment.set(\"balance_price_total\", String(offer.balance_price.total));",
                              "    pm.expect(offer.total_tickets_credit_amount, \"total_tickets_credit_amount\").to.be.a(\"number\");",
                              "    pm.environment.set(\"total_tickets_credit_amount\", String(offer.total_tickets_credit_amount));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"ticket_numbers\": {{ticket_numbers}}\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/exchange/estimate",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "exchange",
                            "estimate"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "id": "fb876b0d-d577-4cba-bb5e-5a9ddfde4875",
                      "name": "Get Installments — exchange (3x)",
                      "request": {
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/installments?creditcard_bin=555555&selected_tokens={{new_slice_tokens_csv}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "installments"
                          ],
                          "query": [
                            {
                              "key": "creditcard_bin",
                              "value": "555555"
                            },
                            {
                              "key": "selected_tokens",
                              "value": "{{new_slice_tokens_csv}}"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"saves exchange_plan_token for 3 installments (balance token)\", () => {",
                              "    const plans = pm.response.json().installment_plans || [];",
                              "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                              "    const plan3 = plans.find(p => p.installment === 3);",
                              "    const planToken = plan3 ? plan3.plan_token : plans[0].plan_token;",
                              "    pm.expect(planToken, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"exchange_plan_token\", planToken);",
                              "});"
                            ]
                          }
                        }
                      ],
                      "response": []
                    },
                    {
                      "name": "Reissue Airline Tickets (POST /exchange)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "pm.test(\"returns reissued tickets\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"reissued_number\", tickets[0].number);",
                              "    pm.environment.set(\"reissued_ticket_numbers\", JSON.stringify(tickets.map(t => t.number).sort().reverse()));",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "POST",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json",
                            "type": "text"
                          }
                        ],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"new_slice_tokens\": {{new_slice_tokens}},\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"TICKET\",\n      \"tickets\": {{ticket_numbers}},\n      \"total\": {{total_tickets_credit_amount}},\n      \"passenger_ids\": {{new_booking_passenger_ids}}\n    },\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{balance_price_total}},\n      \"passenger_ids\": {{new_booking_passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{exchange_plan_token}}\"\n    }\n  ]\n}",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          }
                        },
                        "url": {
                          "raw": "{{url}}/exchange",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "exchange"
                          ]
                        },
                        "description": "Reissues tickets from source booking into the new booking booking. Uses new_slice_tokens and total_tickets_credit_amount from the Exchange Estimate step."
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket (reissued — assert TICKETED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"TICKETED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/tickets/{{reissued_number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{reissued_number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "id": "0f5f58c4-bb50-4c17-bb6c-488e8c6a1a6f",
                      "name": "Delete Ticket — new booking (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const raw = pm.environment.get('reissued_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) throw new Error('reissued_ticket_numbers is empty — ensure Reissue ran first.');",
                              "const savedRaw = pm.environment.get('get_reissued_ticket_numbers');",
                              "if (!savedRaw || JSON.parse(savedRaw).length === 0) {",
                              "    pm.environment.set('get_reissued_ticket_numbers', JSON.stringify([...remaining]));",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('reissued_ticket_numbers', JSON.stringify(remaining));"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "const remaining = JSON.parse(pm.environment.get('reissued_ticket_numbers') || '[]');",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "} else {",
                              "    pm.execution.setNextRequest(\"Get Ticket — new booking (assert CANCELED) (loop per ticket — descending order)\");",
                              "}"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "id": "6b35dcb2-6268-47fc-835f-fc4cc69867b6",
                      "name": "Get Ticket — new booking (assert CANCELED) (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const raw = pm.environment.get('get_reissued_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) throw new Error('get_reissued_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('get_reissued_ticket_numbers', JSON.stringify(remaining));"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"CANCELLED\");",
                              "});",
                              "const remaining = JSON.parse(pm.environment.get('get_reissued_ticket_numbers') || '[]');",
                              "if (remaining.length > 0) pm.execution.setNextRequest(pm.info.requestName);"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "id": "5e9bee32-8206-4bb5-8740-f770426083da",
                      "name": "Cancel Booking (new booking)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "method": "DELETE",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "id": "3fa6a1fa-a32d-49b3-b5bd-7e29f858131f",
                      "name": "Get Booking (new booking — assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking_status is CANCELLED\", () => {",
                              "    pm.expect(pm.response.json().booking.booking_status, \"booking_status\").to.equal(\"CANCELLED\");",
                              "});"
                            ]
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Delete Ticket — source (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "const raw = pm.environment.get('ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) throw new Error('ticket_numbers is empty — ensure Create Ticket ran first.');",
                              "const savedRaw = pm.environment.get('get_ticket_numbers');",
                              "if (!savedRaw || JSON.parse(savedRaw).length === 0) {",
                              "    pm.environment.set('get_ticket_numbers', JSON.stringify([...remaining]));",
                              "}",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));",
                              "const remaining = JSON.parse(pm.environment.get('ticket_numbers') || '[]');",
                              "if (remaining.length > 0) {",
                              "    pm.execution.setNextRequest(pm.info.requestName);",
                              "} else {",
                              "    pm.execution.setNextRequest(\"Get Ticket — source (assert CANCELED) (loop per ticket — descending order)\");",
                              "}"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "DELETE",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Ticket — source (assert CANCELED) (loop per ticket — descending order)",
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "exec": [
                              "const raw = pm.environment.get('get_ticket_numbers');",
                              "const remaining = raw ? JSON.parse(raw) : [];",
                              "if (remaining.length === 0) throw new Error('get_ticket_numbers is empty — ensure Delete Ticket ran first.');",
                              "const next = remaining.shift();",
                              "pm.environment.set('number', next);",
                              "pm.environment.set('get_ticket_numbers', JSON.stringify(remaining));"
                            ],
                            "type": "text/javascript"
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket [\" + pm.environment.get(\"number\") + \"] status is CANCELED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"CANCELLED\");",
                              "});",
                              "const remaining = JSON.parse(pm.environment.get('get_ticket_numbers') || '[]');",
                              "if (remaining.length > 0) pm.execution.setNextRequest(pm.info.requestName);"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Cancel Booking (source)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 204\", () => pm.response.to.have.status(204));"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "DELETE",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/bookings/{{source_booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{source_booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    },
                    {
                      "name": "Get Booking (source — assert CANCELLED)",
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"booking_status is CANCELLED\", () => {",
                              "    pm.expect(pm.response.json().booking.booking_status, \"booking_status\").to.equal(\"CANCELLED\");",
                              "});"
                            ],
                            "type": "text/javascript"
                          }
                        }
                      ],
                      "request": {
                        "method": "GET",
                        "header": [],
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        },
                        "url": {
                          "raw": "{{url}}/bookings/{{source_booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{source_booking_id}}"
                          ]
                        }
                      },
                      "response": []
                    }
                  ],
                  "id": "989136a5-fb46-4be1-9849-256f03341126"
                }
              ],
              "id": "0e694182-f804-48ae-81e6-ab0fbbc6ff0b"
            },
            {
              "name": "same booking",
              "item": [
                {
                  "name": "Round-trip 1 ADT (GOL) | Exchange — same booking — all slices | Credit Card",
                  "id": "866cedd8-5955-4b87-8973-e0ac2e4fa9c8",
                  "description": "Full same-loc exchange — Round-trip 1 ADT (GOL) issued via Credit Card.\n\nFlow: creates and issues the SOURCE booking (SAO↔RIO, Jun-26) to obtain the tickets. Then searches for new dates in the same booking (SAO↔RIO, Jul-26). POST /exchange/estimate (same-booking mode) obtains new_slice_tokens. POST /exchange reissues both slices in the same PNR. Cleanup: deletes reissued tickets then cancels the booking.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "id": "c8f826bd-82f3-46aa-8f74-de9bc4b22d01",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}"
                        }
                      },
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves access_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token).to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Offers (source: SAO→RIO + RIO→SAO)",
                      "id": "e5154817-36a0-4940-a1e3-d0beca4d71d3",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_3}}+RIO,SAO,{{date_4}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_3}}+RIO,SAO,{{date_4}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves slice_token_1 and slice_token_2 (source)\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const journeys = offers[0].journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Price Offer (source)",
                      "id": "1a0ad3f8-7797-4d6c-badf-676a29de2986",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves priced tokens (source)\", () => {",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length).to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Create Booking (source)",
                      "id": "ca5016d0-a470-4b5c-8669-a25a31bd85f4",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"52998224725\",\n          \"type\": \"CPF\"\n        }\n      ]\n    }\n  ]\n}"
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "if (pm.response.code !== 201) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves booking_id\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "});",
                              "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Booking (source — save booking_total, passenger_ids, slice tokens)",
                      "id": "9befa93f-d418-4476-89d4-b0f302618989",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves booking_total\", () => {",
                              "    const total = pm.response.json().booking?.price?.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids\", () => {",
                              "    const ids = (pm.response.json().booking.passengers || []).map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves booking_token (CSV of slice tokens) for Get Installments\", () => {",
                              "    const slices = pm.response.json().booking.slices || [];",
                              "    const tokens = slices.map(s => s.token).filter(Boolean);",
                              "    pm.expect(tokens.length, \"at least one slice token\").to.be.above(0);",
                              "    pm.environment.set(\"booking_token\", tokens.join(\",\"));",
                              "});",
                              "pm.test(\"saves existing_slice_token_1 (outbound) and existing_slice_token_2 (inbound)\", () => {",
                              "    const slices = pm.response.json().booking.slices || [];",
                              "    pm.expect(slices.length, \"at least 2 slices for round-trip\").to.be.at.least(2);",
                              "    pm.environment.set(\"existing_slice_token_1\", slices[0].token);",
                              "    pm.environment.set(\"existing_slice_token_2\", slices[1].token);",
                              "    pm.environment.set(\"exchange_slice_tokens\", JSON.stringify([slices[0].token, slices[1].token]));",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Installments — source (3x)",
                      "id": "3b293943-9318-4260-b2dd-10dc23c0fd65",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/installments?creditcard_bin=555555&selected_tokens={{booking_token}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "installments"
                          ],
                          "query": [
                            {
                              "key": "creditcard_bin",
                              "value": "555555"
                            },
                            {
                              "key": "selected_tokens",
                              "value": "{{booking_token}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves plan_token for 3 installments (source slice token)\", () => {",
                              "    const plans = pm.response.json().installment_plans || [];",
                              "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                              "    const plan3 = plans.find(p => p.installment === 3);",
                              "    const planToken = plan3 ? plan3.plan_token : plans[0].plan_token;",
                              "    pm.expect(planToken, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"plan_token\", planToken);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Create Ticket — Credit Card (source)",
                      "id": "91adab8b-4f4b-4b5a-8722-a6cc170f246b",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{plan_token}}\"\n    }\n  ]\n}"
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "if (pm.response.code !== 201) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"returns tickets with numbers — saves ticket_numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(tickets.map(t => t.number).sort().reverse()));",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Ticket (source — assert TICKETED)",
                      "id": "3259613e-ba3d-443c-a953-15705dbd2e6d",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"TICKETED\");",
                              "});",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Offers (same booking: SAO→REC + REC→SAO)",
                      "id": "a4d07edb-fc57-425d-b28b-4cd5d918db12",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=GOL&booking_id={{booking_id}}&route=SAO,REC,{{date_1}}+REC,SAO,{{date_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "booking_id",
                              "value": "{{booking_id}}"
                            },
                            {
                              "key": "route",
                              "value": "SAO,REC,{{date_1}}+REC,SAO,{{date_2}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"picks a round-trip offer with the same fare family on both journeys\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    pm.expect(offers[0].search_id, \"search_id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"search_id\", offers[0].search_id);",
                              "",
                              "    // fare family lives on each leg's fare_info; take the first one found in a journey",
                              "    const journeyFareFamily = (j) => {",
                              "        for (const s of (j.slices || [])) {",
                              "            for (const l of (s.legs || [])) {",
                              "                const ff = l.fare_info && l.fare_info.fare_family;",
                              "                if (ff) return ff;",
                              "            }",
                              "        }",
                              "        return \"\";",
                              "    };",
                              "",
                              "    // round-trip offers whose outbound and inbound journeys share the same fare family",
                              "    const chosen = offers",
                              "        .filter(o => (o.journeys || []).length >= 2)",
                              "        .find(o => {",
                              "            const ffOut = journeyFareFamily(o.journeys[0]);",
                              "            const ffIn = journeyFareFamily(o.journeys[1]);",
                              "            return ffOut !== \"\" && ffOut === ffIn;",
                              "        });",
                              "    pm.expect(chosen, \"a round-trip offer with matching fare family on both journeys\").to.not.be.undefined;",
                              "",
                              "    const journeys = chosen.journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"new_slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"new_slice_token_2\", journeys[1].slices[0].token);",
                              "    pm.environment.set(\"new_slice_tokens\", JSON.stringify([journeys[0].slices[0].token, journeys[1].slices[0].token]));",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Exchange Estimate (same booking — all slices)",
                      "id": "64b0a5b0-149d-416d-9131-0b92abf39a95",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/exchange/estimate",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "exchange",
                            "estimate"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"search_id\": \"{{search_id}}\",\n  \"new_slice_tokens\": {{new_slice_tokens}},\n  \"exchange_slice_tokens\": {{exchange_slice_tokens}}\n}"
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"response has an offer\", () => {",
                              "    pm.expect(pm.response.json().offer, \"offer\").to.be.an(\"object\");",
                              "});",
                              "pm.test(\"offer has id and expires_at\", () => {",
                              "    const o = pm.response.json().offer;",
                              "    pm.expect(o.id, \"offer.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.expect(o.expires_at, \"offer.expires_at\").to.be.a(\"string\").and.not.empty;",
                              "});",
                              "pm.test(\"offer has balance_price with total\", () => {",
                              "    const price = pm.response.json().offer.balance_price;",
                              "    pm.expect(price, \"balance_price\").to.be.an(\"object\");",
                              "    pm.expect(price.total, \"balance_price.total\").to.be.a(\"number\");",
                              "});",
                              "pm.test(\"offer has journeys array\", () => {",
                              "    pm.expect(pm.response.json().offer.journeys, \"offer.journeys\").to.be.an(\"array\").and.not.empty;",
                              "});",
                              "pm.test(\"saves new_slice_tokens from all slices and new_slice_tokens_csv\", () => {",
                              "    const offer = pm.response.json().offer;",
                              "    const tokens = [];",
                              "    (offer.journeys || []).forEach(j => {",
                              "        (j.slices || []).forEach(s => { if (s.balance_token) tokens.push(s.balance_token); });",
                              "    });",
                              "    pm.expect(tokens.length, \"at least one balance_token\").to.be.above(0);",
                              "    pm.environment.set(\"new_slice_tokens\", JSON.stringify(tokens));",
                              "    pm.environment.set(\"new_slice_tokens_csv\", tokens.join(\",\"));",
                              "});",
                              "pm.test(\"saves balance_price_total\", () => {",
                              "    const offer = pm.response.json().offer;",
                              "    pm.expect(offer.balance_price, \"balance_price\").to.be.an(\"object\");",
                              "    pm.environment.set(\"balance_price_total\", String(offer.balance_price.total));",
                              "});",
                              "pm.test(\"balance_price.total is non-negative (positive balance expected)\", () => {",
                              "    const total = parseFloat(pm.environment.get(\"balance_price_total\") || \"0\");",
                              "    pm.expect(total, \"balance_price.total must be >= 0 — negative balance indicates credit, not a charge\").to.be.at.least(0);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Installments — exchange (3x)",
                      "id": "a586c75e-cdbe-461d-9147-5d446ea9b6b0",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/installments?creditcard_bin=555555&selected_tokens={{new_slice_tokens_csv}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "installments"
                          ],
                          "query": [
                            {
                              "key": "creditcard_bin",
                              "value": "555555"
                            },
                            {
                              "key": "selected_tokens",
                              "value": "{{new_slice_tokens_csv}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves exchange_plan_token for 3 installments (balance token)\", () => {",
                              "    const plans = pm.response.json().installment_plans || [];",
                              "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                              "    const plan3 = plans.find(p => p.installment === 3);",
                              "    const planToken = plan3 ? plan3.plan_token : plans[0].plan_token;",
                              "    pm.expect(planToken, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"exchange_plan_token\", planToken);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Reissue Airline Tickets (POST /exchange)",
                      "id": "fbdd948c-5658-426c-a2de-32b666251d2c",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/exchange",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "exchange"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"new_slice_tokens\": {{new_slice_tokens}},\n  \"exchange_slice_tokens\": {{exchange_slice_tokens}},\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{balance_price_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{exchange_plan_token}}\"\n    }\n  ]\n}"
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "if (pm.response.code !== 201) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"returns reissued tickets\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"reissued_number\", tickets[0].number);",
                              "    pm.environment.set(\"reissued_ticket_numbers\", JSON.stringify(tickets.map(t => t.number).sort().reverse()));",
                              "    // same-booking reissue: the original tickets become EXCHANGED in the same PNR;",
                              "    // cleanup must cancel both the original (first issuance) and the reissued tickets",
                              "    const originalTickets = JSON.parse(pm.environment.get(\"ticket_numbers\") || \"[]\");",
                              "    const reissuedTickets = tickets.map(t => t.number).sort().reverse();",
                              "    // reissued tickets first, then the original (first issuance) tickets",
                              "    pm.environment.set(\"all_ticket_numbers\", JSON.stringify([...reissuedTickets, ...originalTickets]));",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Ticket (reissued — assert TICKETED)",
                      "id": "8ad703b7-615c-4576-a54f-acd764e0b180",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/tickets/{{reissued_number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{reissued_number}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"TICKETED\");",
                              "});",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Delete Ticket (loop per ticket — descending order)",
                      "id": "5029f12f-f7ae-435a-a0d5-d6b4670e6dbc",
                      "request": {
                        "method": "DELETE",
                        "url": {
                          "raw": "{{url}}/tickets/{{current_ticket}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{current_ticket}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const nums = JSON.parse(pm.environment.get(\"all_ticket_numbers\") || \"[]\");",
                              "const idx = parseInt(pm.environment.get(\"ticket_loop_idx\") || \"0\");",
                              "pm.environment.set(\"current_ticket\", nums[idx]);",
                              "pm.environment.set(\"ticket_loop_idx\", String(idx + 1));"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200 or 204\", () => {",
                              "    pm.expect(pm.response.code).to.be.oneOf([200, 204]);",
                              "});",
                              "const nums = JSON.parse(pm.environment.get(\"all_ticket_numbers\") || \"[]\");",
                              "const idx = parseInt(pm.environment.get(\"ticket_loop_idx\") || \"0\");",
                              "if (idx < nums.length) {",
                              "    postman.setNextRequest(\"Delete Ticket (loop per ticket — descending order)\");",
                              "} else {",
                              "    pm.environment.unset(\"ticket_loop_idx\");",
                              "}"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                      "id": "586339ea-58a6-4813-aa0e-d1b21fb49efd",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/tickets/{{current_ticket}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{current_ticket}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const nums = JSON.parse(pm.environment.get(\"all_ticket_numbers\") || \"[]\");",
                              "const idx = parseInt(pm.environment.get(\"cancel_check_idx\") || \"0\");",
                              "pm.environment.set(\"current_ticket\", nums[idx]);",
                              "pm.environment.set(\"cancel_check_idx\", String(idx + 1));"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket_status is CANCELED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"CANCELLED\");",
                              "});",
                              "const nums = JSON.parse(pm.environment.get(\"all_ticket_numbers\") || \"[]\");",
                              "const idx = parseInt(pm.environment.get(\"cancel_check_idx\") || \"0\");",
                              "if (idx < nums.length) {",
                              "    postman.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                              "} else {",
                              "    pm.environment.unset(\"cancel_check_idx\");",
                              "}"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Cancel Booking",
                      "id": "3c5bcdd7-c07f-4bec-9f37-72d3be3cf1a4",
                      "request": {
                        "method": "DELETE",
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200 or 204\", () => {",
                              "    pm.expect(pm.response.code).to.be.oneOf([200, 204]);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "id": "0e6af820-5921-4343-a52c-7974fad4f4a3",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"booking_status is CANCELLED\", () => {",
                              "    pm.expect(pm.response.json().booking.booking_status, \"booking_status\").to.equal(\"CANCELLED\");",
                              "});"
                            ]
                          }
                        }
                      ]
                    }
                  ]
                },
                {
                  "name": "Round-trip 1 ADT (GOL) | Exchange — same booking — inbound slice | Credit Card",
                  "id": "385c9168-47a0-4ffe-b774-2193d1a1ed5d",
                  "description": "Partial same-loc exchange — inbound slice only. Issues the SOURCE booking (SAO↔RIO, Jun-26) then replaces only the inbound slice (RIO→SAO) with a Jul-26 date in the same PNR.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "id": "eb28d2eb-57c5-44f4-8002-2615ea9ac63d",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}"
                        }
                      },
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves access_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token).to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Offers (source: SAO→RIO + RIO→SAO)",
                      "id": "0e28cd6b-6e82-41b9-a7ac-1cc3333a5b74",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_3}}+RIO,SAO,{{date_4}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_3}}+RIO,SAO,{{date_4}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves slice_token_1 and slice_token_2 (source)\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const journeys = offers[0].journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Price Offer (source)",
                      "id": "b8bc1567-ddf0-4efa-bf51-be323d676edf",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves priced tokens (source)\", () => {",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length).to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Create Booking (source)",
                      "id": "181701ca-8f08-45e6-b48d-b6bb66ddeeec",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"52998224725\",\n          \"type\": \"CPF\"\n        }\n      ]\n    }\n  ]\n}"
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "if (pm.response.code !== 201) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves booking_id\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "});",
                              "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Booking (source — save booking_total, passenger_ids, slice tokens)",
                      "id": "a19ed323-1265-4cc0-abe9-728f2e9bdec7",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves booking_total\", () => {",
                              "    const total = pm.response.json().booking?.price?.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids\", () => {",
                              "    const ids = (pm.response.json().booking.passengers || []).map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves booking_token (CSV of slice tokens) for Get Installments\", () => {",
                              "    const slices = pm.response.json().booking.slices || [];",
                              "    const tokens = slices.map(s => s.token).filter(Boolean);",
                              "    pm.expect(tokens.length, \"at least one slice token\").to.be.above(0);",
                              "    pm.environment.set(\"booking_token\", tokens.join(\",\"));",
                              "});",
                              "pm.test(\"saves existing_slice_token_1 (outbound) and existing_slice_token_2 (inbound)\", () => {",
                              "    const slices = pm.response.json().booking.slices || [];",
                              "    pm.expect(slices.length, \"at least 2 slices for round-trip\").to.be.at.least(2);",
                              "    pm.environment.set(\"existing_slice_token_1\", slices[0].token);",
                              "    pm.environment.set(\"existing_slice_token_2\", slices[1].token);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Installments — source (3x)",
                      "id": "9b9f596d-e083-4d55-86a2-398e4881130f",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/installments?creditcard_bin=555555&selected_tokens={{booking_token}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "installments"
                          ],
                          "query": [
                            {
                              "key": "creditcard_bin",
                              "value": "555555"
                            },
                            {
                              "key": "selected_tokens",
                              "value": "{{booking_token}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves plan_token for 3 installments (source slice token)\", () => {",
                              "    const plans = pm.response.json().installment_plans || [];",
                              "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                              "    const plan3 = plans.find(p => p.installment === 3);",
                              "    const planToken = plan3 ? plan3.plan_token : plans[0].plan_token;",
                              "    pm.expect(planToken, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"plan_token\", planToken);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Create Ticket — Credit Card (source)",
                      "id": "22eee51f-dc2e-42aa-a2a0-82f01cba80fe",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{plan_token}}\"\n    }\n  ]\n}"
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "if (pm.response.code !== 201) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"returns tickets with numbers — saves ticket_numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(tickets.map(t => t.number).sort().reverse()));",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Ticket (source — assert TICKETED)",
                      "id": "152b318b-25ca-40ec-833b-fd6b26f3b6b4",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"TICKETED\");",
                              "});",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Offers (same booking: RIO→SAO — inbound only)",
                      "id": "d463b89d-c018-41dd-9411-b45ed24d29c5",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=GOL&booking_id={{booking_id}}&route=RIO,SAO,{{date_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "booking_id",
                              "value": "{{booking_id}}"
                            },
                            {
                              "key": "route",
                              "value": "RIO,SAO,{{date_2}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves search_id and new_slice_token_2 — picks most expensive inbound offer\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    pm.expect(offers[0].search_id, \"search_id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"search_id\", offers[0].search_id);",
                              "",
                              "    const offerTotal = (o) => {",
                              "        if (o.price && typeof o.price.total === \"number\") return o.price.total;",
                              "        let sum = 0;",
                              "        (o.journeys || []).forEach(j => (j.slices || []).forEach(s => {",
                              "            if (s.price && typeof s.price.total === \"number\") sum += s.price.total;",
                              "        }));",
                              "        return sum;",
                              "    };",
                              "",
                              "    const chosen = offers.sort((a, b) => offerTotal(b) - offerTotal(a))[0];",
                              "    const journeys = chosen.journeys;",
                              "    pm.expect(journeys.length, \"at least 1 journey\").to.be.at.least(1);",
                              "    pm.environment.set(\"new_slice_token_2\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"new_slice_tokens\", JSON.stringify([journeys[0].slices[0].token]));",
                              "    pm.environment.set(\"exchange_slice_tokens\", JSON.stringify([pm.environment.get(\"existing_slice_token_2\")]));",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Exchange Estimate (same booking — inbound slice only)",
                      "id": "d62bc5da-60d6-4b3f-95cf-69790f0dd260",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/exchange/estimate",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "exchange",
                            "estimate"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"search_id\": \"{{search_id}}\",\n  \"new_slice_tokens\": {{new_slice_tokens}},\n  \"exchange_slice_tokens\": {{exchange_slice_tokens}}\n}"
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"response has an offer\", () => {",
                              "    pm.expect(pm.response.json().offer, \"offer\").to.be.an(\"object\");",
                              "});",
                              "pm.test(\"offer has id and expires_at\", () => {",
                              "    const o = pm.response.json().offer;",
                              "    pm.expect(o.id, \"offer.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.expect(o.expires_at, \"offer.expires_at\").to.be.a(\"string\").and.not.empty;",
                              "});",
                              "pm.test(\"offer has balance_price with total\", () => {",
                              "    const price = pm.response.json().offer.balance_price;",
                              "    pm.expect(price, \"balance_price\").to.be.an(\"object\");",
                              "    pm.expect(price.total, \"balance_price.total\").to.be.a(\"number\");",
                              "});",
                              "pm.test(\"saves new_slice_tokens and new_slice_tokens_csv\", () => {",
                              "    const offer = pm.response.json().offer;",
                              "    const tokens = [];",
                              "    (offer.journeys || []).forEach(j => {",
                              "        (j.slices || []).forEach(s => { if (s.balance_token) tokens.push(s.balance_token); });",
                              "    });",
                              "    pm.expect(tokens.length, \"at least one balance_token\").to.be.above(0);",
                              "    pm.environment.set(\"new_slice_tokens\", JSON.stringify(tokens));",
                              "    pm.environment.set(\"new_slice_tokens_csv\", tokens.join(\",\"));",
                              "});",
                              "pm.test(\"saves balance_price_total\", () => {",
                              "    const offer = pm.response.json().offer;",
                              "    pm.environment.set(\"balance_price_total\", String(offer.balance_price.total));",
                              "});",
                              "pm.test(\"balance_price.total is non-negative (positive balance expected)\", () => {",
                              "    const total = parseFloat(pm.environment.get(\"balance_price_total\") || \"0\");",
                              "    pm.expect(total, \"balance_price.total must be >= 0 — negative balance indicates credit, not a charge\").to.be.at.least(0);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Installments — exchange (3x)",
                      "id": "eb3c1f8d-23d8-415e-9f6b-42f28f49fca5",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/installments?creditcard_bin=555555&selected_tokens={{new_slice_tokens_csv}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "installments"
                          ],
                          "query": [
                            {
                              "key": "creditcard_bin",
                              "value": "555555"
                            },
                            {
                              "key": "selected_tokens",
                              "value": "{{new_slice_tokens_csv}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves exchange_plan_token for 3 installments (balance token)\", () => {",
                              "    const plans = pm.response.json().installment_plans || [];",
                              "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                              "    const plan3 = plans.find(p => p.installment === 3);",
                              "    const planToken = plan3 ? plan3.plan_token : plans[0].plan_token;",
                              "    pm.expect(planToken, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"exchange_plan_token\", planToken);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Reissue Airline Tickets (POST /exchange)",
                      "id": "26c8d9cc-eb30-4bb8-802e-4fb42334a81d",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/exchange",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "exchange"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"new_slice_tokens\": {{new_slice_tokens}},\n  \"exchange_slice_tokens\": {{exchange_slice_tokens}},\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{balance_price_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{exchange_plan_token}}\"\n    }\n  ]\n}"
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "if (pm.response.code !== 201) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"returns reissued tickets\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"reissued_number\", tickets[0].number);",
                              "    pm.environment.set(\"reissued_ticket_numbers\", JSON.stringify(tickets.map(t => t.number).sort().reverse()));",
                              "    // same-booking reissue: the original tickets become EXCHANGED in the same PNR;",
                              "    // cleanup must cancel both the original (first issuance) and the reissued tickets",
                              "    const originalTickets = JSON.parse(pm.environment.get(\"ticket_numbers\") || \"[]\");",
                              "    const reissuedTickets = tickets.map(t => t.number).sort().reverse();",
                              "    // reissued tickets first, then the original (first issuance) tickets",
                              "    pm.environment.set(\"all_ticket_numbers\", JSON.stringify([...reissuedTickets, ...originalTickets]));",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Ticket (reissued — assert TICKETED)",
                      "id": "98c73050-8085-4dd3-8e79-78e97b41e080",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/tickets/{{reissued_number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{reissued_number}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"TICKETED\");",
                              "});",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Delete Ticket (loop per ticket — descending order)",
                      "id": "e14b966b-fc72-43f6-ba90-c759e9248529",
                      "request": {
                        "method": "DELETE",
                        "url": {
                          "raw": "{{url}}/tickets/{{current_ticket}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{current_ticket}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const nums = JSON.parse(pm.environment.get(\"all_ticket_numbers\") || \"[]\");",
                              "const idx = parseInt(pm.environment.get(\"ticket_loop_idx\") || \"0\");",
                              "pm.environment.set(\"current_ticket\", nums[idx]);",
                              "pm.environment.set(\"ticket_loop_idx\", String(idx + 1));"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200 or 204\", () => {",
                              "    pm.expect(pm.response.code).to.be.oneOf([200, 204]);",
                              "});",
                              "const nums = JSON.parse(pm.environment.get(\"all_ticket_numbers\") || \"[]\");",
                              "const idx = parseInt(pm.environment.get(\"ticket_loop_idx\") || \"0\");",
                              "if (idx < nums.length) {",
                              "    postman.setNextRequest(\"Delete Ticket (loop per ticket — descending order)\");",
                              "} else {",
                              "    pm.environment.unset(\"ticket_loop_idx\");",
                              "}"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                      "id": "4b744dde-3218-430d-b6d2-c7715d3cf04c",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/tickets/{{current_ticket}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{current_ticket}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const nums = JSON.parse(pm.environment.get(\"all_ticket_numbers\") || \"[]\");",
                              "const idx = parseInt(pm.environment.get(\"cancel_check_idx\") || \"0\");",
                              "pm.environment.set(\"current_ticket\", nums[idx]);",
                              "pm.environment.set(\"cancel_check_idx\", String(idx + 1));"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket_status is CANCELED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"CANCELLED\");",
                              "});",
                              "const nums = JSON.parse(pm.environment.get(\"all_ticket_numbers\") || \"[]\");",
                              "const idx = parseInt(pm.environment.get(\"cancel_check_idx\") || \"0\");",
                              "if (idx < nums.length) {",
                              "    postman.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                              "} else {",
                              "    pm.environment.unset(\"cancel_check_idx\");",
                              "}"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Cancel Booking",
                      "id": "7bb3288e-04dc-4625-88ac-a2903b37f278",
                      "request": {
                        "method": "DELETE",
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200 or 204\", () => {",
                              "    pm.expect(pm.response.code).to.be.oneOf([200, 204]);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "id": "c14b5ee7-49a4-4ddd-8e4b-d7b43b813089",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"booking_status is CANCELLED\", () => {",
                              "    pm.expect(pm.response.json().booking.booking_status, \"booking_status\").to.equal(\"CANCELLED\");",
                              "});"
                            ]
                          }
                        }
                      ]
                    }
                  ]
                },
                {
                  "name": "Round-trip 1 ADT (GOL) | Exchange — same booking — outbound slice | Credit Card",
                  "id": "b5b0a3d0-7194-47d1-b5db-7e91b8ba21a1",
                  "description": "Partial same-loc exchange — outbound slice only. Issues the SOURCE booking (SAO↔RIO, Jun-26) then replaces only the outbound slice (SAO→RIO) with a Jul-26 date in the same PNR.",
                  "item": [
                    {
                      "name": "Auth - Access Token",
                      "id": "3bbcee04-04ae-4731-a693-e2811b9c0e07",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/oauth/token",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "oauth",
                            "token"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"username\": \"{{username}}\",\n  \"password\": \"{{password}}\"\n}"
                        }
                      },
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const addDays = (n) => {",
                              "    const d = new Date();",
                              "    d.setDate(d.getDate() + n);",
                              "    return d.toISOString().split('T')[0];",
                              "};",
                              "pm.environment.set('date_1', addDays(12));  // outbound source / one-way",
                              "pm.environment.set('date_2', addDays(19));  // inbound source",
                              "pm.environment.set('date_3', addDays(42));  // outbound exchange",
                              "pm.environment.set('date_4', addDays(49));  // inbound exchange"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves access_token\", () => {",
                              "    const body = pm.response.json();",
                              "    pm.expect(body.access_token).to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"access_token\", body.access_token);",
                              "    if (body.refresh_token) pm.environment.set(\"refresh_token\", body.refresh_token);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Offers (source: SAO→RIO + RIO→SAO)",
                      "id": "452b6fae-94b4-4640-87fe-468dd07d16d5",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=GOL&route=SAO,RIO,{{date_3}}+RIO,SAO,{{date_4}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_3}}+RIO,SAO,{{date_4}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves slice_token_1 and slice_token_2 (source)\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    const journeys = offers[0].journeys;",
                              "    pm.expect(journeys.length, \"round-trip must have 2 journeys\").to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Price Offer (source)",
                      "id": "646d710f-6c41-4987-9005-15eafa5ab86e",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/offers/price?slice_tokens={{slice_token_1}},{{slice_token_2}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers",
                            "price"
                          ],
                          "query": [
                            {
                              "key": "slice_tokens",
                              "value": "{{slice_token_1}},{{slice_token_2}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves priced tokens (source)\", () => {",
                              "    const journeys = pm.response.json().offer.journeys || [];",
                              "    pm.expect(journeys.length).to.be.at.least(2);",
                              "    pm.environment.set(\"slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"slice_token_2\", journeys[1].slices[0].token);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Create Booking (source)",
                      "id": "a33f3355-c58e-4c1d-92e5-6668d6185676",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/bookings",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"selected_tokens\": [\n    \"{{slice_token_1}}\",\n    \"{{slice_token_2}}\"\n  ],\n  \"passengers\": [\n    {\n      \"pax_type\": \"ADT\",\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"gender_type\": \"MALE\",\n      \"birth_date\": \"1990-05-12\",\n      \"phone_number\": \"55 11 999559999\",\n      \"email\": \"john@mymail.com\",\n      \"nationality\": \"BR\",\n      \"documents\": [\n        {\n          \"unique_identifier\": \"52998224725\",\n          \"type\": \"CPF\"\n        }\n      ]\n    }\n  ]\n}"
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "if (pm.response.code !== 201) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves booking_id\", () => {",
                              "    const b = pm.response.json().booking;",
                              "    pm.expect(b.id, \"booking.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"booking_id\", b.id);",
                              "});",
                              "pm.test(\"response time < 15000ms\", () => pm.expect(pm.response.responseTime).to.be.below(15000));"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Booking (source — save booking_total, passenger_ids, slice tokens)",
                      "id": "a72be210-f342-40d0-8819-e3a3376b12cc",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves booking_total\", () => {",
                              "    const total = pm.response.json().booking?.price?.total;",
                              "    pm.expect(total, \"booking.price.total\").to.be.a(\"number\").and.above(0);",
                              "    pm.environment.set(\"booking_total\", String(total));",
                              "});",
                              "pm.test(\"saves passenger_ids\", () => {",
                              "    const ids = (pm.response.json().booking.passengers || []).map(p => p.id).filter(Boolean);",
                              "    pm.expect(ids.length, \"at least one passenger id\").to.be.above(0);",
                              "    pm.environment.set(\"passenger_ids\", JSON.stringify(ids));",
                              "});",
                              "pm.test(\"saves booking_token (CSV of slice tokens) for Get Installments\", () => {",
                              "    const slices = pm.response.json().booking.slices || [];",
                              "    const tokens = slices.map(s => s.token).filter(Boolean);",
                              "    pm.expect(tokens.length, \"at least one slice token\").to.be.above(0);",
                              "    pm.environment.set(\"booking_token\", tokens.join(\",\"));",
                              "});",
                              "pm.test(\"saves existing_slice_token_1 (outbound) and existing_slice_token_2 (inbound)\", () => {",
                              "    const slices = pm.response.json().booking.slices || [];",
                              "    pm.expect(slices.length, \"at least 2 slices for round-trip\").to.be.at.least(2);",
                              "    pm.environment.set(\"existing_slice_token_1\", slices[0].token);",
                              "    pm.environment.set(\"existing_slice_token_2\", slices[1].token);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Installments — source (3x)",
                      "id": "c75bb526-85d9-4c97-a1b8-b87a8f15858f",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/installments?creditcard_bin=555555&selected_tokens={{booking_token}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "installments"
                          ],
                          "query": [
                            {
                              "key": "creditcard_bin",
                              "value": "555555"
                            },
                            {
                              "key": "selected_tokens",
                              "value": "{{booking_token}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves plan_token for 3 installments (source slice token)\", () => {",
                              "    const plans = pm.response.json().installment_plans || [];",
                              "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                              "    const plan3 = plans.find(p => p.installment === 3);",
                              "    const planToken = plan3 ? plan3.plan_token : plans[0].plan_token;",
                              "    pm.expect(planToken, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"plan_token\", planToken);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Create Ticket — Credit Card (source)",
                      "id": "405f1cd0-4e66-4be7-a12b-77950e4f8438",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/tickets",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{booking_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{plan_token}}\"\n    }\n  ]\n}"
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "if (pm.response.code !== 201) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"returns tickets with numbers — saves ticket_numbers\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"number\", tickets[0].number);",
                              "    pm.environment.set(\"ticket_numbers\", JSON.stringify(tickets.map(t => t.number).sort().reverse()));",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Ticket (source — assert TICKETED)",
                      "id": "0d093012-5b54-4914-ae05-eefe55e25fc0",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/tickets/{{number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{number}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"TICKETED\");",
                              "});",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Offers (same booking: SAO→RIO — outbound only)",
                      "id": "9939cc50-2443-4e7d-9bc5-b6a67eff0549",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/offers?adts=1&chds=0&infs=0&provider_type=GOL&booking_id={{booking_id}}&route=SAO,RIO,{{date_1}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "offers"
                          ],
                          "query": [
                            {
                              "key": "adts",
                              "value": "1"
                            },
                            {
                              "key": "chds",
                              "value": "0"
                            },
                            {
                              "key": "infs",
                              "value": "0"
                            },
                            {
                              "key": "provider_type",
                              "value": "GOL"
                            },
                            {
                              "key": "booking_id",
                              "value": "{{booking_id}}"
                            },
                            {
                              "key": "route",
                              "value": "SAO,RIO,{{date_1}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves search_id and new_slice_token_1 — picks most expensive outbound offer\", () => {",
                              "    const offers = pm.response.json().offers;",
                              "    pm.expect(offers, \"offers\").to.be.an(\"array\").and.not.empty;",
                              "    pm.expect(offers[0].search_id, \"search_id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"search_id\", offers[0].search_id);",
                              "",
                              "    const offerTotal = (o) => {",
                              "        if (o.price && typeof o.price.total === \"number\") return o.price.total;",
                              "        let sum = 0;",
                              "        (o.journeys || []).forEach(j => (j.slices || []).forEach(s => {",
                              "            if (s.price && typeof s.price.total === \"number\") sum += s.price.total;",
                              "        }));",
                              "        return sum;",
                              "    };",
                              "",
                              "    const chosen = offers.sort((a, b) => offerTotal(b) - offerTotal(a))[0];",
                              "    const journeys = chosen.journeys;",
                              "    pm.expect(journeys.length, \"at least 1 journey\").to.be.at.least(1);",
                              "    pm.environment.set(\"new_slice_token_1\", journeys[0].slices[0].token);",
                              "    pm.environment.set(\"new_slice_tokens\", JSON.stringify([journeys[0].slices[0].token]));",
                              "    pm.environment.set(\"exchange_slice_tokens\", JSON.stringify([pm.environment.get(\"existing_slice_token_1\")]));",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Exchange Estimate (same booking — outbound slice only)",
                      "id": "88b1f33c-dc41-4b77-9c57-5955ff664daa",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/exchange/estimate",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "exchange",
                            "estimate"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"search_id\": \"{{search_id}}\",\n  \"new_slice_tokens\": {{new_slice_tokens}},\n  \"exchange_slice_tokens\": {{exchange_slice_tokens}}\n}"
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"response has an offer\", () => {",
                              "    pm.expect(pm.response.json().offer, \"offer\").to.be.an(\"object\");",
                              "});",
                              "pm.test(\"offer has id and expires_at\", () => {",
                              "    const o = pm.response.json().offer;",
                              "    pm.expect(o.id, \"offer.id\").to.be.a(\"string\").and.not.empty;",
                              "    pm.expect(o.expires_at, \"offer.expires_at\").to.be.a(\"string\").and.not.empty;",
                              "});",
                              "pm.test(\"offer has balance_price with total\", () => {",
                              "    const price = pm.response.json().offer.balance_price;",
                              "    pm.expect(price, \"balance_price\").to.be.an(\"object\");",
                              "    pm.expect(price.total, \"balance_price.total\").to.be.a(\"number\");",
                              "});",
                              "pm.test(\"saves new_slice_tokens and new_slice_tokens_csv\", () => {",
                              "    const offer = pm.response.json().offer;",
                              "    const tokens = [];",
                              "    (offer.journeys || []).forEach(j => {",
                              "        (j.slices || []).forEach(s => { if (s.balance_token) tokens.push(s.balance_token); });",
                              "    });",
                              "    pm.expect(tokens.length, \"at least one balance_token\").to.be.above(0);",
                              "    pm.environment.set(\"new_slice_tokens\", JSON.stringify(tokens));",
                              "    pm.environment.set(\"new_slice_tokens_csv\", tokens.join(\",\"));",
                              "});",
                              "pm.test(\"saves balance_price_total\", () => {",
                              "    const offer = pm.response.json().offer;",
                              "    pm.environment.set(\"balance_price_total\", String(offer.balance_price.total));",
                              "});",
                              "pm.test(\"balance_price.total is non-negative (positive balance expected)\", () => {",
                              "    const total = parseFloat(pm.environment.get(\"balance_price_total\") || \"0\");",
                              "    pm.expect(total, \"balance_price.total must be >= 0 — negative balance indicates credit, not a charge\").to.be.at.least(0);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Installments — exchange (3x)",
                      "id": "6f36ae16-067b-4b99-8bbe-042dfbcea34b",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/installments?creditcard_bin=555555&selected_tokens={{new_slice_tokens_csv}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "installments"
                          ],
                          "query": [
                            {
                              "key": "creditcard_bin",
                              "value": "555555"
                            },
                            {
                              "key": "selected_tokens",
                              "value": "{{new_slice_tokens_csv}}"
                            }
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"saves exchange_plan_token for 3 installments (balance token)\", () => {",
                              "    const plans = pm.response.json().installment_plans || [];",
                              "    pm.expect(plans, \"installment_plans\").to.be.an(\"array\").and.not.empty;",
                              "    const plan3 = plans.find(p => p.installment === 3);",
                              "    const planToken = plan3 ? plan3.plan_token : plans[0].plan_token;",
                              "    pm.expect(planToken, \"plan_token\").to.be.a(\"string\").and.not.empty;",
                              "    pm.environment.set(\"exchange_plan_token\", planToken);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Reissue Airline Tickets (POST /exchange)",
                      "id": "e95ee094-f01f-4230-8512-52d1e6814c5b",
                      "request": {
                        "method": "POST",
                        "url": {
                          "raw": "{{url}}/exchange",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "exchange"
                          ]
                        },
                        "body": {
                          "mode": "raw",
                          "options": {
                            "raw": {
                              "language": "json"
                            }
                          },
                          "raw": "{\n  \"booking_id\": \"{{booking_id}}\",\n  \"new_slice_tokens\": {{new_slice_tokens}},\n  \"exchange_slice_tokens\": {{exchange_slice_tokens}},\n  \"form_of_payments\": [\n    {\n      \"fop_type\": \"CREDITCARD\",\n      \"total\": {{balance_price_total}},\n      \"passenger_ids\": {{passenger_ids}},\n      \"payment_card\": {\n        \"holder\": \"JOHN DOE\",\n        \"number\": \"5555555555554444\",\n        \"card_brand\": \"MASTERCARD\",\n        \"expire_date\": \"03/30\",\n        \"cvv\": \"737\"\n      },\n      \"plan_token\": \"{{exchange_plan_token}}\"\n    }\n  ]\n}"
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 201\", () => pm.response.to.have.status(201));",
                              "if (pm.response.code !== 201) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"returns reissued tickets\", () => {",
                              "    const tickets = pm.response.json().tickets || [];",
                              "    pm.expect(tickets, \"tickets\").to.be.an(\"array\").and.not.empty;",
                              "    tickets.forEach((t, i) => pm.expect(t.number, `tickets[${i}].number`).to.be.a(\"string\").and.not.empty);",
                              "    pm.environment.set(\"reissued_number\", tickets[0].number);",
                              "    pm.environment.set(\"reissued_ticket_numbers\", JSON.stringify(tickets.map(t => t.number).sort().reverse()));",
                              "    // same-booking reissue: the original tickets become EXCHANGED in the same PNR;",
                              "    // cleanup must cancel both the original (first issuance) and the reissued tickets",
                              "    const originalTickets = JSON.parse(pm.environment.get(\"ticket_numbers\") || \"[]\");",
                              "    const reissuedTickets = tickets.map(t => t.number).sort().reverse();",
                              "    // reissued tickets first, then the original (first issuance) tickets",
                              "    pm.environment.set(\"all_ticket_numbers\", JSON.stringify([...reissuedTickets, ...originalTickets]));",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Ticket (reissued — assert TICKETED)",
                      "id": "0235e74f-bf62-43d3-9bee-cd8ebccd3a81",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/tickets/{{reissued_number}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{reissued_number}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"ticket_status is TICKETED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"TICKETED\");",
                              "});",
                              "pm.test(\"response time < 10000ms\", () => pm.expect(pm.response.responseTime).to.be.below(10000));"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Delete Ticket (loop per ticket — descending order)",
                      "id": "fd42e6bb-5eea-44cd-95da-341bceb07af1",
                      "request": {
                        "method": "DELETE",
                        "url": {
                          "raw": "{{url}}/tickets/{{current_ticket}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{current_ticket}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const nums = JSON.parse(pm.environment.get(\"all_ticket_numbers\") || \"[]\");",
                              "const idx = parseInt(pm.environment.get(\"ticket_loop_idx\") || \"0\");",
                              "pm.environment.set(\"current_ticket\", nums[idx]);",
                              "pm.environment.set(\"ticket_loop_idx\", String(idx + 1));"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200 or 204\", () => {",
                              "    pm.expect(pm.response.code).to.be.oneOf([200, 204]);",
                              "});",
                              "const nums = JSON.parse(pm.environment.get(\"all_ticket_numbers\") || \"[]\");",
                              "const idx = parseInt(pm.environment.get(\"ticket_loop_idx\") || \"0\");",
                              "if (idx < nums.length) {",
                              "    postman.setNextRequest(\"Delete Ticket (loop per ticket — descending order)\");",
                              "} else {",
                              "    pm.environment.unset(\"ticket_loop_idx\");",
                              "}"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Ticket (assert CANCELED) (loop per ticket — descending order)",
                      "id": "180f9a00-a9eb-434a-afef-e8d9cf7e75fc",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/tickets/{{current_ticket}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "tickets",
                            "{{current_ticket}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "prerequest",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "const nums = JSON.parse(pm.environment.get(\"all_ticket_numbers\") || \"[]\");",
                              "const idx = parseInt(pm.environment.get(\"cancel_check_idx\") || \"0\");",
                              "pm.environment.set(\"current_ticket\", nums[idx]);",
                              "pm.environment.set(\"cancel_check_idx\", String(idx + 1));"
                            ]
                          }
                        },
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "pm.test(\"ticket_status is CANCELED\", () => {",
                              "    pm.expect(pm.response.json().ticket_status).to.equal(\"CANCELLED\");",
                              "});",
                              "const nums = JSON.parse(pm.environment.get(\"all_ticket_numbers\") || \"[]\");",
                              "const idx = parseInt(pm.environment.get(\"cancel_check_idx\") || \"0\");",
                              "if (idx < nums.length) {",
                              "    postman.setNextRequest(\"Get Ticket (assert CANCELED) (loop per ticket — descending order)\");",
                              "} else {",
                              "    pm.environment.unset(\"cancel_check_idx\");",
                              "}"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Cancel Booking",
                      "id": "e002e426-deb5-407c-96c2-52fb467842f1",
                      "request": {
                        "method": "DELETE",
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200 or 204\", () => {",
                              "    pm.expect(pm.response.code).to.be.oneOf([200, 204]);",
                              "});"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "name": "Get Booking (assert CANCELLED)",
                      "id": "0492c82c-1ad9-47ea-a96f-f2ababe027cf",
                      "request": {
                        "method": "GET",
                        "url": {
                          "raw": "{{url}}/bookings/{{booking_id}}",
                          "host": [
                            "{{url}}"
                          ],
                          "path": [
                            "bookings",
                            "{{booking_id}}"
                          ]
                        },
                        "auth": {
                          "type": "bearer",
                          "bearer": [
                            {
                              "key": "token",
                              "value": "{{access_token}}",
                              "type": "string"
                            }
                          ]
                        }
                      },
                      "event": [
                        {
                          "listen": "test",
                          "script": {
                            "type": "text/javascript",
                            "exec": [
                              "pm.test(\"status 200\", () => pm.response.to.have.status(200));",
                              "if (pm.response.code !== 200) { pm.execution.setNextRequest(null); }",
                              "pm.test(\"booking_status is CANCELLED\", () => {",
                              "    pm.expect(pm.response.json().booking.booking_status, \"booking_status\").to.equal(\"CANCELLED\");",
                              "});"
                            ]
                          }
                        }
                      ]
                    }
                  ]
                }
              ],
              "id": "53a571e0-c267-480a-b423-bb12f658d5e9"
            }
          ],
          "id": "45810878-4c4b-428d-bf2d-2d4c477e61e7"
        }
      ]
    }
  ],
  "auth": {
    "type": "bearer"
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// Inject x-api-key header for every request except /oauth/token.",
          "const isOAuthToken = pm.request.url.toString().includes('/oauth/token');",
          "if (!isOAuthToken) {",
          "    const apiKey = pm.environment.get('api_key') || pm.variables.get('api_key');",
          "    if (apiKey) {",
          "        pm.request.headers.upsert({ key: 'x-api-key', value: apiKey });",
          "    }",
          "}"
        ]
      }
    },
    {
      "listen": "test",
      "script": {
        "type": "text/javascript",
        "exec": [
          ""
        ]
      }
    }
  ],
  "variable": [
    {
      "key": "id",
      "value": "1",
      "disabled": true
    },
    {
      "key": "base_url",
      "value": "https://postman-rest-api-learner.glitch.me/",
      "disabled": true
    },
    {
      "key": "number",
      "value": "5774995096800"
    },
    {
      "key": "passenger_ids",
      "value": ""
    },
    {
      "key": "ticket_numbers",
      "value": ""
    },
    {
      "key": "booking_total",
      "value": ""
    },
    {
      "key": "slice_token_1",
      "value": ""
    },
    {
      "key": "slice_token_2",
      "value": ""
    },
    {
      "key": "pax_group_1",
      "value": ""
    },
    {
      "key": "pax_group_2",
      "value": ""
    },
    {
      "key": "total_group_1",
      "value": ""
    },
    {
      "key": "total_group_2",
      "value": ""
    },
    {
      "key": "tickets_emission_1",
      "value": ""
    }
  ]
}