imin Authenticated Checkout

Introduction

The Authenticated Checkout allows the Checkout to be pre-populated with a logged-in user's personal details.

To enable Authenticated Checkout, you must register your webhook with imin. This can be done by contacting your imin liaison.

Please only refer to this page if you are using imin's Search API (as opposed to processing open data directly).

Request

Every ScheduledSession and Slot provided via the imin Search API is bookable if and only if it has an imin:checkoutUrlTemplate field. a "book" button can be attached to each of these bookable items.

In order to make an Authenticated Checkout request, you'll need the following information:

  • OrderedItem type: Which type of item is being booked. Presently, there are two options:

    • ScheduledSession: An individual session of an Event. e.g. a Group Run at 11:00 in Victoria Park

    • Slot: A bookable instance of a Facility at a specific time. e.g. a 10:30 - 11:00 slot for a Badminton court in Whitechapel Sports Centre.

  • OrderedItem id: The .id field of the item.

    • For a ScheduledSession, this might look like "https://opendata.fusion-lifestyle.com/OpenActive/api/scheduled-sessions/1234567"

    • For a Slot, this might look like: "https://tmactive.leisurecloud.net/OpenActive/api/slots/8901234"

    This identifies what, where and when the user is booking.

  • Offer id: Identifies the ticket type e.g. "Junior (8-18) £9".

    • For a ScheduledSession, a list of Offers can be found in the SessionSeries that is its parent

    • For a Slot, a list of Offers can be found in the FacilityUse that is its parent

    Use the .id field of the selected Offer

  • [OPTIONAL] Customer identifier: Customer's ID within your (the Broker's) system e.g. uDeOzNfX.

  • Customer's given name: e.g. "Rebekah"

  • Customer's family name: e.g. "Spinoza"

  • Customer's email: e.g. "rebekahspinoza@email.com"

  • [OPTIONAL][BOOLEAN] Customer is 13 or over?: Is the customer aged 13 years old or over? The customer must be aged 13 or over in order to book.

    • If this field is excluded, Checkout will ask the customer if they are aged 13 years or over. The booking can only continue if they are.

    • If this field is false, Checkout will return a validation error.

  • Broker name: Name of the app that Checkout is branded for e.g. "Acme Sports Finder"

  • Broker home page URL: URL for the home page of the organisation that is represented by Broker name e.g. "https://acmesportsfinder.co.uk"

  • Back to Broker URL: URL to use for a "back" button if the customer, for example, decides to go back and choose another session e.g. "https://acmesportsfinder.co.uk/search"

  • Back to Broker User Profile URL: URL to head to customer's user profile, where they can see the bookings they've made e.g. "https://acmesportsfinder.co.uk/users/rebekahspinoza"

Please make sure all URLs included within the Webhook Request includehttps:// or http://

In your production environment, all URLs included within the Webhook Request includehttps://

The request then has the following format (replace the values in << name >>with an appropriate value):

POST /api/checkout-sessions HTTP/1.1
Host: checkout.example.com
Date: Mon, 8 Oct 2018 20:52:35 GMT
Accept: application/json
{
"@context": ["https://openactive.io/", "https://imin.co/"],
"type": "imin:CheckoutSession",
"imin:initialOrder": {
"type": "OrderQuote",
"customer":{
"type": "Person",
"identifier": "<< Customer identifier >>",
"givenName": "<< first name >>",
"familyName": "<< last name >>",
"email": "<< email address >>",
"imin:is13OrOver": << Customer is 13 or over? >>
},
"broker": {
"type": "Organization",
"name": "<< broker name >>",
"url": "<< broker home page URL >>"
},
"orderedItem": [
{
"type": "OrderItem",
"acceptedOffer": "<< Offer ID >>",
"orderedItem": {
"type": "<< OrderedItem type >>",
"id": "<< OrderedItem id >>"
}
}
]
},
"imin:navigationLinks": [
{
"type": "WebPage",
"name": "Back to Broker",
"imin:linkType": "https://imin.co/BackToBrokerLink",
"url": "<< back to broker URL >>"
},
{
"type": "WebPage",
"name": "Back to Broker User Profile",
"imin:linkType": "https://imin.co/BackToBrokerUserProfileLink",
"url": "<< back to broker user profile URL >>"
}
]
}

Response

The response will reflect back the request, but will additionally contain a few other fields:

  • .id: URL of the Checkout Session in the API. This is the same as the Location header. Navigating to this URL will return this exact JSON.

  • ."imin:initialOrder".id: ID of the order itself. This is a URL but it will not necessarily be possible to navigate to it. This is intended behaviour as it's sole purpose is to uniquely identify the order. When an order is successful, a webhook will be called that will use this same id. This way, the OrderQuote returned here and the Order received by the success webhook can be linked.

  • .potentialAction: Includes an OrderAction . This OrderAction represents the next step to continue the order. Redirect the customer to this OrderAction's .target and they will see Checkout loaded with their chosen event and time. They won't need to type in their name or email as these will already be known. The rest of the flow will then continue in the Checkout.

It is advised not to rely on the position in an array of the OrderAction but to instead find the item in the .potentialAction array that has type "OrderAction". In JavaScript this would look like:

const checkoutOrderAction = response.potentialAction.find(item =>
item.type === 'OrderAction');

The following JSON is what we will provide for the Authenticated Checkout:

HTTP/1.1 201 Created
Date: Mon, 8 Oct 2018 20:52:36 GMT
Content-Type: application/json
Location: https://example.checkout.com/api/checkout-sessions/BQokikJOvBiI2H
{
"@context": ["https://openactive.io/", "https://imin.co/"],
"type": "imin:CheckoutSession",
"id": "https://checkout.hulahub.com/api/checkout-sessions/BQokikJOvBiI2H",
"identifier": "BQokikJOvBiI2H",
"imin:initialOrder": {
"type": "OrderQuote",
"id": "https://book.imin.co/ns/v1/brokers/<<your_broker_id>>/orders/<<unique_identifier>>",
"customer":{
"type": "Person",
"identifier": "<< Customer identifier >>",
"givenName": "<< first name >>",
"familyName": "<< last name >>",
"email": "<< email address >>",
"imin:is13OrOver": << Customer is 13 or over? >>
},
"broker": {
"type": "Organization",
"name": "<< broker name >>",
"url": "<< broker home page URL >>"
},
"orderedItem": [
{
"type": "OrderItem",
"acceptedOffer": "<< Offer ID >>",
"orderedItem": {
"type": "<< OrderedItem type >>",
"id": "<< OrderedItem id >>"
}
}
]
},
"imin:navigationLinks": [
{
"type": "WebPage",
"name": "Back to Broker",
"imin:linkType": "https://imin.co/BackToBrokerLink",
"url": "<< back to broker URL >>"
},
{
"type": "WebPage",
"name": "Back to Broker User Profile",
"imin:linkType": "https://imin.co/BackToBrokerUserProfileLink",
"url": "<< back to broker user profile URL >>"
}
],
"potentialAction": [
{
"type": "OrderAction",
"name": "Checkout",
"target": "https://checkout.example.com/checkout-sessions/BQokikJOvBiI2H",
}
]
}

Note that the "name" property within WebPage and OrderAction types is deprecated, but must still be included in the request.

Success Webhook

The webhook call on completion includes the following JSON:

POST << your webhook URL e.g. http://example.com/webhooks/on-success >> HTTP/1.1
Host: api.example.com
Date: Mon, 8 Oct 2018 20:52:35 GMT
Accept: application/json
{
"@context": ["https://openactive.io/", "https://imin.co/"],
"type": "Order",
"id": "https://book.imin.co/ns/v1/brokers/<<your_broker_id>>/orders/<<unique_identifier>>",
"customer":{
"type": "Person",
"identifier": "<< Customer identifier >>",
"givenName": "<< first name >>",
"familyName": "<< last name >>",
"email": "<< email address >>",
"imin:is13OrOver": << Customer is 13 or over? >>
},
"broker": {
"type": "Organization",
"name": "<< broker name >>",
"url": "<< broker home page URL >>"
},
"orderedItem": [
{
"type": "OrderItem",
"acceptedOffer": "<< Offer ID >>",
"orderedItem": {
"type": "<< OrderedItem type >>",
"id": "<< OrderedItem id >>"
},
"orderItemStatus": "https://openactive.io/OrderConfirmed",
"accessToken": [
{
"type": "Barcode",
"text": "<< e.g. "123456" >>"
}
],
"accessCode": [
{
"type": "PropertyValue",
"name": "Membership ID",
"value": "<< e.g. "654321" >>"
}
]
}
]
}

If anything fails at any point in the process, the Checkout UI will render the message: "The booking could not be completed, please contact the organiser" (or something to that effect). For the avoidance of doubt, whilst there is a “Success Webhook” and a message for the consumer, there is not a “failure webhook”.

To get more information about the ScheduledSession that's been booked, head to https://search.imin.co/events-api/v2/scheduled-sessions/<< ScheduledSession ID (URI encoded) >>