Destinationless Bookings
Overview
Hubby now supports destinationless bookings, allowing customers to make reservations without specifying a destination upfront. This feature streamlines the booking process and provides more flexibility for customers.
How It Works
Initial Booking Process
- Customers can make a booking without selecting a destination
- The booking process starts with redeeming a promo code
- After successful promo code redemption, customers are presented with a destination selection screen
Destination Selection
- Customers are shown a curated list of available destinations
- Only whitelisted destinations for the specific customer are displayed
- This ensures customers can only select destinations they are authorized to book
Whitelisting Process
- Destinations are whitelisted per customer
- The whitelist is managed by the system administrator
- This provides control over which destinations each customer can access
Benefits
- Simplified initial booking process
- Controlled access to destinations
- Flexible destination selection after booking
- Improved user experience with a streamlined workflow
Technical Implementation
The destinationless booking feature is implemented through our API, allowing for seamless integration with existing booking systems. The whitelisting mechanism ensures secure and controlled access to destinations while maintaining flexibility in the booking process.
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.
Code Example
Here's an example of how to implement a destinationless booking:
import crypto from 'crypto';
// Configuration
const API_SECRET = 'your_api_secret';
const API_KEY = 'your_api_key';
// Use staging for development, production for live
const BASE_URL = process.env.NODE_ENV === 'production'
? 'https://api.hubbyesim.com/api'
: 'https://api-staging.hubby.dev/api';
// Generate HMAC signature for authentication
function generateSignature(timestamp: string, method: string, path: string): string {
const payload = `${timestamp}${method}${path}`;
return crypto
.createHmac('sha256', API_SECRET)
.update(payload)
.digest('hex');
}
// Generate API headers
function generateHeaders(method: string, path: string) {
const timestamp = Math.floor(Date.now() / 1000).toString();
const signature = generateSignature(timestamp, method, path);
return {
'x-api-key': API_KEY,
'x-timestamp': timestamp,
'x-signature': signature,
'Content-Type': 'application/json'
};
}
// Create a destinationless booking
async function createDestinationlessBooking(promoCode: string) {
const path = '/api/bookings';
const method = 'POST';
const response = await fetch(`${BASE_URL}${path}`, {
method,
headers: generateHeaders(method, path),
body: JSON.stringify({
departure_date: new Date().toISOString(),
package_specifications: [], // Empty array for destinationless booking
promo_code: promoCode
})
});
return response.json();
}
// Get available packages for a country
async function getCountryPackages(countryCode: string) {
const path = `/api/countries/${countryCode}/packages`;
const method = 'GET';
const response = await fetch(`${BASE_URL}${path}`, {
method,
headers: generateHeaders(method, path)
});
return response.json();
}
// Update booking with selected package
async function updateBookingWithPackage(bookingId: string, packageId: string) {
const path = `/api/bookings/${bookingId}`;
const method = 'PUT';
const response = await fetch(`${BASE_URL}${path}`, {
method,
headers: generateHeaders(method, path),
body: JSON.stringify({
package_specifications: [{
package_id: packageId
}]
})
});
return response.json();
}
// Example usage
async function handleDestinationlessBooking() {
try {
// 1. Create the booking with promo code
const booking = await createDestinationlessBooking('PROMO123');
// 2. Get available packages for a specific country
// Note: In a real application, you would get the list of whitelisted countries
// from your backend and let the user select one
const { data: countryPackages } = await getCountryPackages('US');
// 3. Let user select a package from the available options
const selectedPackage = countryPackages[0]; // In real app, this would be user selection
// 4. Update booking with selected package
const updatedBooking = await updateBookingWithPackage(booking.data.id, selectedPackage.id);
console.log('Booking completed:', updatedBooking);
} catch (error) {
console.error('Error in booking process:', error);
}
}This example demonstrates:
- Proper HMAC authentication using the API secret
- Creating a destinationless booking with a promo code
- Retrieving available packages for a specific country
- Updating the booking with the selected package
- Error handling for the entire process
The API endpoints support this workflow by:
- Allowing bookings without package specifications
- Providing country-specific package listings
- Supporting package selection after the initial booking