|
589 | 589 |
|
590 | 590 | - The <a>Broker</a> MUST update the `Order` in with an internal status of `https://schema.org/OrderDelivered` after invoices have been created and notifications successfully sent.
|
591 | 591 |
|
592 |
| -x) **Refunds an Cancellation** - The <a>Broker</a> subscribes to updates from the <a>Booking System</a> to process cancellations and refunds. |
| 592 | +x) **Refunds and Cancellation** - The <a>Broker</a> subscribes to updates from the <a>Booking System</a> to process cancellations and refunds. |
593 | 593 | - A secure <a>Orders feed</a> of `Order`s MUST be provided by the <a>Booking System</a>, with the contents of the feed specific to the authentication credentials. This allows the <a>Broker</a> to maintain an updated state of all their bookings across a number of <a>Booking Systems</a>, even when changes are made outside of the <a>Broker</a>. This also allows the <a>Broker</a> to handle refunds to cancellations, and process notifications to <a>Customers</a> in a consistent way.
|
594 | 594 | - The <a>Booking System</a> must ensure that the `Order`s in the <a>Orders feed</a> represent the current state of `OrderItem`s within the system, for the properties included in the feed.
|
595 | 595 | - The <a>Broker</a> uses these `Order`s to process refunds and send update notifications to the <a>Customer</a>.
|
|
860 | 860 |
|
861 | 861 | - The <a>Broker</a> has machine readable permission to access the relevant instance of a compliant Open Booking API provided by the <a>Booking System</a> via an API key or similar token.
|
862 | 862 |
|
863 |
| -The <a>Broker</a> MUST NOT attempt to book an opportunity that is not <a>bookable</a> by the above criteria. The <a>Booking System</a> MUST return an error if an `Order` is submitted that contains activities that are not <a>bookable</a>, and include an `error` against each `OrderItem` in the `OrderQuote` that is not <a>bookable</a>. |
| 863 | +The <a>Broker</a> MUST NOT attempt to book an opportunity that is not <a>bookable</a> by the above criteria. The <a>Booking System</a> MUST include an `error` of value `UnavailableOpportunityError` against each `OrderItem` in the `OrderQuote` that is not <a>bookable</a>. |
864 | 864 |
|
865 | 865 | Note that although the <a>Customer</a> may be ineligible to attend a <a>bookable</a> opportunity based on the `genderRestriction` or `ageRange`, this specification encourages the <a>Broker</a> NOT to capture gender and age data from the <a>Customer</a> and NOT to enforce validation of these restrictions, but instead to prominently display any restrictions in the booking process to ensure that the <a>Customer</a> is aware of these.
|
866 | 866 |
|
|
880 | 880 | 5. The <a>Broker</a> MAY additionally filter based on the `Offer`s that apply to the customer, for example based on `ageRange` if specified in the `Offer`. This specification provides no guidance as to how the filtering should be performed, however it recommends against gathering additional personal data about the <a>Customer</a> in order to restrict `Offer`s presented, and instead advocates clear messaging regarding the restrictions of each `Offer` to allow the <a>Customer</a> to make an informed decision.
|
881 | 881 |
|
882 | 882 |
|
| 883 | + |
| 884 | +<div class="issue" data-number="103"></div> |
| 885 | + |
| 886 | + |
883 | 887 | ## Amending the OrderQuote before **B**
|
884 | 888 |
|
885 | 889 | The <a>Broker</a> MAY call **C1** and MUST call **C2** when the <a>Customer</a> updates their basket to add and remove items.
|
|
905 | 909 |
|
906 | 910 | To cancel an existing OrderItem, the <a>Broker</a> MUST:
|
907 | 911 |
|
908 |
| -1. Use the latest state of the `Order` from the <a>Orders feed</a> to determine which `OrderItem`s may be cancelled. If `allowSimpleCancellation` is `true` and `latestCancellationBeforeStartDate` subtracted from the opportunity `startDate` is in the future, a PATCH against the `OrderItem` `id` with a body of `{ "orderItemStatus": "https://openactive.io/CustomerCancelled" }` MUST succeed. |
| 912 | +1. Use the latest state of the `Order` stored during the booking flow and updated via the <a>Orders feed</a> to determine which `OrderItem`s may be cancelled. If `allowSimpleCancellation` is `true` and `latestCancellationBeforeStartDate` subtracted from the opportunity `startDate` is in the future, a PATCH against the `Order` including the `OrderItem` with `"orderItemStatus": "https://openactive.io/CustomerCancelled"` MUST succeed. |
909 | 913 |
|
910 | 914 | 2. Inform the <a>Customer</a> of the expected refund before they commit to cancellation, where the value of the refund for each `OrderItem` MUST be equal to:
|
911 |
| -- For `taxMode` of `https://openactive/TaxNet`: the sum of the `price` in the `acceptedOffer` and all the prices in `unitTaxSpecification`. |
912 |
| -- For `taxMode` of `https://openactive/TaxGross`: the `price` in the `acceptedOffer`. |
| 915 | + (i) for `taxMode` of `https://openactive/TaxNet`, the sum of the `price` in the `acceptedOffer` and all the prices in `unitTaxSpecification`; |
| 916 | + (ii) for `taxMode` of `https://openactive/TaxGross`, the `price` in the `acceptedOffer`. |
913 | 917 |
|
914 |
| -3. Submit a PATCH for each `OrderItem` to be cancelled using the URL `id` of the `OrderItem` from the feed with a body of `{ "orderItemStatus": "https://openactive.io/CustomerCancelled" }`. On success, a 204 response will be received, without any body. On failure a 5xx response will be received with an error message. |
| 918 | +3. Submit a PATCH for the `Order` including only the `id` for each of the `OrderItem`s to be cancelled, with an `"orderItemStatus": "https://openactive.io/CustomerCancelled"` set on each. On success, a 204 response will be received, without any body. On failure a 5xx response will be received with an error message. |
915 | 919 |
|
916 | 920 | 4. Process any refunds based on the resulting updates to the <a>Orders feed</a>. Successfully cancelled `OrderItems` will have `orderItemStatus` set to `https://openactive.io/CustomerCancelled`. Note refunds MUST NOT be processed except in response to updates in the <a>Orders feed</a>.
|
917 | 921 |
|
918 |
| -To cancel an entire `Order`, a PATCH request must be made to each `OrderItem` within it individually. To minimise the number of updates in the <a>Orders feed</a>, it is recommended that multiple DELETEs are sent in quick succession. |
| 922 | +To cancel an entire `Order`, a single PATCH request MUST be made including `"orderItemStatus": "https://openactive.io/CustomerCancelled"` for each `OrderItem` within it. |
919 | 923 |
|
920 |
| -Note that there is no provision for a <a>Customer</a> to cancel an `Order` after the cancellation window specified by `latestCancellationBeforeStartDate`, yet they may wish to do this out of politeness even though no refund is possible, with the benefit that their place may be taken by another participant. |
| 924 | +Note that there is no provision for a <a>Customer</a> to cancel an `Order` after the cancellation window specified by `latestCancellationBeforeStartDate. They may wish to do this out of politeness even though no refund is possible, with the benefit that their place may be taken by another participant, which can be included in future versions of this specification. |
921 | 925 |
|
922 | 926 | <div class="issue" data-number="92"></div>
|
923 | 927 |
|
| 928 | +<div class="issue" data-number="102"></div> |
| 929 | + |
| 930 | + |
924 | 931 | ### Seller requested cancellation
|
925 | 932 |
|
926 | 933 | <figure>
|
|
1097 | 1104 |
|
1098 | 1105 | A summary of endpoints defined by this specification is provided below:
|
1099 | 1106 |
|
1100 |
| -| Endpoint Name | Status | Resource | HTTP Verb | Example Path | |
1101 |
| -|------------------------|-------------|------------------|-----------|--------------------------------------------------| |
1102 |
| -| Order Creation | REQUIRED | Order | PUT | `/orders/{uuid}` | |
1103 |
| -| Order Deletion | REQUIRED | Order | DELETE | `/orders/{uuid}` | |
1104 |
| -| Orders RPDE Feed | REQUIRED | Orders feed | GET | `/orders-rpde` | |
1105 |
| -| OrderItem Cancellation | REQUIRED | OrderItem | PATCH | `/orders/{uuid}/order-items/{order-item-id}` | |
1106 |
| -| Order Status | OPTIONAL | Order | GET | `/orders/{uuid}` | |
| 1107 | +| Endpoint Name | Status | Resource | HTTP Verb | Example Path | |
| 1108 | +|-------------------------|-------------|------------------|-----------|-------------------| |
| 1109 | +| Order Creation | REQUIRED | Order | PUT | `/orders/{uuid}` | |
| 1110 | +| Order Deletion | REQUIRED | Order | DELETE | `/orders/{uuid}` | |
| 1111 | +| OrderItem Cancellation | REQUIRED | Order | PATCH | `/orders/{uuid}` | |
| 1112 | +| Orders RPDE Feed | REQUIRED | Orders feed | GET | `/orders-rpde` | |
| 1113 | +| Order Status | OPTIONAL | Order | GET | `/orders/{uuid}` | |
1107 | 1114 |
|
1108 | 1115 |
|
1109 | 1116 | <div class="issue" data-number="98"></div>
|
|
1194 | 1201 |
|
1195 | 1202 | ### Order Deletion
|
1196 | 1203 |
|
1197 |
| -| Endpoint Name | Status | Resource | HTTP Verb | Example Path | |
1198 |
| -|------------------------|-------------|------------------|-----------|--------------------------------------------------| |
1199 |
| -| Order Deletion | REQUIRED | Order | DELETE | `/orders/{uuid}` | |
| 1204 | +| Endpoint Name | Status | Resource | HTTP Verb | Example Path | |
| 1205 | +|------------------------|-------------|------------------|-----------|----------------------| |
| 1206 | +| Order Deletion | REQUIRED | Order | DELETE | `/orders/{uuid}` | |
1200 | 1207 |
|
1201 | 1208 | Deleting an `Order` allows for the whole Booking Flow to be reversed for fatal error and testing scenarios.
|
1202 | 1209 |
|
|
1214 | 1221 | </pre>
|
1215 | 1222 |
|
1216 | 1223 |
|
1217 |
| -### Orders RPDE Feed |
| 1224 | +### OrderItem Cancellation |
1218 | 1225 |
|
1219 |
| -| Endpoint Name | Status | Resource | HTTP Verb | Example Path | |
1220 |
| -|------------------------|-------------|------------------|-----------|--------------------------------------------------| |
1221 |
| -| Orders RPDE Feed | REQUIRED | Orders feed | GET | `/orders-rpde` | |
| 1226 | +| Endpoint Name | Status | Resource | HTTP Verb | Example Path | |
| 1227 | +|------------------------|-------------|------------------|-----------|----------------------| |
| 1228 | +| OrderItem Cancellation | REQUIRED | Order | PATCH | `/orders/{uuid}` | |
1222 | 1229 |
|
1223 |
| -<pre class="example" title="Order RPDE Feed: example request" data-transform="dataExampleOrderFeedRequest"> |
| 1230 | +All other properties except the `id` and `orderItemStatus` inside the `OrderItem` MUST be ignored. `OrderItem`s omitted from the PATCH request MUST also be ignored. |
| 1231 | + |
| 1232 | +<pre class="example" title="OrderItem Cancellation: example request" data-transform="dataExampleOrderItemCancellationRequest"> |
1224 | 1233 | </pre>
|
1225 | 1234 |
|
1226 |
| -<pre class="example" title="Order RPDE Feed: example response" data-transform="dataExampleOrderFeedResponse"> |
| 1235 | +The cancellation request succeeds and fails atomically. |
| 1236 | + |
| 1237 | +<pre class="example" title="OrderItem Cancellation: example success response" data-transform="dataExampleOrderItemCancellationSuccessResponse"> |
1227 | 1238 | </pre>
|
1228 | 1239 |
|
| 1240 | +<!-- |
| 1241 | +<pre class="example" title="OrderItem Cancellation: example error response" data-transform="dataExampleOrderItemCancellationErrorResponse"> |
| 1242 | +</pre> |
| 1243 | +--> |
1229 | 1244 |
|
1230 |
| -### OrderItem Cancellation |
1231 | 1245 |
|
1232 |
| -| Endpoint Name | Status | Resource | HTTP Verb | Example Path | |
1233 |
| -|------------------------|-------------|------------------|-----------|--------------------------------------------------| |
1234 |
| -| OrderItem Cancellation | REQUIRED | OrderItem | PATCH | `/orders/{uuid}/order-items/{order-item-id}` | |
1235 | 1246 |
|
1236 |
| -<pre class="example" title="OrderItem Cancellation: example request" data-transform="dataExampleOrderItemCancellationRequest"> |
| 1247 | +### Orders RPDE Feed |
| 1248 | + |
| 1249 | +| Endpoint Name | Status | Resource | HTTP Verb | Example Path | |
| 1250 | +|------------------------|-------------|------------------|-----------|----------------------| |
| 1251 | +| Orders RPDE Feed | REQUIRED | Orders feed | GET | `/orders-rpde` | |
| 1252 | + |
| 1253 | +<pre class="example" title="Order RPDE Feed: example request" data-transform="dataExampleOrderFeedRequest"> |
1237 | 1254 | </pre>
|
1238 | 1255 |
|
1239 |
| -<pre class="example" title="OrderItem Cancellation: example response" data-transform="dataExampleOrderItemCancellationResponse"> |
| 1256 | +<pre class="example" title="Order RPDE Feed: example response" data-transform="dataExampleOrderFeedResponse"> |
1240 | 1257 | </pre>
|
1241 | 1258 |
|
| 1259 | + |
1242 | 1260 | ### Order Status
|
1243 | 1261 |
|
1244 | 1262 | A <a>Booking System</a> MAY provide an endpoint to allow a <a>Broker</a> to retrieve complete `Order`s. In future versions of the specification, endpoints may be provided which permit a <a>Broker</a> to see all `Order`s created by a <a>Customer</a>. In this current implementation, the <a>Broker</a> MUST keep its own record of `Order`s as described elsewhere in this specification, and not rely on this OPTIONAL Order Status endpoint.
|
1245 | 1263 |
|
1246 |
| -| Endpoint Name | Status | Resource | HTTP Verb | Example Path | |
1247 |
| -|------------------------|-------------|------------------|-----------|--------------------------------------------------| |
1248 |
| -| Order Status | OPTIONAL | Order | GET | `/orders/{uuid}` | |
| 1264 | +| Endpoint Name | Status | Resource | HTTP Verb | Example Path | |
| 1265 | +|------------------------|-------------|------------------|-----------|-----------------------| |
| 1266 | +| Order Status | OPTIONAL | Order | GET | `/orders/{uuid}` | |
1249 | 1267 |
|
1250 | 1268 | <pre class="example" title="Order Status: example request" data-transform="dataExampleOrderStatusRequest">
|
1251 | 1269 | </pre>
|
|
1608 | 1626 | | `OrderAlreadyExistsError` | 400 | If the UUID used for an `OrderQuote` already represents a completed Order. |
|
1609 | 1627 |
|
1610 | 1628 |
|
| 1629 | +<!--| `CancellationNotPermittedError` | 400 | If the cancellation is not permitted due to internal rules of the booking system not otherwise exposed to the `Broker`. The `description` property of the object SHOULD include a <a>Customer</a>-facing description of the reason that cancellation is not permitted. |--> |
| 1630 | + |
| 1631 | + |
| 1632 | + |
1611 | 1633 | #### Order Creation - `OrderItem` errors
|
1612 | 1634 |
|
1613 | 1635 | Note that all `OrderItem` errors for an `OrderQuote` request result in a `409 Conflict` response, as the error is expected to be resolved, and the request resubmitted, as per [[RFC2616]] section 10.4.10.
|
|
1618 | 1640 | | `UnacceptableOfferError` | 409 | If the `acceptedOffer` is not a URL which corresponds to an <a>Applicable `Offer`</a> for the opportunity. |
|
1619 | 1641 | | `UnknownOfferError` | 409 | If the `acceptedOffer` is not a URL which corresponds to an `Offer` within the <a>Booking System</a>. |
|
1620 | 1642 | | `UnknownOpportunityDetailsError` | 409 | If the `orderedItem` is not a URL which corresponds to an opportunity on the <a>Booking System</a>. |
|
1621 |
| -| `UnavailableOpportunityError` | 409 | If the `Offer` contained in the `acceptedOffer` property is not bookable | |
| 1643 | +| `UnavailableOpportunityError` | 409 | If the `Offer` contained in the `acceptedOffer` property is not <a>bookable</a>. | |
1622 | 1644 | | `OpportunityIsFullError` | 409 | If there are no available spaces for the opportunity contained in the `orderedItem` property |
|
1623 | 1645 | | `OpportunityHasInsufficientCapacityError` | 409 | If there are not enough available spaces in the opportunity contained in the `orderedItem` property to fulfil the number requested by the `orderQuantity` property. |
|
1624 | 1646 |
|
|
0 commit comments