# Orders

# Orders
This overview summarizes the Ordering flow and how it interacts with merchant Software Service and Keeta.
Order Events State MachineUnderstanding the Order Flow

---

The order flow has the following Macro steps:
1. Order Event ReceptionThrough Order Events,  Keeta communicates to the Software Service the existence of a new order, as well as the other events of the order lifecycle.
**Open Delivery** provides two ways for merchant **Software Service** to be aware of new events:
- **[Polling](#tag/ordersPolling)**:
Receiving events through polling provided by  Keeta is the common way Open Delivery Order Events works.
- **[Webhook](#tag/ordersWebhook)**:
Optionally it is recommended the implementation of a **webhook** by the merchant **Software Service** for the **Keetas** to send new events directly, ensuring a much faster communication.

2. Order DetailsBefore confirming or canceling an order, it is necessary to get the order details so that the merchant Software Service user can check if he will be able to prepare and deliver this order, such as checking if he has all the necessary items and if he is available to make the delivery to the informed address.
Through the [GET /orders/{id}](#operation/orderDetails) endpoint the merchant Software Service can get all the details of an order.
This endpoint returns the code 200 and the content of the request. If an invalid request id is entered the endpoint returns 404.
Regarding order detail information, the following additional clarification is provided to prevent user information leakage:
> Keeta will return encrypted data with the `ENC_` prefix when returning users' personal privacy data(as customer, delivery). Software Services can call the [POST /v1/batchDecrypt](#operation/batchDecrypt) endpoint to decrypt the data.
Please note that data can only be decrypted in **merchant self-delivery or third-party logistics (3PL)** delivery scenarios. For Keeta platform-delivery orders (full service), the data cannot be decrypted.

3. Order Events Updates
 Following the order lifecycle, the merchant Software Service needs to notify Keeta of the upcoming order status.
After acknowledging receipt of a new order event (either via polling or webhook) is expected that the Software Service explicitly
[POST /orders/{orderId}/confirm](#operation/confirmOrder) or [POST /orders/{orderId}/requestCancellation](#operation/requestCancellation) within a  time window set by Keeta.
Otherwise the order can time out and auto-cancel and the merchant can suffer a penalty based on Keeta policy.
Order acceptances should be posted as quickly as possible to minimize consumer cancellations.
When the order is ready, it is expected that a request will be sent to [POST /orders/{orderId}/readyForPickup](#operation/orderReady)
> When sending requests to these endpoints, is expected that Keeta notifies the consumer of the progress of the order.

4. Order Cancellation
 An order can be canceled for several reasons and the initiative to cancel an order can come from the merchant, the customer, or Keeta.   
 It may also happen that the delivery person requests the cancellation in some  scenarios, such as when the customer is not found at the delivery address.
> **Cancellation Rules**
It is expected that both Keeta and merchant Software Service have their own order cancellation policies and inform their users.

A cancellation request must always contain:
- **reason**: Open text field indicating the reason for the cancellation.
- **code**: An enumerator containing a cancellation reason.
- **mode**: Field indicating whether the cancellation occurred Automatically or Manually.

The cancellation can be requested by:
**Software Service** (Merchant):
If the merchant wants to cancel an order, it must make a [POST /orders/{orderId}/requestCancellation](#operation/requestCancellation) request.
> **Penalties**
Avoid order cancellations! Excessive cancellations can result in some penalties (depending on Keeta's policy) such as having the merchant temporarily closed on the platform.

**Cancellation Validation**
The Cancellation request does not guarantee that the order is cancelled. When sending a request [/orders/{orderId}/requestCancellation](#operation/requestCancellation),  Keeta will send the code 202 (accepted) in response.
This does not yet mean
that the request has been cancelled. It means that the request has been accepted and will be processed by Keeta cancellation service. As a result of this request, the merchant Software Service may receive at the next  polling (or via webhook) one of the following events:
- CANCELLED

The order should only be Canceled when the CANCELLED event is generated.
> Cancellation rules may vary depending on the timing of the order (before or after confirmation). In some situations it is possible that  Keeta cancellation service will consult with the consumer on whether or not the  consumer accepts the cancellation of the order.


```
Cancellation codes:

- INSUFFICIENT_DISHES
- SUSPENSION_OF_BUSINESS
- INSUFFICIENT_MANPOWER
- OTHERS
```
Cancellation by **Keeta** can happen by:

```
code: CONSUMER_CANCELLATION_REQUESTED
```
The consumer can request the cancellation of an order.
Depending on the cancellation rules applied, this option may not be enabled for all merchants.
It may also only be allowed at certain times, such as before the  order is confirmed.

```
code: OTHER_CANCELLATION_REASON
```
Keetas may cancel the order for reasons other than via customer.
Possible reasons for order cancellation by the system include: timing out without acceptance,
no rider accepting the order, or the rider reporting the  store as closed.
When the Order Application initiates a cancellation, an order cancellation event is transmitted to
the Software Service via webhook or polling. The Software Service must then update the order status based on
the event  details.
5. Order Refund
 Users can initiate a fully order refund or a partial item refund request from the Order Application,which will trigger the `USER_REFUND_REQUEST` event to be sent to the Software Service.
 This event will include details  such as the refunded items and pricing information. 
 The refund process follows a handshake protocol: if the merchant agrees to the refund request, 
 they need to call the Agree Refund API; 
 if they disagree, they should 
  call the Reject Refund API.
**Sample metadata** within `USER_REFUND_REQUEST` event, refer to [polling API](#operation/pollingEvents) and [webhook](#operation/newEvent).

```json
{
  "money": 8500,
  "opTime": 1751005551823,
  "shopId": "461827",
  "status": 5002,
  "currency": "HKD",
  "isAppeal": 0,
  "partRefund": 0,
  "applyOpType": 10,
  "applyReason": "Wrong Order",
  "orderViewId": 783441058793308,
  "handleOpType": 20,
  "handleReason": "Merchant Agreed to Refund",
  "refundProducts": [
      {
          "id": 12053105,
          "name": "1️⃣  Noodles with 1 Topping",
          "spec": "",
          "tags": [],
          "count": 1,
          "price": 7500,
          "skuId": 8949938,
          "spuId": 9897081,
          "groups": [
              {
                  "groupId": 4305174,
                  "groupName": "Choose Your Choices of Noodles",
                  "groupNameI18n": {
                      "en": "Choose Your Choices of Noodles",
                      "zh-HK": "選擇麵底",
                      "default": "選擇麵底"
                  },
                  "groupOpenItemCode": "cgp-7741|1-1",
                  "shopProductGroupSkuList": [
                      {
                          "count": 1,
                          "price": 0,
                          "spuId": 2069967,
                          "spuName": "Rice Stick Noodle Supremes",
                          "currency": "HKD",
                          "spuPvList": [],
                          "groupSkuId": 23903426,
                          "refundCount": 0,
                          "refundPrice": 0,
                          "spuNameI18n": {
                              "en": "Rice Stick Noodle Supremes",
                              "zh-HK": "米線",
                              "default": "米線"
                          },
                          "groupSkuOpenItemCode": "128019"
                      }
                  ]
              }
          ],
          "remark": "",
          "picList": [
              "http://img-ap-hongkong.mykeeta.net/sailorproduct/aa2d5209534619f31c2e966080ecac5885942.jpg"
          ],
          "currency": "HKD",
          "nameI18n": {
              "en": "1️⃣  Noodles with 1 Topping",
              "zh-HK": "1️⃣  單拼小窩米線",
              "default": "1️⃣  單拼小窩米線"
          },
          "priceStr": "$75.00",
          "spuPvList": [],
          "promotions": [],
          "refundType": 1,
          "originPrice": 7500,
          "refundCount": 1,
          "refundPrice": 0,
          "orderProductId": 359379560,
          "originPriceStr": "$75.00",
          "priceWithGroup": {
              "amount": 7500,
              "amountStr": "$75.00",
              "originAmount": 7500,
              "originAmountStr": "$75.00"
          },
          "skuOpenItemCode": "AY290105",
          "spuOpenItemCode": "8898",
          "priceWithoutGroup": {
              "amount": 5900,
              "amountStr": "$59.00",
              "originAmount": 5900,
              "originAmountStr": "$59.00"
          }
      }
  ],
  "partRefundCount": 0,
  "afterSaleOrderId": 783440453161676
}
```
Reverse Transaction Policy
 The reverse transaction flow includes two scenarios: Cancellation Requests and Refund Requests, initiated by four possible parties:
   UserMerchantKeeta Customer SupportKeeta System
 Below are the detailed rules:
 
   .tg  {border-collapse:collapse;border-spacing:0;}
   .tg td{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
     overflow:hidden;padding:10px 5px;word-break:normal;}
   .tg th{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
     font-weight:normal;overflow:hidden;padding:10px 5px;word-break:normal;}
   .tg .tg-0pky{border-color:inherit;text-align:left;vertical-align:top}
   UserMerchantCustomer ServiceSystemCancellationFull Service: Users can only cancel order before merchants accpet (confirm) the order, without merchants' approval.
        After a user successfully places an order, the merchant has the option to proactively cancel
        the order at any time within 48 hours after the order is completed.Merchants can choose to initiate order cancellations through the Software Services 
        system, or alternatively, log into the Keeta Order
         Management System to cancel orders.For the latter option, Keeta will send an order cancellation notification to Software Services via API.
       If an order cancellation request is 
       escalated to Keeta Customer Support,
        the support team may cancel the order at any time—up to 30 days after the order is completed. Therefore, if an order is cancelled by Customer Support (even after order completion), the cancellation event will be notified to Software ServicesIf an order is not accepted within five minutes, the system will automatically cancel the order. Merchant approval is not required for this cancellation.⚠️ Important:Failure to accept an order within five 
       minutes will result in the temporary closure
        of the store.RefundAfter a user submits a refund request, an event notification will be triggered, and merchant approval is required.
       Regardless of whether the software integrates the deny refund or approve 
       refund API, merchants can always log in to the Keeta Merchant Portal to communicate with users and manage disputes via Instant Messenger.No matter which method the merchant uses to process the refund request—either through the Keeta Merchant Portal or via software capabilities—the outcome is idempotent. Both workflows can operate in parallel, and the final result will be determined by whichever response is received firstMerchants are not able to initiate refund requests via API.Same as aboveN/A    
   In summary, Keeta may initiate order refund or cancellation notifications at any point in time. Software Services should handle these order status updates based on its own operational needs — either by aligning with Keeta’s order status, or, by ignoring the notifications to preserve the integrity of its internal system state.If you prefer not to have your internal order status changed by Keeta under certain conditions (e.g., after an order is accepted or after completion), please discard Keeta’s order status notifications to ensure your system’s order status remains unaffected.If this results in reconciliation issues for the merchant, they should contact Keeta’s Business Development (BD) team to resolve the matter.

Version: v.1.0.7

## Description:

  - `Orders` ()
    This overview summarizes the Ordering flow and how it interacts with merchant Software Service and Keeta. Order Events State Machine Understanding the Order Flow The order flow has the following Macro steps: 1. Order Event Reception Through Order Events,  Keeta communicates to the Software Service the existence of a new order, as well as the other events of the order lifecycle. Open Delivery provides two ways for merchant Software Service to be aware of new events: Polling:Receiving events through polling provided by  Keeta is the common way Open Delivery Order Events works.Webhook:Optionally it is recommended the implementation of a webhook by the merchant Software Service for the Keetas to send new events directly, ensuring a much faster communication. 2. Order Details Before confirming or canceling an order, it is necessary to get the order details so that the merchant Software Service user can check if he will be able to prepare and deliver this order, such as checking if he has all the necessary items and if he is available to make the delivery to the informed address. Through the GET /orders/{id} endpoint the merchant Software Service can get all the details of an order. This endpoint returns the code 200 and the content of the request. If an invalid request id is entered the endpoint returns 404. Regarding order detail information, the following additional clarification is provided to prevent user information leakage: Keeta will return encrypted data with the ENC_ prefix when returning users' personal privacy data(as customer, delivery). Software Services can call the POST /v1/batchDecrypt endpoint to decrypt the data.Please note that data can only be decrypted in merchant self-delivery or third-party logistics (3PL) delivery scenarios. For Keeta platform-delivery orders (full service), the data cannot be decrypted. 3. Order Events Updates Following the order lifecycle, the merchant Software Service needs to notify Keeta of the upcoming order status. After acknowledging receipt of a new order event (either via polling or webhook) is expected that the Software Service explicitlyPOST /orders/{orderId}/confirm or POST /orders/{orderId}/requestCancellation within a  time window set by Keeta.Otherwise the order can time out and auto-cancel and the merchant can suffer a penalty based on Keeta policy.Order acceptances should be posted as quickly as possible to minimize consumer cancellations. When the order is ready, it is expected that a request will be sent to POST /orders/{orderId}/readyForPickup When sending requests to these endpoints, is expected that Keeta notifies the consumer of the progress of the order. 4. Order Cancellation An order can be canceled for several reasons and the initiative to cancel an order can come from the merchant, the customer, or Keeta.   
 It may also happen that the delivery person requests the cancellation in some  scenarios, such as when the customer is not found at the delivery address. Cancellation RulesIt is expected that both Keeta and merchant Software Service have their own order cancellation policies and inform their users. A cancellation request must always contain: reason: Open text field indicating the reason for the cancellation.code: An enumerator containing a cancellation reason.mode: Field indicating whether the cancellation occurred Automatically or Manually. The cancellation can be requested by: Software Service (Merchant): If the merchant wants to cancel an order, it must make a POST /orders/{orderId}/requestCancellation request. PenaltiesAvoid order cancellations! Excessive cancellations can result in some penalties (depending on Keeta's policy) such as having the merchant temporarily closed on the platform. Cancellation Validation The Cancellation request does not guarantee that the order is cancelled. When sending a request /orders/{orderId}/requestCancellation,  Keeta will send the code 202 (accepted) in response.This does not yet meanthat the request has been cancelled. It means that the request has been accepted and will be processed by Keeta cancellation service. As a result of this request, the merchant Software Service may receive at the next  polling (or via webhook) one of the following events: CANCELLED The order should only be Canceled when the CANCELLED event is generated. Cancellation rules may vary depending on the timing of the order (before or after confirmation). In some situations it is possible that  Keeta cancellation service will consult with the consumer on whether or not the  consumer accepts the cancellation of the order. Cancellation codes:

- INSUFFICIENT_DISHES
- SUSPENSION_OF_BUSINESS
- INSUFFICIENT_MANPOWER
- OTHERS
Cancellation codes:

- INSUFFICIENT_DISHES
- SUSPENSION_OF_BUSINESS
- INSUFFICIENT_MANPOWER
- OTHERS Cancellation by Keeta can happen by: code: CONSUMER_CANCELLATION_REQUESTED
code: CONSUMER_CANCELLATION_REQUESTED The consumer can request the cancellation of an order.Depending on the cancellation rules applied, this option may not be enabled for all merchants.It may also only be allowed at certain times, such as before the  order is confirmed. code: OTHER_CANCELLATION_REASON
code: OTHER_CANCELLATION_REASON Keetas may cancel the order for reasons other than via customer.Possible reasons for order cancellation by the system include: timing out without acceptance,no rider accepting the order, or the rider reporting the  store as closed. When the Order Application initiates a cancellation, an order cancellation event is transmitted tothe Software Service via webhook or polling. The Software Service must then update the order status based onthe event  details. 5. Order Refund Users can initiate a fully order refund or a partial item refund request from the Order Application,which will trigger the `USER_REFUND_REQUEST` event to be sent to the Software Service.
 This event will include details  such as the refunded items and pricing information. 
 The refund process follows a handshake protocol: if the merchant agrees to the refund request, 
 they need to call the Agree Refund API ; 
 if they disagree, they should 
  call the Reject Refund API . Sample metadata within USER_REFUND_REQUEST event, refer to polling API and webhook. {
  "money": 8500,
  "opTime": 1751005551823,
  "shopId": "461827",
  "status": 5002,
  "currency": "HKD",
  "isAppeal": 0,
  "partRefund": 0,
  "applyOpType": 10,
  "applyReason": "Wrong Order",
  "orderViewId": 783441058793308,
  "handleOpType": 20,
  "handleReason": "Merchant Agreed to Refund",
  "refundProducts": [
      {
          "id": 12053105,
          "name": "1️⃣  Noodles with 1 Topping",
          "spec": "",
          "tags": [],
          "count": 1,
          "price": 7500,
          "skuId": 8949938,
          "spuId": 9897081,
          "groups": [
              {
                  "groupId": 4305174,
                  "groupName": "Choose Your Choices of Noodles",
                  "groupNameI18n": {
                      "en": "Choose Your Choices of Noodles",
                      "zh-HK": "選擇麵底",
                      "default": "選擇麵底"
                  },
                  "groupOpenItemCode": "cgp-7741|1-1",
                  "shopProductGroupSkuList": [
                      {
                          "count": 1,
                          "price": 0,
                          "spuId": 2069967,
                          "spuName": "Rice Stick Noodle Supremes",
                          "currency": "HKD",
                          "spuPvList": [],
                          "groupSkuId": 23903426,
                          "refundCount": 0,
                          "refundPrice": 0,
                          "spuNameI18n": {
                              "en": "Rice Stick Noodle Supremes",
                              "zh-HK": "米線",
                              "default": "米線"
                          },
                          "groupSkuOpenItemCode": "128019"
                      }
                  ]
              }
          ],
          "remark": "",
          "picList": [
              "http://img-ap-hongkong.mykeeta.net/sailorproduct/aa2d5209534619f31c2e966080ecac5885942.jpg"
          ],
          "currency": "HKD",
          "nameI18n": {
              "en": "1️⃣  Noodles with 1 Topping",
              "zh-HK": "1️⃣  單拼小窩米線",
              "default": "1️⃣  單拼小窩米線"
          },
          "priceStr": "$75.00",
          "spuPvList": [],
          "promotions": [],
          "refundType": 1,
          "originPrice": 7500,
          "refundCount": 1,
          "refundPrice": 0,
          "orderProductId": 359379560,
          "originPriceStr": "$75.00",
          "priceWithGroup": {
              "amount": 7500,
              "amountStr": "$75.00",
              "originAmount": 7500,
              "originAmountStr": "$75.00"
          },
          "skuOpenItemCode": "AY290105",
          "spuOpenItemCode": "8898",
          "priceWithoutGroup": {
              "amount": 5900,
              "amountStr": "$59.00",
              "originAmount": 5900,
              "originAmountStr": "$59.00"
          }
      }
  ],
  "partRefundCount": 0,
  "afterSaleOrderId": 783440453161676
}
{
  "money": 8500,
  "opTime": 1751005551823,
  "shopId": "461827",
  "status": 5002,
  "currency": "HKD",
  "isAppeal": 0,
  "partRefund": 0,
  "applyOpType": 10,
  "applyReason": "Wrong Order",
  "orderViewId": 783441058793308,
  "handleOpType": 20,
  "handleReason": "Merchant Agreed to Refund",
  "refundProducts": [
      {
          "id": 12053105,
          "name": "1️⃣  Noodles with 1 Topping",
          "spec": "",
          "tags": [],
          "count": 1,
          "price": 7500,
          "skuId": 8949938,
          "spuId": 9897081,
          "groups": [
              {
                  "groupId": 4305174,
                  "groupName": "Choose Your Choices of Noodles",
                  "groupNameI18n": {
                      "en": "Choose Your Choices of Noodles",
                      "zh-HK": "選擇麵底",
                      "default": "選擇麵底"
                  },
                  "groupOpenItemCode": "cgp-7741|1-1",
                  "shopProductGroupSkuList": [
                      {
                          "count": 1,
                          "price": 0,
                          "spuId": 2069967,
                          "spuName": "Rice Stick Noodle Supremes",
                          "currency": "HKD",
                          "spuPvList": [],
                          "groupSkuId": 23903426,
                          "refundCount": 0,
                          "refundPrice": 0,
                          "spuNameI18n": {
                              "en": "Rice Stick Noodle Supremes",
                              "zh-HK": "米線",
                              "default": "米線"
                          },
                          "groupSkuOpenItemCode": "128019"
                      }
                  ]
              }
          ],
          "remark": "",
          "picList": [
              "http://img-ap-hongkong.mykeeta.net/sailorproduct/aa2d5209534619f31c2e966080ecac5885942.jpg"
          ],
          "currency": "HKD",
          "nameI18n": {
              "en": "1️⃣  Noodles with 1 Topping",
              "zh-HK": "1️⃣  單拼小窩米線",
              "default": "1️⃣  單拼小窩米線"
          },
          "priceStr": "$75.00",
          "spuPvList": [],
          "promotions": [],
          "refundType": 1,
          "originPrice": 7500,
          "refundCount": 1,
          "refundPrice": 0,
          "orderProductId": 359379560,
          "originPriceStr": "$75.00",
          "priceWithGroup": {
              "amount": 7500,
              "amountStr": "$75.00",
              "originAmount": 7500,
              "originAmountStr": "$75.00"
          },
          "skuOpenItemCode": "AY290105",
          "spuOpenItemCode": "8898",
          "priceWithoutGroup": {
              "amount": 5900,
              "amountStr": "$59.00",
              "originAmount": 5900,
              "originAmountStr": "$59.00"
          }
      }
  ],
  "partRefundCount": 0,
  "afterSaleOrderId": 783440453161676
} Reverse Transaction Policy The reverse transaction flow includes two scenarios: Cancellation Requests and Refund Requests, initiated by four possible parties: UserMerchantKeeta Customer SupportKeeta System Below are the detailed rules: .tg  {border-collapse:collapse;border-spacing:0;}
   .tg td{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
     overflow:hidden;padding:10px 5px;word-break:normal;}
   .tg th{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
     font-weight:normal;overflow:hidden;padding:10px 5px;word-break:normal;}
   .tg .tg-0pky{border-color:inherit;text-align:left;vertical-align:top} UserMerchantCustomer ServiceSystemCancellationFull Service: Users can only cancel order before merchants accpet (confirm) the order, without merchants' approval.
        After a user successfully places an order, the merchant has the option to proactively cancel
        the order at any time within 48 hours after the order is completed.Merchants can choose to initiate order cancellations through the Software Services 
        system, or alternatively, log into the Keeta Order
         Management System to cancel orders.For the latter option, Keeta will send an order cancellation notification to Software Services via API.
       If an order cancellation request is 
       escalated to Keeta Customer Support,
        the support team may cancel the order at any time—up to 30 days after the order is completed. Therefore, if an order is cancelled by Customer Support (even after order completion), the cancellation event will be notified to Software ServicesIf an order is not accepted within five minutes, the system will automatically cancel the order. Merchant approval is not required for this cancellation.⚠️ Important:Failure to accept an order within five 
       minutes will result in the temporary closure
        of the store.RefundAfter a user submits a refund request, an event notification will be triggered, and merchant approval is required.
       Regardless of whether the software integrates the deny refund or approve 
       refund API, merchants can always log in to the Keeta Merchant Portal to communicate with users and manage disputes via Instant Messenger.No matter which method the merchant uses to process the refund request—either through the Keeta Merchant Portal or via software capabilities—the outcome is idempotent. Both workflows can operate in parallel, and the final result will be determined by whichever response is received firstMerchants are not able to initiate refund requests via API.Same as aboveN/A In summary, Keeta may initiate order refund or cancellation notifications at any point in time. Software Services should handle these order status updates based on its own operational needs — either by aligning with Keeta’s order status, or, by ignoring the notifications to preserve the integrity of its internal system state. If you prefer not to have your internal order status changed by Keeta under certain conditions (e.g., after an order is accepted or after completion), please discard Keeta’s order status notifications to ensure your system’s order status remains unaffected. If this results in reconciliation issues for the merchant, they should contact Keeta’s Business Development (BD) team to resolve the matter.

