API: Cancel Booking

Important Notice

Based on the BookingController provided, there is no dedicated cancel endpoint implemented. Booking cancellation is typically handled through the update endpoint by modifying seat statuses or booking types.

Alternative Cancellation Methods

Method 1: Update Booking with Cancel Status

Use the update endpoint to mark seats as cancelled:

PUT /bookings/{id}
Request Body for Cancellation:

{
  "mobile": "01712345678",
  "name": "John Doe",
  "gender": "Male",
  "age": 30,
  "address": "123 Main Street, Dhaka",
  "passport_no": null,
  "nid": "1234567890123",
  "nationality": "Bangladeshi",
  "email": "john@example.com",
  "trip_id": 1,
  "type": 5,
  "date": "2025-08-18",
  "time": "10:00:00",
  "route_id": 1,
  "boarding_id": 1,
  "dropping_id": 2,
  "booking_details": [
    {
      "seat_inventory_id": 1,
      "seat_id": 1,
      "price": 1500,
      "discount": 50,
      "cancel_status": 1
    },
    {
      "seat_inventory_id": 2,
      "seat_id": 2,
      "price": 1500,
      "discount": 0,
      "cancel_status": 1
    }
  ]
}
                
Sample Response:

{
  "status": "success",
  "code": 200,
  "message": "Booking updated successfully",
  "data": {
    "booking": {
      "id": 5,
      "pnr_number": "L2DB92GFBG",
      "trip_id": 1,
      "type": 5,
      "date": "2025-08-18",
      "time": "10:00:00",
      "route_id": 1,
      "boarding_id": 1,
      "dropping_id": 2,
      "total_tickets": 0,
      "total_price": 0,
      "total_discount": 0,
      "total_amount": 0,
      "status": "updated",
      "updated_at": "2025-08-18T11:30:00.000000Z"
    },
    "customer": {
      "id": 1,
      "name": "John Doe",
      "mobile": "01712345678",
      "email": "john@example.com",
      "gender": "Male",
      "age": 30,
      "address": "123 Main Street, Dhaka",
      "passport_no": null,
      "nid": "1234567890123",
      "nationality": "Bangladeshi"
    },
    "boarding_info": {
      "id": 1,
      "trip_id": 1,
      "time": "08:00:00",
      "counter_id": 1,
      "counter_name": "Kallyanpur Counter",
      "counter_location": "Near Kallyanpur Bus Stand",
      "district_name": "Dhaka"
    },
    "dropping_info": {
      "id": 2,
      "trip_id": 1,
      "time": "14:00:00",
      "counter_id": 2,
      "counter_name": "GEC Counter",
      "counter_location": "GEC Circle",
      "district_name": "Chittagong"
    },
    "updated_seats": [],
    "seat_status_summary": {
      "total_seats_updated": 0,
      "seat_status": "cancelled",
      "payment_status": "refund_pending"
    }
  }
}
                

Method 2: Seat Inventory Release

The update process automatically:

  • Releases previously booked seats back to available status
  • Sets booking_id to null in seat inventory
  • Clears blocked_until timestamps
  • Updates seat status to STATUS_AVAILABLE

Cancellation Logic in Update Method

Seat Release Process
  1. Get existing booking details
  2. Release previously booked seats
  3. Set seat status to available
  4. Clear booking references
  5. Delete old booking details
Cancel Status Handling
  • cancel_status: 0 - Keep seat
  • cancel_status: 1 - Cancel seat
  • Only seats with cancel_status = 0 are processed
  • Cancelled seats are excluded from new booking

Recommended Implementation

For a proper cancellation API, consider implementing a dedicated cancel endpoint:

Proposed Cancel Endpoint:
DELETE /bookings/{id}/cancel
Proposed Request Body:

{
  "cancellation_reason": "Customer requested cancellation",
  "refund_amount": 2950,
  "cancellation_fee": 100,
  "net_refund": 2850
}
                

Current Workaround Process

  1. Step 1: Get booking details using GET /bookings/{id}
  2. Step 2: Prepare update request with cancel_status = 1 for all seats
  3. Step 3: Send PUT /bookings/{id} with empty booking_details or cancelled seats
  4. Step 4: Verify seats are released back to available status

Important Notes:

  • No Dedicated Cancel Endpoint - Use update method with cancel_status
  • Seat Release - Update method automatically releases previously booked seats
  • Partial Cancellation - Can cancel individual seats using cancel_status field
  • Complete Cancellation - Set cancel_status = 1 for all seats or use empty booking_details
  • Refund Handling - Not implemented in current controller, needs separate logic

Error Handling:

404 Not Found - Booking Not Found

{
  "status": "error",
  "code": 404,
  "message": "Booking not found",
  "data": null
}
                

JavaScript Example:


async function cancelBooking(bookingId) {
  try {
    // First get the current booking details
    const bookingResponse = await fetch(`/api/bookings/${bookingId}`, {
      headers: {
        'Authorization': 'Bearer your_token'
      }
    });

    if (!bookingResponse.ok) {
      throw new Error('Booking not found');
    }

    const booking = await bookingResponse.json();

    // Prepare cancellation request
    const cancelRequest = {
      ...booking.data.customer,
      trip_id: booking.data.booking.trip_id,
      type: 5, // Cancelled status
      date: booking.data.booking.date,
      time: booking.data.booking.time,
      route_id: booking.data.booking.route_id,
      boarding_id: booking.data.booking.boarding_id,
      dropping_id: booking.data.booking.dropping_id,
      booking_details: booking.data.booked_seats.map(seat => ({
        seat_inventory_id: seat.seat_inventory_id,
        seat_id: seat.seat_id,
        price: seat.price,
        discount: seat.discount,
        cancel_status: 1 // Cancel this seat
      }))
    };

    // Send update request for cancellation
    const cancelResponse = await fetch(`/api/bookings/${bookingId}`, {
      method: 'PUT',
      headers: {
        'Authorization': 'Bearer your_token',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(cancelRequest)
    });

    if (!cancelResponse.ok) {
      throw new Error('Failed to cancel booking');
    }

    const result = await cancelResponse.json();
    console.log('Booking cancelled successfully:', result);

    return result;
  } catch (error) {
    console.error('Error cancelling booking:', error);
    throw error;
  }
}

// Usage
cancelBooking(5)
  .then(result => {
    console.log('Cancellation completed:', result.data.seat_status_summary);
  })
  .catch(error => {
    console.error('Booking cancellation failed:', error.message);
  });