# Your First Amadeus Booking - Step by Step Tutorial

This tutorial will walk you through creating your first flight booking using the Amadeus API integration.

## Prerequisites

- ✅ Application running (`docker-compose up -d`)
- ✅ Amadeus credentials configured (run `./setup-amadeus.sh`)
- ✅ Keycloak configured with superadmin user

---

## Step 1: Get Authentication Token

First, you need to authenticate with your application:

```bash
TOKEN=$(curl -s -X POST "http://localhost:8080/realms/b2b-flight-platform/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=superadmin" \
  -d "password=admin123" \
  -d "grant_type=password" \
  -d "client_id=b2b-flight-backend" \
  -d "client_secret=b2b-flight-backend-secret" | jq -r '.access_token')

echo "Token: $TOKEN"
```

**Expected Output**: A long JWT token string

---

## Step 2: Search for Flights

Let's search for a round-trip flight from Madrid to New York:

```bash
SEARCH_RESPONSE=$(curl -s -X POST "http://localhost:8081/api/v1/flights/search" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "originLocationCode": "MAD",
    "destinationLocationCode": "NYC",
    "departureDate": "2026-03-15",
    "returnDate": "2026-03-22",
    "adults": 1,
    "children": 0,
    "infants": 0,
    "travelClass": "ECONOMY",
    "currencyCode": "EUR",
    "max": 5
  }')

echo "$SEARCH_RESPONSE" | jq '.'
```

**What You'll See**:
- List of available flight offers
- Prices in EUR
- Flight details (airline, departure/arrival times)
- Number of available seats

**Save the first offer ID**:
```bash
OFFER_ID=$(echo "$SEARCH_RESPONSE" | jq -r '.data[0].id')
echo "Selected Offer ID: $OFFER_ID"
```

---

## Step 3: Get Fare Rules (Optional but Recommended)

Before booking, check the fare rules:

```bash
curl -s -X GET "http://localhost:8081/api/v1/flights/fare-rules/$OFFER_ID" \
  -H "Authorization: Bearer $TOKEN" | jq '.'
```

**What You'll See**:
- Cancellation policy
- Change fees
- Baggage allowance
- Refund conditions

---

## Step 4: Create Agency (If Not Already Created)

You need an agency to make bookings:

```bash
AGENCY_RESPONSE=$(curl -s -X POST "http://localhost:8081/api/v1/agencies" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Test Travel Agency",
    "matriculeNumber": "TEST001",
    "contactEmail": "agency@test.com",
    "contactPhone": "+34612345678",
    "subscriptionType": "MONTHLY",
    "markupPercentage": 5.0
  }')

AGENCY_ID=$(echo "$AGENCY_RESPONSE" | jq -r '.id')
echo "Agency ID: $AGENCY_ID"
```

---

## Step 5: Verify Agency

The agency must be verified before making bookings:

```bash
curl -s -X POST "http://localhost:8081/api/v1/agencies/$AGENCY_ID/verify" \
  -H "Authorization: Bearer $TOKEN" | jq '.'
```

---

## Step 6: Create Booking

Now let's create the booking with passenger details:

```bash
BOOKING_RESPONSE=$(curl -s -X POST "http://localhost:8081/api/v1/bookings" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"agencyId\": \"$AGENCY_ID\",
    \"flightOfferId\": \"$OFFER_ID\",
    \"passengers\": [{
      \"firstName\": \"JOHN\",
      \"lastName\": \"DOE\",
      \"dateOfBirth\": \"1990-01-15\",
      \"gender\": \"MALE\",
      \"email\": \"john.doe@example.com\",
      \"phone\": \"+34612345678\",
      \"passportNumber\": \"A12345678\",
      \"passportExpiry\": \"2030-12-31\",
      \"passportCountry\": \"ES\",
      \"nationality\": \"ES\"
    }],
    \"contactEmail\": \"booking@test.com\",
    \"contactPhone\": \"+34612345678\"
  }")

echo "$BOOKING_RESPONSE" | jq '.'

BOOKING_ID=$(echo "$BOOKING_RESPONSE" | jq -r '.id')
echo "Booking ID: $BOOKING_ID"
```

**What You'll See**:
- Booking confirmation
- PNR (Passenger Name Record)
- Booking reference
- Status: PENDING_PAYMENT

---

## Step 7: Add Funds to Wallet

Before issuing the ticket, the agency needs funds:

```bash
# Get the booking price
BOOKING_PRICE=$(echo "$BOOKING_RESPONSE" | jq -r '.totalPrice')
echo "Booking Price: $BOOKING_PRICE EUR"

# Add funds to agency wallet (as SUPER_ADMIN)
curl -s -X POST "http://localhost:8081/api/v1/wallet/recharge" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"agencyId\": \"$AGENCY_ID\",
    \"amount\": 2000.00,
    \"currency\": \"EUR\",
    \"paymentMethod\": \"BANK_TRANSFER\",
    \"reference\": \"TEST-RECHARGE-001\"
  }" | jq '.'

# Approve the recharge
RECHARGE_ID=$(curl -s -X GET "http://localhost:8081/api/v1/wallet/recharge/pending" \
  -H "Authorization: Bearer $TOKEN" | jq -r '.[0].id')

curl -s -X POST "http://localhost:8081/api/v1/wallet/recharge/$RECHARGE_ID/approve" \
  -H "Authorization: Bearer $TOKEN" | jq '.'
```

---

## Step 8: Issue Ticket

Now issue the ticket:

```bash
TICKET_RESPONSE=$(curl -s -X POST "http://localhost:8081/api/v1/tickets/issue" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"bookingId\": \"$BOOKING_ID\"
  }")

echo "$TICKET_RESPONSE" | jq '.'

TICKET_NUMBER=$(echo "$TICKET_RESPONSE" | jq -r '.ticketNumber')
echo "Ticket Number: $TICKET_NUMBER"
```

**What You'll See**:
- Ticket number (e.g., 157-1234567890)
- Ticket status: ISSUED
- Booking status updated to CONFIRMED
- Wallet balance deducted

---

## Step 9: Retrieve Ticket Details

Check the ticket details:

```bash
curl -s -X GET "http://localhost:8081/api/v1/tickets/$TICKET_NUMBER" \
  -H "Authorization: Bearer $TOKEN" | jq '.'
```

---

## Step 10: Void or Refund (Optional)

### Option A: Void Ticket (Within 24 hours, no penalty)

```bash
curl -s -X POST "http://localhost:8081/api/v1/tickets/$TICKET_NUMBER/void" \
  -H "Authorization: Bearer $TOKEN" | jq '.'
```

### Option B: Refund Ticket (After 24 hours, with penalties)

```bash
curl -s -X POST "http://localhost:8081/api/v1/tickets/$TICKET_NUMBER/refund" \
  -H "Authorization: Bearer $TOKEN" | jq '.'
```

---

## Complete Script

Here's the complete script to run all steps:

```bash
#!/bin/bash

echo "=== Amadeus First Booking Tutorial ==="
echo ""

# Step 1: Get Token
echo "Step 1: Getting authentication token..."
TOKEN=$(curl -s -X POST "http://localhost:8080/realms/b2b-flight-platform/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=superadmin" \
  -d "password=admin123" \
  -d "grant_type=password" \
  -d "client_id=b2b-flight-backend" \
  -d "client_secret=b2b-flight-backend-secret" | jq -r '.access_token')
echo "✅ Token obtained"
echo ""

# Step 2: Search Flights
echo "Step 2: Searching for flights..."
SEARCH_RESPONSE=$(curl -s -X POST "http://localhost:8081/api/v1/flights/search" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "originLocationCode": "MAD",
    "destinationLocationCode": "NYC",
    "departureDate": "2026-03-15",
    "returnDate": "2026-03-22",
    "adults": 1,
    "travelClass": "ECONOMY",
    "currencyCode": "EUR",
    "max": 5
  }')
OFFER_ID=$(echo "$SEARCH_RESPONSE" | jq -r '.data[0].id')
OFFER_PRICE=$(echo "$SEARCH_RESPONSE" | jq -r '.data[0].price.total')
echo "✅ Found flights. Selected offer: $OFFER_ID (Price: $OFFER_PRICE EUR)"
echo ""

# Step 3: Create Agency
echo "Step 3: Creating agency..."
AGENCY_RESPONSE=$(curl -s -X POST "http://localhost:8081/api/v1/agencies" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Test Travel Agency",
    "matriculeNumber": "TEST001",
    "contactEmail": "agency@test.com",
    "contactPhone": "+34612345678",
    "subscriptionType": "MONTHLY",
    "markupPercentage": 5.0
  }')
AGENCY_ID=$(echo "$AGENCY_RESPONSE" | jq -r '.id')
echo "✅ Agency created: $AGENCY_ID"
echo ""

# Step 4: Verify Agency
echo "Step 4: Verifying agency..."
curl -s -X POST "http://localhost:8081/api/v1/agencies/$AGENCY_ID/verify" \
  -H "Authorization: Bearer $TOKEN" > /dev/null
echo "✅ Agency verified"
echo ""

# Step 5: Create Booking
echo "Step 5: Creating booking..."
BOOKING_RESPONSE=$(curl -s -X POST "http://localhost:8081/api/v1/bookings" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"agencyId\": \"$AGENCY_ID\",
    \"flightOfferId\": \"$OFFER_ID\",
    \"passengers\": [{
      \"firstName\": \"JOHN\",
      \"lastName\": \"DOE\",
      \"dateOfBirth\": \"1990-01-15\",
      \"gender\": \"MALE\",
      \"email\": \"john.doe@example.com\",
      \"phone\": \"+34612345678\",
      \"passportNumber\": \"A12345678\",
      \"passportExpiry\": \"2030-12-31\",
      \"passportCountry\": \"ES\",
      \"nationality\": \"ES\"
    }],
    \"contactEmail\": \"booking@test.com\",
    \"contactPhone\": \"+34612345678\"
  }")
BOOKING_ID=$(echo "$BOOKING_RESPONSE" | jq -r '.id')
echo "✅ Booking created: $BOOKING_ID"
echo ""

# Step 6: Add Wallet Funds
echo "Step 6: Adding funds to wallet..."
curl -s -X POST "http://localhost:8081/api/v1/wallet/recharge" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"agencyId\": \"$AGENCY_ID\",
    \"amount\": 2000.00,
    \"currency\": \"EUR\",
    \"paymentMethod\": \"BANK_TRANSFER\",
    \"reference\": \"TEST-RECHARGE-001\"
  }" > /dev/null

RECHARGE_ID=$(curl -s -X GET "http://localhost:8081/api/v1/wallet/recharge/pending" \
  -H "Authorization: Bearer $TOKEN" | jq -r '.[0].id')

curl -s -X POST "http://localhost:8081/api/v1/wallet/recharge/$RECHARGE_ID/approve" \
  -H "Authorization: Bearer $TOKEN" > /dev/null
echo "✅ Wallet funded with 2000 EUR"
echo ""

# Step 7: Issue Ticket
echo "Step 7: Issuing ticket..."
TICKET_RESPONSE=$(curl -s -X POST "http://localhost:8081/api/v1/tickets/issue" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"bookingId\": \"$BOOKING_ID\"
  }")
TICKET_NUMBER=$(echo "$TICKET_RESPONSE" | jq -r '.ticketNumber')
echo "✅ Ticket issued: $TICKET_NUMBER"
echo ""

# Summary
echo "=== Booking Complete! ==="
echo ""
echo "Agency ID: $AGENCY_ID"
echo "Booking ID: $BOOKING_ID"
echo "Ticket Number: $TICKET_NUMBER"
echo "Price: $OFFER_PRICE EUR"
echo ""
echo "View ticket details:"
echo "curl -X GET \"http://localhost:8081/api/v1/tickets/$TICKET_NUMBER\" \\"
echo "  -H \"Authorization: Bearer $TOKEN\" | jq '.'"
echo ""
```

Save this as `first-booking-tutorial.sh` and run it!

---

## Troubleshooting

### Error: "Agency not verified"
**Solution**: Make sure you ran Step 5 to verify the agency

### Error: "Insufficient wallet balance"
**Solution**: Make sure you added and approved wallet funds in Step 7

### Error: "Flight offer not found"
**Solution**: The offer might have expired. Run Step 2 again to get a fresh offer

### Error: "Invalid passenger data"
**Solution**: Check that all required fields are provided and dates are in correct format (YYYY-MM-DD)

---

## Next Steps

1. **Explore Swagger UI**: http://localhost:8081/swagger-ui.html
2. **Read Full Guide**: `docs/AMADEUS_INTEGRATION_GUIDE.md`
3. **Check Quick Reference**: `docs/AMADEUS_QUICK_REFERENCE.md`
4. **Monitor Your System**: `curl http://localhost:8081/actuator/health`

---

## Congratulations! 🎉

You've successfully completed your first booking using the Amadeus API integration!

**What you learned**:
- ✅ How to search for flights
- ✅ How to create agencies
- ✅ How to create bookings
- ✅ How to manage wallet funds
- ✅ How to issue tickets
- ✅ How to void/refund tickets

**Ready for production?**
- Get production Amadeus credentials
- Update `.env` with production URL and credentials
- Test thoroughly in test environment first
- Set up monitoring and alerts
- Review security best practices

---

**Last Updated**: January 2026
