GithubHelp home page GithubHelp logo

customer-accounts-api's People

Watchers

 avatar  avatar  avatar  avatar

customer-accounts-api's Issues

Expand `customerNotice` usage to C2

Currently there is no way for the Booking System to notify the Customer of any notice specific to when they are booking an OrderItem via a particular Customer Account.

Unlike restrictions and the description, which are present in the open data feed and applicable to all guests, for Customer Account bookings, it may be desirable to display a message that is relevant to only the specific Customer making the booking. This is possible for Customer Account bookings as the Customer has already authenticated with the Booking System.

To allow such messages to be displayed to the Customer, use of the customerNotice property could be extended to C2.

This usage of customerNotice would be distinct from the customerNotice outputted at B, which is already part of the Open Booking API (and is expected to be communicated to the Customer after the booking has been completed). Hence if the same value was set on customerNotice at C2 and B, it would be communicated to the Customer twice.

Consider "accessCode", for Customer Account pin codes

In the future it may be worth considering how Customer Account pin codes could be handled by this specification.

This would support a use case where the Customer Account has a unique and globally applicable entry pin code instead of a globally applicable membership barcode or QR code.

We do not have clear examples of whether this is desirable.

Dependent accounts and booking on-behalf-of

Requirements

Dependent accounts

The membership proposal already covers the basic creation and linking of Customer Accounts. This works well for the case when the account holder has an email address and is able to use the Broker interface themselves.

However for scenarios where the Broker system is being used on behalf of children and other adults, there is no mechanism for creating Customer Accounts for these individuals.

Additionally some Sellers might require that new junior accounts are linked to an adult account.

Specific use cases include:

  • Junior walk-ins: where an adult seeks to create an account on behalf of a child, such that the child can be provisioned a physical card that can be used to walk-in to a Leisure Centre to access e.g. Free Swimming.
  • Accounts for children under e.g. 8 years old: where an operator such as Everyone Active might require the accounts to be linked to an adult account.
  • Accounts for juniors that have a monthly paid membership (e.g. "Better Health Junior"), but where the account holder does not have an email address of their own.

Observations:

  • Google allows Gmail accounts to be created at any age (accounts must be supervised by their parents for children under 13), so it is possible for anyone to have an email address and therefore have their own account. This should be considered in any UX design.
  • Junior memberships with direct debit are available from age 11 in most operators.

Booking "on behalf of"

Allowing one individual to book on behalf of another.

Specific use cases include:

  • When one member of a family wants to book on-behalf-of the rest of the family (e.g. the family go swimming, or attend fitness classes together), and make use of the memberships that different family members have.
  • Friends who regularly participate in an activity together booking on behalf of each other (e.g. attend fitness classes together), and make use of the memberships that they each have.
  • Adult wants to book on behalf of a child, using the child's membership.

Payments are out of scope of the specifications and handled by the Broker, so the focus of this proposal is on how the booking is achieved.

Concept Options for Dependent accounts

Options are presented below. The last of these is recommended by this proposal.

1) Model full groups and permissions

Different booking systems have different internal models of linking Customer Accounts. One approach is to attempt to create a flexible abstraction from these models, and expose that to the Broker.

For example, by modelling groups similar to WhatsApp groups, or YouTube brand accounts. This attempts to abstract the Booking System's own groups model and permit the Broker to access and update it.

Request examples

GET /customer-account-groups/0
POST /customer-account-groups/0/members
POST /customer-account-groups/0/owner
POST /customer-account-groups/0/administrators
POST /customer-account-groups/0/invites
DELETE /customer-account-groups/0/owner?id=
DELETE /customer-account-groups/0/administrators?id=
DELETE /customer-account-groups/0/members?id=
DELETE /customer-account-groups/0/invites?id=
Response example

{
  "@context": "https://openactive.io/",
  "@type": "CustomerAccountGroup",
  "@id": "https://eg.com/customer-account-groups/fdc14503-275e-46d3-9922-45b986c9f9aa",
  "identifier": "fdc14503-275e-46d3-9922-45b986c9f9aa",
  "name": "Family",
  "administrator": [
    "https://eg.com/customer-accounts/fdc14503-275e-46d3-9922-45b986c9f9aa"
  ],
  "member": [
    {
      "@type": "CustomerAccount",
      "@id": "https://eg.com/customer-accounts/fdc14503-275e-46d3-9922-45b986c9f9aa",
      "identifier": "fdc14503-275e-46d3-9922-45b986c9f9aa",
      "accountNumber": "CA00000123"
      "customer": {
        "@type": "Person",
        "email": "[email protected]",
        "telephone": "020 811 8055",
        "givenName": "Geoff",
        "familyName": "Capes"
      }
    }
  ],
  "invited": [
    "https://eg.com/customer-accounts/fdc14503-275e-46d3-9922-45b986c9f9aa"
  ]
}

Customer Accounts can have Dependent Accounts with the following constraints:

  • Dependents can only be associated with a single "primary" Customer Account
  • Dependents cannot log in separately, unless they transitioned to be a standalone account
  • Existing standalone Customer Accounts cannot become Dependent Accounts

To allow extensibility in the future, this is modelled as a single "group" which the "primary" Customer Account is an "admin" of (analogous to WhatsApp groups). This allows for the model to evolve in future to allow multiple groups to include a single Customer Account, inviting of existing Customer Accounts to a group, and promotion of those accounts to "primary" status.

Administrators are a subset of members, and are only available in implementations that support group privileges, where they will always contain the current user (and where removing the current user will have them leave the group, or delete the group if they are the last administrator).

Example actions:

  • New members may be added by POST using a CustomerAccount without an @id.
  • Existing members may be invited using a CustomerAccount with a POST with an @id only (the Broker must have obtained this @id from the Customer through separate authentication).
    • Invites do not send emails, which allows them to be handled by the Broker.
    • Note that for privacy only the first name and surname of invited users are displayed.
  • Invites maybe accepted via a DELETE to the invited collection with the user’s own CustomerAccount @id
  • Invited maybe rejected via a DELETE to the members collection with the user’s own CustomerAccount @id
  • Can't remove the last primary from the group.
  • Caters for limit on admins in the system, e.g. 1 admin per group

Dependent records are accessed and updated by replacing "me" with the Dependent Account identifier in the endpoints specified in Appendix D.

Advantages

  • Secure and GDPR compliant
  • Any group membership between accounts in the Broker is reflected
  • implicitly describes permissions for who can book for who

Disadvantages

  • When the Broker connects to multiple Booking Systems they will need to reconcile not just access, but membership of multiple groups across multiple systems - which is a non-trivial UX challenge and could be quite confusing for the user
  • It also presents challenges when groups on the Booking System do not fit the model
  • This doesn't explicitly resolve the issue of dependent accounts, though they may exist and be managed within the group

2) managedBy model for dependent accounts

Rather than attempting to abstract the group model, this approach only abstracts concept of the "owner" of the dependent account.

This means that the Broker is able to add "subaccounts" to the primary authenticated accounts that has been linked, using the OAuth token of the primary account.

E.g. managedBy must include only the current customer account, to simplify implementation, and make the intention explicit.

This Customer Account is accessible only via the OAuth2 keys for the managedBy accounts listed

The result of the endpoint below are similar to initialisation, and the account is created with permission to the Broker from a bookings perspective

POST /customer-accounts

{
  "@context": "https://openactive.io/",
  "@type": "CustomerAccount",
  "managedBy": [ 
    {
      "@type": "CustomerAccount",
      "@id": "https://eg.com/customer-accounts/fdc14503-275e-46d3-9922-45b986c9f9aa"
    }
  ],
  "customer": {
    "@type": "Person",
    "email": "[email protected]",
    "telephone": "020 811 8055",
    "givenName": "Geoff",
    "familyName": "Capes",
    "birthDate": "1970-01-01",
    "gender": "https://schema.org/Female",
    "address": {
      "@type": "PostalAddress",
      "streetAddress": "Raynes Park High School, 46A West Barnes Lane",
      "addressLocality": "New Malden",
      "addressRegion": "London",
      "postalCode": "NW5 3DU",
      "addressCountry": "GB"
    },
    "emergencyContact": {
      "@type": "Person",
      "name": "Ralph Capes",
      "telephone": "020 811 8055"
    }
  }
}

Advantages

  • Secure and GDPR compliant
  • Any group membership between accounts in the Broker is reflected
  • implicitly describes permissions for who can book for who

Disadvantages

  • Assumes that the managedBy parent/child model maps cleanly onto the model used within the Booking System. This approach may be confusing to users if this is not the case.
  • When the Broker connects to multiple Booking Systems they will need to reconcile not just access, but managedBy accounts across multiple systems. This is simpler than reconciling groups, but will still a significant UX challenge and still could be quite confusing for the user
  • Might be confusing to the user in terms of how they actually log into these created accounts in the Booking System itself, for example to resolve an unpaid debt or upgrade a membership. The accounts are created "behind the scenes".
  • Requires additional consideration to handle when an account is no longer managedBy (e.g. child comes of age, and no longer wants to be connected to their parent's account), as access is via the parent's OAuth token. For example: "It looks like the account for Little Jonny with Everyone Active is no longer linked to Mary. Please either create a new account for Jonny, or if Jonny has an email address and password, log in with his account". This could be confusing to the user.
  • Also may require consideration for allowing dependent accounts to move to different primary accounts.

3) Broker managed child accounts

To remove the need to synchronise any relationships with the Booking System, the Broker could exclusively manage dependent accounts.

This approach allows the Broker to create dependent accounts that are not connected to any primary account, but instead are managed entirely by the Broker.

Advantages

  • Secure and GDPR compliant
  • Simply allows the allocation of barcodes
  • Removes issues around reconciling accounts between multiple Booking Systems, as the accounts are simply duplicated

Disadvantages

  • Does not work for cases where the dependent account is upgraded to a monthly membership (it is duplicated, so which account is upgraded?)
  • Creates duplicate accounts in the booking system

4) Dependent accounts are handled within the OpenID Connect Flow (Recommended)

To get around the need for the Broker to model dependent accounts, simply put the dependent account creation step within the OpenID Connect flow.

For example by the following additional parameters:
allow_delegation=true

allow_signup and allow_delegation may not be used together, as they specify the mechanism by which a new account is created. allow_signup should be used for the primary Broker account, whereas allow_delegation should be used for all subsequent accounts. This encourages best practice of the authenticated user being the actual user, while allowing for legacy accounts that require the actual user to use another user's credentials.

At least one primary account should have been successfully linked to the Broker in order for allow_delegation to be used. It is expected that the Booking System persists the authenticated session in a cookie so that the user does not need to log in to the Booking System again.

For compatibility with Booking Systems that require an email address for each account, an additional parameter delegation_login_hint is provided, which can optionally be used by the Booking System to inform the user of the email address that is being used to create the account. For such systems this may default to the authenticated user's email address, if the delegation_login_hint is not provided.

Additionally a parameter of delegation_name_hint allows the UI of the Booking System to display the name of the Broker account to be linked, to help signpost the user appropriately.

When a user is created via allow_delegation, the email address is optionally set via initialisation, and the email field is not required.

An illustration of the allow_delegation flow can be seen in the screenshot below. Note the middle screen would be skipped if the primary account was already logged in, e.g. if they had linked an account previously.

Screenshot 2022-01-20 at 10 52 33

An example of a delegated account creation screen within a system that requires email address for each account, along with an example of a delegated account linking screen is as follows:

Screenshot 2022-01-20 at 10 52 40

For systems that do not require an email address for each account, the email field in the first screen above could simply be omitted.

Dependent Accounts are simply accessed via the endpoints specified in Appendix D, as from the Broker's perspective they appear as standard Customer Accounts, with their own tokens.

It is expected that the Booking System will provide a means to display which Brokers an account is connected to, such that if the Dependent is switched to a different Primary, the new Primary may view a list of connected Brokers and choose to disconnect them.

Advantages

  • Secure and GDPR compliant
  • No additional endpoints required, only a small addition to the OAuth flow
  • Endpoints in Appendix D work as-is using me with the Dependent Account tokens, without needing to accept a Customer ID or checking for an association to the primary account on each API call.
  • Flexible as allows different grouping or dependent management models to be presented to the user by the Booking System using the Booking System's native rendering. This should should make it easier for the user to log into the Booking System directly, and understand what accounts are being created where.
  • Removes issues around reconciling accounts between multiple Booking Systems in a consistent way - every account must simply be individually "linked", whether it is an primary or dependent account.
  • OpenID Connect tokens will survive the primary and dependent accounts being separated, which removes the need to handle this scenario.
  • More easily allows the user to log in an existing account with an email address, instead of creating a new delegated account, which reduces issues around potential account duplication.
  • Moving dependent accounts between primary accounts can be performed within the Booking System independently of the Broker.
  • Does not add any unnecessary constraints to the Booking System.
  • The same OpenID Connect flow is used, which can be designed to avoid duplicate account creation.
  • Deleting dependent accounts is handled by the Booking System rather than the Broker.
  • Similar to the concept of Netflix profiles within accounts, so likely to be familiar.
  • Encourages best practice of the actual user only authenticating as themselves rather than requiring them to share passwords with others, which allows multi-factor authentication to be supported in future if required.
  • Encourages the user to replicate the same linkage on the Booking System side, while showing the two groupings are distinct.

Disadvantages

  • Does not allow "auto-matching" or "prepopulation" of dependent accounts across systems with the Broker's accounts. Each dependent account needs to be linked one at a time for each Booking System. Although auto-matching would still require reconciliation for cases where the data in systems does not match exactly, so prepopulation is likely to mostly be a complex process anyway.

Concept Options for accounts booking "on behalf of"

Options are presented below. The last of these is recommended by this proposal.

1) Consent synchronisation

In this approach, the consent for users to book on behalf of each other is synchronised between the Broker and the Booking System, for example:

  • POST /booking-on-behalf-of/invite to send an invite
  • PUT /my-invites/invite to accept an invite, which provides "book on-behalf-of" consent

Alternatively, the /accept endpoint only exists on the accounts that are offering access to their personal data, in order to minimise the number of API calls.

If not applied as part of Option 1 above ("Model full groups and permissions") then this would require e.g. one API call for each member of a group.

Advantages

  • Secure and GDPR compliant
  • Allows permissions to be used with the Booking System/Broker, which may reduce the need for a user to provide the same permission in multiple places.

Disadvantages

  • Requires a group/permissions model to be synchronised between Broker and Booking system
  • Permissions model may differ between Broker and Booking System, which may not make this initiative the user if one change affects the other unexpectedly
  • Many API calls required
  • Does not offer security advantages over Option 2 from a "Broker trust" perspective, as the Broker is still trusted to set the permissions

2) Broker has full authority to make bookings (Recommended)

In this approach, the Booking System allows any accounts that have granted permission to a particular Broker to be used as the subject of an "on-behalf-of" booking.

This is achieved by the Broker simply specifying the @id of any connected Customer Account as the attendee of a booking.

For security, attendee details are not included in the response from C1/C2/B, and must be dereferenced by the Broker if required. The customer details are still included in the response from C1/C2/B, as the customer is always based on the authenticating API key.

For security, an additional /connect/revocation endpoint is required to allow the Customer to explicitly disconnect from the Broker (rather than simply forgetting its authentication tokens). Implementation of this endpoint is also best practice, so it might be helpful to make this explicit in the specification.

Booking on-behalf-of follows the same approach as specified in the Customer Accounts API proposal under the section "Online Booking through a Customer Account", using an @id reference to the relevant Customer Account for the attendee.

C1, C2 and B request extract:

    "attendee": {
      "@type": "Person",
      "hasAccount": "https://eg.com/customer-accounts/fdc14503-275e-46d3-9922-45b986c9f9aa"
    },

Advantages

  • Secure and GDPR compliant
  • Simple implementation and low complexity, as it does not require group or permissions synchronisation between the Broker and Booking System
  • Flexible to accommodate a wide variety of different consent models within the Broker

Disadvantages

  • "Book on-behalf-of" consent is not communicated to the Booking System from the Broker, and therefore the same consent may need to be expressed separately within the Booking System.
  • The Broker must be trusted to use this feature in a way that tracks and respect a user's "book on-behalf-of" consent is respected. Use of this feature may require the Seller to audit the Broker to ensure they have implemented such permissions correctly.

`eligibleEntitlementType` within the `Offer` in the open feed, and associated controlled vocabulary

Proposal

In order to indicate which Offer is appropriate for a particular Entitlement Type, the eligibleEntitlementType property is used.

The Offer is applicable to the Customer if at least one of the Concepts in the eligibleEntitlementType array within the Offer matches that which a Broker has associated with the Customer.

The Entitlement SKOS vocabulary itself is maintained by the owner of the Membership Scheme.

Example

"offers": [
  {
    "@type": "Offer",
    "@id": "https://example.com/api/identifiers/facility-uses/1489/slots/14882#/offers/0",
    "identifier": "OX-AD",
    "name": "Adult",
    "price": 3.3,
    "priceCurrency": "GBP",
    "eligibleEntitlementType": [
      {
        "id": "https://data.mcractive.com/openactive/entitlement-list#12345",
        "type": "Concept",
        "prefLabel": "MCRactive Adult Non-resident",
        "inScheme": "https://data.mcractive.com/openactive/entitlement-list"
      }
    ]
  },
  {
    "@type": "Offer",
    "@id": "https://example.com/api/identifiers/facility-uses/1489/slots/14882#/offers/1",
    "identifier": "MCR2",
    "name": "MCRactive Junior Resident",
    "price": 2.1,
    "priceCurrency": "GBP",
    "ageRestriction": {
      "@type": "QuantitativeValue",
      "minValue": 50
    },
    "eligibleEntitlementType": [
      {
        "id": "https://data.mcractive.com/openactive/entitlement-list#5678",
        "type": "Concept",
        "prefLabel": "MCRactive Junior Resident",
        "inScheme": "https://data.mcractive.com/openactive/entitlement-list"
      }
    ]
  }
],

Naming for concepts within the specification

From @thill-odi:

Okay, so to summarise issues arising from the TWG call of 4 November (i.e., just now):

  • We need for documentation purposes a term to describe the set of all offers to which a customer account has access. These are currently referred to as 'entitlements'. I don't like this term because it conflicts with the technical application of eligibleEntitlementType elsewhere in the document - not all offers are associated with an 'entitlement' in this more restrictive sense

I would propose 'Membership Category', as this is what determines what that set is

other proposals were:

  • benefit
  • claim
  • stamp
  • role
  • no generic term is needed

We also could use a generic term for barcodes, QR codes, and other representations that are used t gain access to a facility

in the document itself these are currently referred to either with the schema.org term accessPass or with the term 'barcode'

i thought the term 'Access Mechanism' was a helpful generalisation of 'barcode', but if I understood Nick rightly he took this to refer to the kind or type of the accessPass, not the individual instance

should we just use 'Access Pass'?

Include explicit namespace identifier

In the technical working group call on 9 December 2021, there was a debate about whether to keep the namespaceIdentifier in the path of the endpoints, or whether it would be better to infer this from the authentication.

PUT /customer-accounts/me/access-passes/{namespaceIdentifier}

Although the call moved in favour of removing the identifier completely, on reflection this actually creates a few design challenges:

  • The resulting @id of the created Barcode (e.g. "https://id.eg.com/customer-accounts/fdc14503-275e-46d3-9922-45b986c9f9aa/access-pass/{namespaceIdentifier}") is not globally unique without the namespace identifier, as it will change depending on the authentication in use.
  • Future extension to the spec to allow multiple namespaces to be accessed via the same authentication becomes problematic
  • It creates the potential for strange and difficult-to-debug behaviour if there are issues with the authentication on either the Broker or Booking System side.

To mitigate these:

  • The reserved namespaceIdentifier "broker-default" is defined, which uses the authentication to determine which namespace to use
  • Only create/update/delete of broker-default namespace is supported in this version of the specification
  • @id is not included in the returned Barcode, as it is unnecessary implementation complexity, however identifier (the internal namespaceIdentifier) is included to aid debugging.

Late cancellation policy

From discussions with Everyone Active, it is possible for a customer to request the cancellation of a Customer Account booking outside of the cancellation window. Before such a cancellation is requested, the customer should be notified of any late cancellation policy that may apply. For example: a late cancellation charge is added to the account if the space is not relet.

To ensure clarity is provided to Customers before they proceed with the cancellation, the policy could be summarised in a free text property customerAccountBookingLateCancellationPolicy. The Broker would then display this text to the Customer before they proceed to request a cancellation outside of the cancellation window, and the Customer may then use this information to determine whether they wish to proceed with the cancellation.

If a customerAccountBookingLateCancellationPolicy is not provided, the Broker would assume that cancellation outside of the cancellation window is not permitted.

Example open data extract

"organizer": {
  "@type": "Organization"
  ...
  "customerAccountBookingLateCancellationPolicy": "Late cancellations may incur a penalty if the space is not relet"
}

If a Customer is not permitted to make a late cancellation, they must receive an error from the Cancellation request with the reason clearly articulated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.