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 Events API (as opposed to processing open data directly).

Request

Every ScheduledSession and Slot provided via the imin Events 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:

  • Opportunity 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.

  • Opportunity identifier: The .identifier 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 Slot itself.

    Use the .id field of the selected Offer

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

  • Customer: This can be either a ID string or a Customer object

    • ID string: e.g. https://book.imin.co/api/v2/customers/qOZtNY9m. This is the imin ID for a Customer Account you've registered with imin. Details on registering Customer Accounts with imin can be found here.

    • Customer Object:

      • [OPTIONAL] Broker customer identifier: Customer's ID within your (the Broker's) system e.g. uDeOzNfX. This is not used by imin internally but will be included in the success webhook, helping you to connect successful bookings with your customers.

      • 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.

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 broker customer identifier [OPTIONAL] is specific to you, the broker. For the avoidance of doubt, the customer.identifier is not related to the provider whose session has been booked.

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": "<< Broker customer identifier >>",
      "givenName": "<< first name >>",
      "familyName": "<< last name >>",
      "email": "<< email address >>",
      "imin:is13OrOver": << Customer is 13 or over? >>
    },
    // OR "customer": "https://book.imin.co/api/v2/customers/qOZtNY9m", 
    "broker": {
      "type": "Organization",
      "name": "<< broker name >>",
      "url": "<< broker home page URL >>"
    },
    "orderedItem": [
      {
        "type": "OrderItem",
        "acceptedOffer": "<< Offer ID >>",
        "orderedItem": {
          "type": "<< Opportunity type >>",
          "identifier": "<< Opportunity identifier >>"
        }
      }
    ]
  },
  "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 Authenticated Checkout response has the following format:

HTTP/1.1 201 Created
Content-Type: application/json
Location: << your checkout domain >>/api/checkout-sessions/<< an identifier >>

{
  "@context": ["https://openactive.io/", "https://imin.co/"],
  "type": "imin:CheckoutSession",
  "id": "<< your checkout domain >>/api/checkout-sessions/<< an identifier >>",
  "identifier": "BQokikJOvBiI2H",
  "imin:initialOrder": {
    "type": "OrderQuote",
    "id": "https://book.imin.co/api/v2/orders/by-checkout-session/<< an identifier >>",
    "customer":{
      "type": "Person",
      "identifier": "<< Broker 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": "<< Opportunity type >>",
          "identifier": "<< Opportunity identifier >>"
        }
      }
    ]
  },
  "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/<< an identifier >>",
     }
  ]
}

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

Booking Success Webhook

If the customer completes the booking initiated by Authenticated Checkout, imin will call a Booking Success Webhook in your system (please arrange with us to set up your webhook)

The webhook's request has this format:

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/api/v2/orders/by-checkout-session/<< an 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": "<< Opportunity type >>",
        "identifier": "<< Opportunity identifier >>"
      },
      "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 item that's been booked, head to:

  • https://search.imin.co/events-api/v2/scheduled-sessions/{data.identifer} where it is a ScheduledSession; or

  • https://search.imin.co/facilities-api/v2/slots/{data.identifer} where it is a Slot.

NB the data.identifer must be URI encoded.

Last updated