Customer Package Choice
This guide demonstrates how to integrate Hubby eSIM into your airline booking flow, allowing customers to choose their preferred data package and managing the communication flow through your existing channels.
Overview
In this integration pattern:
- Your system fetches available packages for the destination
- Customer selects their preferred package during booking
- Booking is created with the specific package ID
- You receive a promo code to include in your booking confirmation email
- Customer redeems the code in the Hubby app
Prerequisites
- A Hubby Partner account with API access
- Your API credentials (public key and secret)
- Ability to modify your booking flow UI
- Email template system for confirmation emails
API Endpoints
Hubby provides two API endpoints for different environments:
- Production:
https://api.hubbyesim.com/api- Use this for live applications - Staging:
https://api-staging.hubby.dev/api- Use this for testing and development
Always test thoroughly in staging before using production.
Implementation Steps
1. Authentication Setup
First, implement the HMAC authentication system:
const crypto = require('crypto');
function generateHeaders(method, path, timestamp) {
const payload = timestamp + method + path;
const signature = crypto
.createHmac('sha256', process.env.HUBBY_API_SECRET)
.update(payload)
.digest('hex');
return {
'x-api-key': process.env.HUBBY_API_KEY,
'x-timestamp': timestamp,
'x-signature': signature,
'Content-Type': 'application/json'
};
}2. Fetching Available Packages
When a customer books a flight, fetch the available packages for their destination:
// Use staging for development, production for live
const API_BASE_URL = process.env.NODE_ENV === 'production'
? 'https://api.hubbyesim.com'
: 'https://api-staging.hubby.dev';
async function getPackagesForCountry(countryCode) {
const timestamp = Date.now().toString();
const path = `/api/countries/${countryCode}/packages`;
const response = await fetch(`${API_BASE_URL}${path}`, {
method: 'GET',
headers: generateHeaders('GET', path, timestamp)
});
const data = await response.json();
if (data.success) {
// Format packages for display
return data.data[countryCode].map(package => ({
id: package.id,
label: package.label,
size: package.bytes,
price: package.price,
validity: package.days
}));
}
throw new Error('Failed to fetch packages');
}3. Package Selection UI
Example React component for package selection:
function PackageSelector({ countryCode, onSelect }) {
const [packages, setPackages] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function loadPackages() {
try {
const packages = await getPackagesForCountry(countryCode);
setPackages(packages);
} catch (err) {
setError('Failed to load packages');
} finally {
setLoading(false);
}
}
loadPackages();
}, [countryCode]);
if (loading) return <div>Loading packages...</div>;
if (error) return <div>{error}</div>;
return (
<div className="package-grid">
{packages.map(pkg => (
<div key={pkg.id} className="package-card">
<h3>{pkg.label}</h3>
<p>Valid for {pkg.validity} days</p>
<p>Price: ${pkg.price}</p>
<button onClick={() => onSelect(pkg)}>
Select Package
</button>
</div>
))}
</div>
);
}4. Creating the Booking
Once a package is selected, create the booking with the specific package ID:
async function createEsimBooking(bookingData) {
const timestamp = Date.now().toString();
const path = '/api/bookings';
const response = await fetch(`${API_BASE_URL}/api/bookings`, {
method: 'POST',
headers: generateHeaders('POST', path, timestamp),
body: JSON.stringify({
booking_id: bookingData.bookingId,
departure_date: bookingData.flightDate,
email: bookingData.customerEmail,
first_name: bookingData.firstName,
last_name: bookingData.lastName,
package_specifications: [{
destination: bookingData.countryCode,
package_id: bookingData.selectedPackageId // When set, this spec is resolved only by this ID; other fields in this entry are ignored
}],
communication_options: {
should_send_message: false // We'll handle communication
}
})
});
return await response.json();
}5. Handling the Response and Email Integration
async function handleBookingAndSendEmail(bookingResponse, emailTemplate) {
if (bookingResponse.success) {
const promoCode = bookingResponse.data.promo_codes[0].promo_code;
// Store the Hubby booking reference
await updateFlightBooking({
hubbyBookingId: bookingResponse.data.id,
promoCode: promoCode
});
// Add eSIM details to confirmation email
const emailContent = emailTemplate.replace(
'{{ESIM_DETAILS}}',
`
Your eSIM Promo Code: ${promoCode}
To activate your eSIM:
1. Download the Hubby app
2. Enter your promo code
3. Follow the installation instructions
`
);
await sendConfirmationEmail(emailContent);
} else {
// Handle error cases
console.error('Booking creation failed:', bookingResponse.error);
}
}Complete Integration Example
Here's how to put it all together in your booking flow:
const express = require('express');
const router = express.Router();
router.post('/flight-bookings', async (req, res) => {
try {
// 1. Create flight booking
const flightBooking = await createFlightBooking(req.body);
// 2. If eSIM was selected
if (req.body.includeEsim) {
// 3. Create Hubby eSIM booking
const esimBooking = await createEsimBooking({
bookingId: flightBooking.id,
flightDate: flightBooking.departureDate,
customerEmail: flightBooking.customerEmail,
firstName: flightBooking.firstName,
lastName: flightBooking.lastName,
countryCode: flightBooking.destination,
selectedPackageId: req.body.selectedPackageId
});
// 4. Handle response and send email
await handleBookingAndSendEmail(
esimBooking,
flightBookingEmailTemplate
);
}
// 5. Return success to customer
res.json({
success: true,
message: 'Flight booked! Check your email for details.'
});
} catch (error) {
res.status(500).json({
success: false,
error: 'Booking failed. Please try again.'
});
}
});Best Practices
- Cache Package Data: Cache package information for short periods to reduce API calls
- Clear Presentation: Display package options clearly with size, validity, and price
- Error Handling: Implement fallbacks if package fetching fails
- Email Templates: Create clear instructions for eSIM activation in emails
- Promo Code Storage: Securely store promo codes for customer service purposes
Monitoring and Support
Monitor your integration using:
- Package selection rates
- Booking success rates
- Promo code redemption rates
- Customer support inquiries
Contact support@hubbyesim.com for:
- Custom package configurations
- Integration support
- API optimization