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 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 ScheduledSessionitems

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

  • ScheduledSession id: The id field of the ScheduledSession e.g. "https://opendata.fusion-lifestyle.com/OpenActive/api/scheduled-sessions/1234567"

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

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

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

  • 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/marvinspinoza"

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",
"givenName": "<< first name >>",
"familyName": "<< last name >>",
"email": "<< email address >>"
},
"broker": {
"type": "Organization",
"name": "<< broker name >>",
"url": "<< broker home page URL >>"
},
"orderedItem": [
{
"type": "OrderItem",
"orderedItem": {
"type": "ScheduledSession",
"id": "<< Scheduled Session 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",
"givenName": "<< first name >>",
"familyName": "<< last name >>",
"email": "<< email address >>"
},
"broker": {
"type": "Organization",
"name": "<< broker name >>",
"url": "<< broker home page URL >>"
},
"orderedItem": [
{
"type": "OrderItem",
"orderedItem": {
"type": "ScheduledSession",
"id": "<< Scheduled Session 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",
"givenName": "<< first name >>"
"familyName": "<< last name >>"
"email": "<< email address >>"
},
"broker": {
"type": "Organization",
"name": "<< broker name >>",
"url": "<< broker home page URL >>"
},
"orderedItem": [
{
"type": "OrderItem",
"orderedItem": {
"type": "ScheduledSession",
"id": "<< Scheduled Session 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) >>