openactive / customer-accounts-api Goto Github PK
View Code? Open in Web Editor NEWRepository for discussions broadly related to Customer Accounts
License: MIT License
Repository for discussions broadly related to Customer Accounts
License: MIT License
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.
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.
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:
Observations:
Allowing one individual to book on behalf of another.
Specific use cases include:
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.
Options are presented below. The last of these is recommended by this proposal.
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:
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:
Dependent records are accessed and updated by replacing "me" with the Dependent Account identifier
in the endpoints specified in Appendix D.
managedBy
model for dependent accountsRather 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"
}
}
}
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.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 usermanagedBy
(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.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.
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.
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:
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.
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.Options are presented below. The last of these is recommended by this proposal.
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 invitePUT /my-invites/invite
to accept an invite, which provides "book on-behalf-of" consentAlternatively, 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.
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"
},
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.
"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"
}
]
}
],
From @thill-odi:
Okay, so to summarise issues arising from the TWG call of 4 November (i.e., just now):
I would propose 'Membership Category', as this is what determines what that set is
other proposals were:
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'?
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:
@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.To mitigate these:
namespaceIdentifier
"broker-default"
is defined, which uses the authentication to determine which namespace to usebroker-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.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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.