Booking Request Component
The booking request component takes a quote and outputs a booked trip or an error when booking the quote.
iOS Sample
Payment flow handling
The booking request component requires a URL scheme to be set for the braintree SDK to fully manage 3DSecure payment flows. Please follow this guide for adding a URL Scheme to successfully handle app switching for the iOS implementation.
The booking request is implemented as a ViewController to automatically handle the presentation, dismissal and handling of the payment flow.
private var bookingStatus = KarhooBookingStatus.shared
let bookingScreenBuilderResult = KarhooUI().screens()
.bookingRequest()
.buildBookingScreen(quote: quote,
bookingDetails: bookingStatus.getBookingDetails()!,
bookingMetadata: nil,
callback: { [weak self] result in
if let bookingResult = result.completedValue() {
switch bookingResult {
case .tripAllocated(let trip): // user booked a trip
case .bookingFailed(let error): // there was an error booking a trip
case .prebookConfirmed(let trip, let prebookAction): // the user prebooked a trip for a later date
}
}
})
guard let bookingScreen = bookingScreenBuilderResult.screen() else {
print("error building karhoo booking screen: \(bookingScreenBuilderResult.error())")
return
}
bookingScreen.modalPresentationStyle = .fullScreen
self.present(bookingScreen)
Android Sample
Add the View to your layout
<com.karhoo.uisdk.screen.booking.booking.bookingrequest.BookingRequestView
android:id="@+id/booking_request_widget"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
Initialise the View in your Activity or Fragment. Example shown below is for a Fragment.
//Instantiate BookingQuotesViewModel
private lateinit var bookingQuotesViewModel: BookingQuotesViewModel by lazy {
ViewModelProvider(this).get(BookingStatusStateViewModel::class.java)
}
//Instantiate BookingStatusStateViewModel
private val bookingStatusStateViewModel: BookingStatusStateViewModel by lazy {
ViewModelProvider(this).get(BookingStatusStateViewModel::class.java)
}
//Instantiate BookingRequestStateViewModel
private lateinit var bookingRequestStateViewModel: BookingRequestStateViewModel by lazy {
ViewModelProvider(this).get(BookingRequestStateViewModel::class.java)
}
private var quote: Quote? = null
Bind the Views and observe the outputs
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//Setup the Booking Request Component
booking_request_widget.apply {
bindViewToBookingStatus(requireActivity(), bookingStatusStateViewModel)
bindViewToBookingRequest(requireActivity(), bookingRequestStateViewModel)
}
//Set up the observer for the actions and outputs
bookingQuotesViewModel.viewStates().observe(owner, createQuoteObservable())
bookingRequestStateViewModel.viewActions().observe(this, bindToBookingRequestOutputs())
}
private fun createQuoteObservable(): Observer<QuoteListStatus> {
return Observer { it ->
it.let { quote ->
val selectedQuote = quote.selectedQuote
this.quote = selectedQuote
this.quote?.let {
booking_request_widget?.showBookingRequest(it, null)
}
}
}
}
private fun bindToBookingRequestOutputs(): Observer<in BookingRequestViewContract.BookingRequestAction> {
return Observer { actions ->
when (actions) {
is BookingRequestViewContract.BookingRequestAction.ShowTermsAndConditions -> {
//Use the url to show the user the terms and conditions e.g.
val intent = Intent(context, WebActivity::class.java)
intent.putExtra(EXTRA_URL, actions.url)
startActivity(intent)
}
is BookingRequestViewContract.BookingRequestAction.WaitForTripAllocation ->
//Handle the wait when the booking has been made and the driver allocation is in progress
waitForTripAllocation()
is BookingRequestViewContract.BookingRequestAction.HandleBookingError ->
//Handle errors
showErrorDialog(actions.stringId)
}
}
}
Handle the payment result returned by Braintree
//You will need to call this from the Activity if you're not using fragments
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQ_CODE_BRAINTREE || requestCode == REQ_CODE_BRAINTREE_GUEST || requestCode == AdyenPaymentView.REQ_CODE_ADYEN) {
booking_request_widget.onActivityResult(requestCode, resultCode, data)
}
}
companion object {
const val REQ_CODE_BRAINTREE = 301
const val REQ_CODE_BRAINTREE_GUEST = 302
}
Updated over 3 years ago
What’s Next