The Holibob API - Payment Flow
Introduction
To enable Holibob as the Merchant on Record, API partners must integrate their client site with the Stripe payment flow. This integration requires configuring the partner channel on the Holibob system with a payment type set to REQUIRED. The integration process involves two primary steps: fetching a Stripe Payment Intent via a GraphQL query and using this intent to render the Stripe payment form on the frontend. This document provides a detailed guide on implementing these steps to ensure seamless payment processing.
Stripe Payment Flow

Integration Guide
Overview
This guide explains how to integrate with Holibob's Stripe payment processing system. The integration involves two main steps:
Fetching a Stripe Payment Intent from our API
Using the Payment Intent to render the Stripe payment form on your frontend
Step 1: Fetching the Payment Intent
GraphQL Query
To get a Stripe Payment Intent, make a GraphQL query to our API:
query PaymentIntent($bookingSelector: BookingSelector!) {
stripePaymentIntent(bookingSelector: $bookingSelector) {
id
amount
clientSecret
apiKey
createdAt
}
}
Parameters
bookingSelector
: An object containing the booking ID
{
id: string // The booking ID
}
Response
The response will contain:
id
: The Stripe Payment Intent IDamount
: Amount to be charged in minor unitsclientSecret
: Unique secret generated per Stripe intentapiKey
: Stripe public keycreatedAt
: When the payment intent was created
Step 2: Implementing the Payment Form
For the most up-to-date documentation, refer to the official Stripe docs linked below. Otherwise, you can continue by following our internal React integration guide.
Stripe Documentation
React Integration → https://github.com/stripe/react-stripe-js?tab=readme-ov-file
Component Demo → https://checkout.stripe.dev/
Prerequisites
Install the required Stripe packages:
npm install @stripe/stripe-js @stripe/react-stripe-js
Implementation Steps
Initialise Stripe with the API key:
import { loadStripe } from '@stripe/stripe-js';
const stripePromise = loadStripe(apiKey);
Wrap your payment form with the Stripe Elements provider:
import { Elements } from '@stripe/react-stripe-js';
<Elements
stripe={stripePromise}
options={{
clientSecret,
locale: 'en' // Optional: Set the locale for Stripe Elements
}}
>
{/* Your payment form components */}
</Elements>
Create a payment form with the Card Element:
import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
const PaymentForm = () => {
const stripe = useStripe();
const elements = useElements();
const [error, setError] = useState(null);
const [processing, setProcessing] = useState(false);
const handleSubmit = async (event) => {
event.preventDefault();
if (!stripe || !elements) {
return;
}
setProcessing(true);
const result = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement)!,
},
});
if (result.error) {
setError(result.error.message);
setProcessing(false);
} else {
// Payment succeeded
if (result.paymentIntent.status === 'succeeded') {
// Handle successful payment
}
}
};
return (
<form onSubmit={handleSubmit}>
<CardElement />
{error && <div>{error}</div>}
<button disabled={!stripe || processing}>
{processing ? 'Processing...' : 'Pay'}
</button>
</form>
);
};
Error Handling
If you attempt to commit a booking without satisfying the payment requirements, you will receive the following error:
BookingCommitError: Cannot commit booking without paymentIntent
Example Error Response
{
"errors": [
{
"message": ""Cannot commit booking. Booking availability \"3MNZV2\" does not have paymentIntent.",
"extensions": {
"code": "BOOKING_COMMIT_ERROR",
"http": {
"status": 400
}
}
}
]
}
Sandbox vs Production
When bookings are made in sandbox mode, Holibob surfaces Stripe test credentials via the stripePaymentIntent
GraphQL query. This allows you to simulate the full payment experience without charging real money.
In contrast, live bookings made in production will use live Stripe credentials, resulting in actual charges to customer cards.
Testing
Use Stripe's test card numbers for testing:
Success: 4242 4242 4242 4242
Decline: 4000 0000 0000 0002
Insufficient: 4000 0000 0000 9995
3D Secure: 4000 0025 0000 3155