Implementation Guides

Adding Extra Bags

note

The ability to book baggage with your flight is not available for all airlines yet. We recommend using British Airways offers to follow along on this guide.


What do you need to start?

This guide will go through the changes you need to make in the booking flow to be able to list and book services for any offer you want. It's important you know the basics of how to create a booking.
  • If you are not familiar with how to create an order please heads over to our Quick Start Guide.

  • This guide will start from an offer so make sure you grab an offer ID for a British Airways flight before we start.

tip

We've put together a Postman Collection that contains all of the requests you'll need to follow along with this guide.


Overview

Baggages are a type of what we call available_services. Available services are specific to an offer but not surfaced through the API by default. The changes we'll make to work with available services are:
  • Retrieve an offer along with its available_services

  • Include services to order creation

  • See the services booked on an order


Getting services for an offer

We start by fetching the offer to make sure to get its most up to date information. The get offer endpoint gives you the ability to retrieve available services with the offer by applying the query param return_available_services set to true. Using a valid offer id you can use:

Shell

curl -X GET --compressed "https://api.duffel.com/air/offers/
$OFFER_ID
?return_available_services=true"
-H "Accept-Encoding: gzip"
-H "Accept: application/json"
-H "Duffel-Version: beta"
-H "Authorization: Bearer
$YOUR_ACCESS_TOKEN
"
This request will return an offer which now include the available_services attribute.

Available services

The only available service currently supported is baggages. Wi-fi and meals are a couple of the options we aim to support in the near future. Each available service is unique and identifiable by id. The price of the service is described by total_currency and total_amount. And the actual service information is determined by its type and metadata.
Important to notice that services are specific to segments and passengers. The relationship is described by the attributes segment_ids and passenger_ids.

Learn more

For a complete description of the available services schema checkout the API reference.

Booking with services

Once you know what offer and service a user wants to book all you have to send request to the create order endpoint with 2 small changes to the payload.

Shell

curl -X POST --compressed "https://api.duffel.com/air/orders"
-H "Accept-Encoding: gzip"
-H "Accept: application/json"
-H "Content-Type: application/json"
-H "Duffel-Version: beta"
-H "Authorization: Bearer
$YOUR_ACCESS_TOKEN
"
-d '{
"data": {
"selected_offers": ["'"$OFFER_ID"'"],
"payments": [
{
"type": "balance",
"currency": "'"$TOTAL_CURRENCY"'",
"amount": "'"$TOTAL_AMOUNT"'"
}
],
"passengers": [
{
"phone_number": "+442080160508",
"email": "tony@example.com",
"born_on": "1980-07-24",
"title": "mr",
"gender": "m",
"family_name": "Stark",
"given_name": "Tony",
"infant_passenger_id": "'"$INFANT_PASSENGER_ID"'",
"id": "'"$ADULT_PASSENGER_ID_1"'"
},
{
"phone_number": "+442080160509",
"email": "potts@example.com",
"born_on": "1983-11-02",
"title": "mrs",
"gender": "m",
"family_name": "Potts",
"given_name": "Pepper",
"id": "'"$ADULT_PASSENGER_ID_2"'"
},
{
"phone_number": "+442080160506",
"email": "morgan@example.com",
"born_on": "2019-08-24",
"title": "mrs",
"gender": "f",
"family_name": "Stark",
"given_name": "Morgan",
"id": "'"$INFANT_PASSENGER_ID"'"
}
],
"services": [
{
"quantity": 2,
"id": "'"$SERVICE_ID_1"'"
},
{
"quantity": 1,
"id": "'"$SERVICE_ID_2"'"
}
]
}
}'
You must add the attribute services to your request payload. This field should contain a list of services to be book along with the offer specified in the selected_offers field. Each service on the list here must contain the available service id ($SERVICE_ID_N) and the desired quantity.
The payment amount ($TOTAL_AMOUNT) must be increased by the amount times quantity of each service you'd like to purchase. For example, if your offer total is 50 GBP and you include service A with quantity 2 and total_amount 10 GBP, the amount of the payment should now be 70 GBP.

Services on Order

Once the booking has gone through in the airline's system we will return the usual order create response payload to you. You can always retrieve your order by id:

Shell

curl -X GET --compressed "https://api.duffel.com/air/orders/
$ORDER_ID
"
-H "Accept-Encoding: gzip"
-H "Accept: application/json"
-H "Duffel-Version: beta"
-H "Authorization: Bearer
$YOUR_ACCESS_TOKEN
"

Services

The service object will look exactly the same as the available service expect for maximum_quantity being replaced with quantity. It's worth flagging that any ancillary baggages booked as services will not be present in the slices[].segments[].passengers[].baggages[]. They are only present in the services field. If you want the full picture of a passenger's baggage you will need to combine both.

Documents

Some airlines record the booking and the payment of ancillary services in a document different from the electronic ticket issued for the flight. These documents are called Electronic Miscellaneous Documents. When available we expose them in the API as a document with a type of electronic_miscellaneous_document_associated.

Learn more

For look at the services and documents schema, please visit our API reference:

Using the Additional Baggage UI component

We offer two Additional Baggage React components to simplify creating an order with additional baggages. Both components provide a responsive user interface for baggage selection that looks good on all screen sizes.
There are two ways you can integrate the Additional Baggage components into your application.

Import the Duffel Components library into your project using a package manager

To get started, import the package using your favourite package manager.

Shell (using yarn)

yarn add @duffel/components
Then import the preferred version of the additional baggage component to your application. We offer two versions of the component
  • AdditionalBaggageSelection (A complete component with an integrated passenger selection UI)

  • AdditionalBaggage (A standalone component, more suitable for usage with a specific passenger and a specific segment)


Use the UMD module (for non-React projects)

The Baggage Selection components can also be used in non-React projects. You'll use the Duffel Components UMD module, which bundles React, ReactDOM and other dependencies required for Baggage Selection to be rendered in your application.
First, you'll import the Duffel Components UMD module and CSS file and then create a placeholder node in your HTML for the component.
You'll then use DuffelComponents.renderAdditionalBaggageSelectionComponent (or DuffelComponents.renderAdditionalBaggageComponent for the standalone version) to render the component into your application, passing in the id of the placeholder node you created, as well as the required props for the corresponding component.

HTML

<!DOCTYPE html>
<html lang="en">
<head>
<title>
Duffel Components - example usage of Baggage components in non-React
project
</title>
<link
rel="stylesheet"
href="https://unpkg.com/@duffel/components@latest/dist/AdditionalBaggageSelection.min.css"
/>
<!-- or if you prefer a single-slice, single-passenger version -->
<link
rel="stylesheet"
href="https://unpkg.com/@duffel/components@latest/dist/AdditionalBaggage.min.css"
/>
</head>
<body class="container">
<h1>Baggages</h1>
<div id="target"></div>
<script
type="text/javascript"
src="https://unpkg.com/@duffel/components@latest/dist/AdditionalBaggageSelection.umd.min.js"
></script>
<script>
DuffelComponents.renderAdditionalBaggageSelectionComponent('target', {
offer: offer,
passengers: passengers,
onSubmit: onSubmitFn,
})
</script>
<!-- or if you prefer a single-slice, single-passenger version -->
<script
type="text/javascript"
src="https://unpkg.com/@duffel/components@latest/dist/AdditionalBaggage.umd.min.js"
></script>
<script>
DuffelComponents.renderAdditionalBaggageComponent('target', {
availableServices: availableServicesForPassenger,
additionalBaggage: selectedBaggage
onChange: onChangeFn
})
</script>
</body>
</html>
Please see below to see the difference between the two components.

Using the baggage selection component with an integrated passenger selection UI

AdditionalBaggageSelection will display all the passengers and the flights alongside the selection component.

To use this, import the component and its corresponding CSS into your application.

JavaScript

import { AdditionalBaggageSelection } from '@duffel/components'
import '@duffel/components/dist/AdditionalBaggageSelection.min.css'
Then, follow the steps in this guide to get an offer and its available services.
Each passenger will have a corresponding id assigned to them in the Offer. Their names can be added if you have them.

JavaScript

const passengers = [
{
id: 'pas_0000A8oTVsAt8YurG9h4xn',
name: 'Amelia Earhart',
},
{
id: 'pas_0000A8oTVsAt8YurG9h4xo',
name: 'Charles Lindbergh',
},
]
After retrieving those, you can pass them into the component. We advise wrapping the AdditionalBaggageSelection component in a modal as in the example below.

React

<YourModal>
<AdditionalBaggageSelection
offer={offer}
passengers={passengers}
onSubmit={onSubmitFn}
currencyConversion={currencyConversion} /* optional */
initialBaggageSelection={initialBaggageSelection} /* optional */
/>
</YourModal>
It may be helpful to reference the following example payloads during your integration.

Using the standalone passenger selection UI

If you prefer more flexibility or you would like to deal with the passenger selection logic yourself, we also offer a standalone component, AdditionalBaggage.

Similar to the above, import the component and its CSS into your application.

JavaScript

import { AdditionalBaggage } from '@duffel/components'
import '@duffel/components/dist/AdditionalBaggage.min.css'
AdditionalBaggage is a controlled component. The component accepts 3 props:
  • availableServices - all the available services with type: 'baggage' for this passenger and segment

  • additionalBaggages - the selected service ids and quantities

  • onChange - this function will be called with the updated list of baggages. This should update the state in the component and pass that state back into the additionalBaggages prop to reflect the change.

The component is designed to work for one passenger and one segment at a time. You will have to retrieve the available services from the offer as described above and filter them down before passing them into the component.

React

// This assumes that this state works with one passenger, and `availableServices` have been filtered down to only the ones involving the passenger.
// If multiple `AdditionalBaggage` component is updating the same state, the logic would be a little different.
const [additionalBaggages, setAdditionalBaggages] = React.useState([])
return (
<AdditionalBaggage
availableServices={availableServices}
additionalBaggages={additionalBaggages}
onChange={(updatedBaggages) => setAdditionalBaggages(updatedBaggages)}
/>
)

Displaying baggage prices in an alternative currency

You can also display baggage prices in a currency of your choice for your customer.
Pass in an additional currencyConversion prop to AdditionalBaggageSelection (or AdditionalBaggage) including the ISO 4217 currency type and conversion rate to use. The conversion rate provided will be applied to baggage prices in your organisation's default currency.
Please be aware that converted prices are for display purposes only. The amount to be paid to Duffel will be the original value in your organisation's default currency.
Example
  • 1 GBP = 10.69 HKD

  • For the carry on baggage, the original price in the organisation's currency is 25 GBP.

JavaScript

const currencyConversion = {
currency: 'HKD',
rate: 10.69,
}


Customising colours (optional)

CSS variables for colours are exposed and can be optionally overridden and customised to match your application's requirements. The full set of CSS colour variables are displayed below, however we recommend only overriding the --ACCENT colour. This should be in RGB format.
If you change the default accent colour, you'll want to check the resulting component's contrast to ensure it meets accessibility requirements.

CSS

--GREY-100: #f7f5f9;
--GREY-200: #e2e2e8;
--GREY-400: #ababb4;
--GREY-500: #86868e;
--GREY-600: #696972;
--GREY-700: #4b4b55;
--GREY-900: #29292e;
--BLACK: 0, 0, 0;
--WHITE: 255, 255, 255;
--ACCENT: 57, 111, 233;
--ACCENT-LIGHT-100: 0.08;
--ACCENT-LIGHT-200: 0.24;
--ACCENT-LIGHT-300: 0.48;
--ACCENT-LIGHT-1000: 1;

Keep Learning

Now you are able to include baggages to an order! Once we support more ancillary services you'll be able to rely on the same flow but apply it to other available service types. If you'd like to get a deeper look into the API reference to learn more you can jump to:
If you still haven't learned how to cancel an order we recommend looking at that next: