This tutorial is a guide on how you integrate a payment transaction into your 1-to-1 booking where the payment is handled by an external payment provider - in this example Stripe.
- You need to have an understanding of graphs/booking blueprints and actions described in this article.
- Be familiar with the tutorial series creating a booking, as this tutorial is basically just an extension.
- You will need an account with a payment provider, fx. Stripe.
Note: Before you get started it is important you know that Timekit does not receive payments, we only support that you can carry out a payment transaction with an external payment as a part of a booking. This is why you also need to integrate with a payment provider, in order to receive the actual payment. In this example, we will use Stripe.
As the examples in this tutorial might become out of date please check Stripe's own tutorial as reference.
This tutorial is based on an example where a customer, needs to pay up-front for booking a resource. In this example we will use the instant_payment graph which is a booking blueprint for 1-to-1 bookings that supports payments.
In short, the instant_payment graph is different from a 1-to-1 booking graph as it will instantly block the requested calendar time-slot and await a payment. It will unblock the slot again if the payment isn't registered within a predefined timeinterval, fx. 5 minutes.
Note: Payments is also possible with group bookings. Please see instructions further below.
Step 1: Create the booking with the instant_payment graph
curl --request POST \
--header 'Content-Type: application/json' \
--url https://api.timekit.io/v2/bookings \
--user :live_api_key_7nzvc7wsBQQISLeFSVhROys9V1bUJ1z7 \
"resource_id": The DeLorean's ID,
"what": "I want to book the DeLorean",
"where": "Sesame St, Middleburg, FL 32068, USA",
"description": "I want to try the trick you mentioned by getting the DeLorean to 88mph.",
"name": "Marty McFly",
This step is very similar to when you create a normal booking. The main difference is the "timeout" parameter, which defines how much time we will give the customer to complete his payment.
The timeout of 5 minutes, as defined above, is the default. Please configure this parameter to match your specific booking experience unless you're fine with 5 minutes.
Timekit will respond as described in the create booking tutorial, the important part being the id of the newly created booking:
As per the definition of the instant_payment graph, a timer is now running where we, in this example, have 5 minutes to set the booking as paid.
Step 2: Getting payment from your payment provider.
This step is where we'll use Stripe's checkout tutorial using PHP as the server-side language. So send a payment form to the customer:
<form action="charge.php" method="post">
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<?php echo $stripe['publishable_key']; ?>"
data-description="Payment for booking the Flux Capacitor"
In the charge.php file, capture the payment and register it on the booking:
Step 3: Registering the booking as paid.
Again copying from Stripe's tutorial:
$timekitBookingId = '58190fc6-1ec0-4ebb-b627-7ce6aa9fc703';
$timekitApiKey = 'live_api_key_7nzvc7wsBQQISLeFSVhROys9V1bUJ1z7';
$token = $_POST['stripeToken'];
$email = $_POST['stripeEmail'];
$customer = \Stripe\Customer::create(array(
'email' => $email,
'source' => $token
$charge = \Stripe\Charge::create(array(
'customer' => $customer->id,
'amount' => 5000,
'currency' => 'usd'
//This is where we register payment on the Timekit booking
$timekitPaymentData = json_encode(['pay' => ['payment_id' => $charge->id]]);
$ch = curl_init('https://api.timekit.io/v2/bookings/'.rawurlencode($timekitBookingId).'/pay');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_USERPWD, ":" . $timekitApiKey);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $timekitPaymentData);
//TODO: handle that more than 5 minutes has passed since the booking was created. Timekit will respond with a 422 status and an error message = "Cannot apply action 'pay' to current state 'unpaid'"
echo '<h1>Successfully charged $50.00!</h1>';
If the payment was received in time (within 5 minutes), the booking is now in the paid state and the booking is confirmed.
Decide the timeout that is right for your booking experience
What the right timeout setting is, will depend on your use-case. This means the risk of customers missing a booking because of a too short timeout that will make the resource available for bookings again, against the risk of "false" bookings like customers aborting the payment flow, their card getting declined, etc.
Payments in Group bookings
The same steps are required for bookings using the group_customer_payment graph when you need to make sure a customer pays for his/her booking of a seat in a class as described in the group bookings tutorial.