ONDC-Official / v1.1.0-logs

2 stars 107 forks source link

eSamudaay-buyer - compliance check #170

Closed sandeepshahi closed 1 year ago

sandeepshahi commented 1 year ago

Flow 1,4

/confirm

/update call to calculate and update refund amnt is missing

BLR-0118 commented 1 year ago

@ShishirPrashanth

ShishirPrashanth commented 1 year ago

@bluecypher @BLR-0118

Fixed in https://github.com/ONDC-Official/v1.1.0-logs/pull/179:

/confirm - fixed (in flow 1, applicable to all flows) /update - added second update with the refund amount (in flow 1, applicable to all flows)

BLR-0118 commented 1 year ago

Logs ok. Need to understand how the following are handled:

  1. Will the buyer app have live search or cached search? If cached search, how will disabled merchants be handled?
  2. How will you ensure buyer pin location is accurate i.e. gps coords map correctly to address?
  3. How will non-serviceable cases be handled?
  4. How will inventory out of stock cases be handled?
  5. What if buyer changes delivery location to something different from what was setup initially?
  6. Are unsolicited status & cancel calls being handled?
  7. How will error codes be Interpreted & displayed?
  8. Is this an SDK or full-fledged buyer app? If buyer app, can we have access to a demo version?
BLR-0118 commented 1 year ago

@ShishirPrashanth

ShishirPrashanth commented 1 year ago

@BLR-0118 @bluecypher Will the buyer app have live search or cached search? If cached search, how will disabled merchants be handled? Buyer app will cache search results. Merchant will expire in 3 scenarios:

  1. Seller app explicitly disables the merchant using bpp/providers.time.label: "disable".
  2. bpp/providers.ttl expires. We save the timestamp when we receive data of the store. If on_search time + bpp/providers.ttl is higher than the current time then we remove the store from the cache.
  3. If we don't receive data from a particular store for 48 hours. We will pull catalog 4 times per day so the particular store needs to miss 8 on_search requests in order to be removed from the cache.

In case the store was disabled in between 2 catalog pulls (store got disabled but buyer app doesn't know yet), there will be an error during on_select which will be handled gracefully by the buyer app.

How will you ensure buyer pin location is accurate i.e. gps coords map correctly to address? This is a mobile application so we get accurate coords from the user's GPS. We also allow the user to locate exact pin on the map and use google autocomplete to easily find their address. The flow is very similar to apps like Swiggy, Zomato etc. We use google maps api to calculate all necessary info related to coordinates. Several thousands of (non ONDC) orders have been processed with the same piece of code and we haven't seen any error so far.

How will non-serviceable cases be handled?

  1. Seller app sends error in on_select which is displayed to the user. In case of multi fulfillments it will also display which specific item is non serviceable.
  2. User will navigate back to the cart screen. The same error will continue to be displayed here.
  3. User can modify cart (delivery address, items etc.) and retry.
  4. New cart will start over with select with a new transaction id. The SDK doesn't allow user to continue to init with different details from select.

How will inventory out of stock cases be handled?

  1. Seller app sends error in on_select which is displayed to the user. Complete details will be displayed to the user including info about which item was (completely or partially) out of stock.
  2. User will navigate back to the cart screen. The same error will continue to be displayed here.
  3. User can modify cart (items, delivery address etc.) and retry.
  4. New cart will start over with select with a new transaction id. The SDK doesn't allow user to continue to init with different details from select.

What if buyer changes delivery location to something different from what was setup initially? This is not possible on the app. The SDK doesn't allow it either. There will be no change in info between select, init and confirm for the same transaction id. In case anything needs to be changed (due to error or user changing his mind before placing order or anything else) then everything will start over from select with a new transaction id.

Are unsolicited status & cancel calls being handled? Yes As soon as on_status or on_cancel is received, the latest order status is updated and immediately displayed to the user.

How will error codes be Interpreted & displayed? Value of error.code is consumed and mapped to an appropriate human readable message. We cannot check for error.message since it is no longer mandatory. For example during on_select if we receive 30009, we will display "Dropoff location not serviceable by Logistics Provider" on the screen. After this the user will be able to navigate back to the cart page (in case they want to make changes and try again). The same error message will be displayed clearly at the bottom the the screen here as well until the user makes changes to the cart.

Is this an SDK or full-fledged buyer app? If buyer app, can we have access to a demo version? We have an SDK as well as a full-fledged app (that uses the SDK). All logs have been submitted through the app. APK can be provided for demo. You can download and try out the app on any android phone.

ShishirPrashanth commented 1 year ago

Short note on the working of the SDK and it's integration with the app: This will help clarify various flows and many of the questions asked.

The SDK consists of a few simple APIs that can be called by the buyer app:

  1. Catalog Refresh API
  2. Verify Cart API
  3. Confirm Order API

It also has the following APIs for tracking after order placement:

  1. Order Status API
  2. Order Cancel API
  3. Order Return API

Catalog Refresh API: Catalog refresh API makes a search by city call and updates the cache with all the providers that respond on on_search. Buyer app sets a cron schedule to call this API 4 times per day.

Verify Cart API: Verify cart API calls select + init. Buyer app creates and modifies the cart locally (requests are not spammed to the seller). Once the cart is finalized, a single API call is made to the SDK for verification of the same. The following scenarios can occur:

  1. Happy flow, everything works: SDK sends select, receives on_select with no errors. Then the SDK sends init, receives on_init with no errors. At this point the SDK updates the cart status to "VERIFIED" and provides the quote to the app. The app allows the user to proceed to make payment only if the cart status is "VERIFIED". The SDK too allows Confirm Order API to be called only if the cart status is "VERIFIED".
  2. Failed during on_select: SDK sends select, receives on_select with error. SDK will update cart status to "FAILED" and updates all attributes to the cart so that app can display exactly what happened to the user. No init call will be made if on_select has error.
  3. Failed during on_init (rare case but handled similar to case 2): SDK sends select, receives on_select with no errors. Then the SDK sends init, receives on_init with error. SDK will update cart status to "FAILED" and updates all attributes to the cart so that app can display exactly what happened to the user. No init call will be made if on_select has error.

In case user wants to modify details of the cart (whether it is VERIFIED or FAILED), they are free to do so. However the buyer app will have to call the verify cart API once again which will generate a new transaction id and start over from select. This ensures that buyer information cannot change between select and init.

Confirm Order API: Once cart is verified, the user will make payment and call the Confirm Order API with the necessary payment info. The SDK calls confirm and receives on_confirm to update the status of the order. From this moment the SDK will listen for on_status and on_cancel for any updates to the order and automatically update the status on the buyer app. Customer will be able to see these updates in real time. In case anything breaks, the retry flow will trigger and finally in case the order is not confirmed by the seller, the order will be cancelled and the customer will be refunded automatically.

Order Status API: Backup API since unsolicited on_status are handled. Buyer can request status of the order on demand.

Order Cancel API: In case buyer wants to cancel, they can select reason code. SDK sends /cancel and listens for /on_cancel. In case of NACK during cancel or on_cancel, the order status will not change and the buyer will be notified that the cancellation failed. In case of successful cancellation, the order status will be updated and the customer will be refunded automatically. This works for seller cancellation as well (unsolicited on_cancel)

Order Return API: In case buyer wants to return items, they can select which items to return along with reason code and click/upload images. SDK sends /update and listens for /on_update. In case of NACK during update or on_update, order status will not change and buyer will be notified that return has failed. In case of successful return (received successful on_update), SDK will continue listening for further on_updates. As soon as the return status moves to return_picked or liquidated, refund amount will be calculated and displayed to the user and a second update call will be made to send the refund amount to the seller. Until then the user will see that "Return is being processed".

ShishirPrashanth commented 1 year ago

@BLR-0118 @bluecypher Hope this answers all your questions Pls let me know in case of any other queries.

Thanks

BLR-0118 commented 1 year ago
  1. Merchant disabling should be explicit, i.e. only thru "disabled" key in on_search;
  2. txn id should be reused in select when buyer chooses between different stores and / or when recreating the cart due to error conditions (check this);
  3. allowing buyer to select delivery location as the 1st step of checkout is required (in which case, you need to call select with same txn id);
  4. pls share your APK so I can check the flow.
BLR-0118 commented 1 year ago

@ShishirPrashanth

ShishirPrashanth commented 1 year ago
  1. Sure. We will disable merchants only through explicit "disabled" key.
  2. The Jira seems to tackle the problem of multiple select calls being made. In our case we don't make multiple select calls, only a single select call is made when the cart is finalized. We don't make select calls for every addition or modification of anything in the cart. For the case of retrying after error in cart, we will allow reuse of the same transaction id. This will be deployed in preprod by tomorrow eod.
  3. Already implemented. Buyer selects delivery location before the first select call.
  4. Shared on email.
ShishirPrashanth commented 1 year ago

@BLR-0118

BLR-0118 commented 1 year ago

Checked APK. You need to look at the following:

  1. Delivery location should be selected as the 1st step for checkout, not before the 1st select call. This is because cart creation is an iterative process where buyer can add & remove things before being ready for checkout;
  2. Need to use proper error codes e.g. when trying to checkout, I get this error "Time out, please try later"; @ShishirPrashanth
BLR-0118 commented 1 year ago

logs cleared for v1.1.0

BLR-0118 commented 1 year ago

@ShishirPrashanth