Adding a pharmaceutical item to the cart and receiving an updated quote (Java)

In this use case, the user wants to add an item to his cart. This usually results in the pharmacy blocking that item in his inventory for a limited period of time at af fixed price. Sometimes, the pharmacy may also apply a discount on the total cart value. In some other cases, the pharmacy might even add promotional items to the cart at zero price.

Select

Code snippets

Client calls the BAP server to trigger select:

    @PostMapping("/healthcare_pharmacy/add_items")
    public ResponseEntity addItems(
            @RequestHeader HttpHeaders headers,
            @RequestBody ClientSelectRequest request) {
        var response = bapApplicationService.generateSelectRequest(request, headers);
        return ResponseEntity.ok(response);
    }

BAP server generates the protocol request body


/*
Example Request JSON:
{
    "context": {
        "domain": "nic2004:52311",
        "country": "IND",
        "city": "std:080",
        "action": "select",
        "core_version": "0.9.2",
        "bap_id": "https://mock_bap.com/",
        "bap_uri": "https://mock_bap.com/beckn/",
        "transaction_id": "1239890342",
        "message_id": "123793824",
        "timestamp": "2021-03-23T10:00:40.065Z"
    },
    "message": {
        "order": {
            "items": [
                {
                    "id": "vit_c",
                    "quantity": {
                        "count": 1
                    }
                },
                {
                    "id": "a_500",
                    "quantity": {
                        "count": 1
                    }
                }
            ]
        }
    }
}
*/

    public Response generateSelectRequest(ClientSelectRequest request, HttpHeaders headers) {

        // Generate message id
        var messageId = UUID.randomUUID().toString();

        // Check if transaction id exists in the request.
        // Generate if not exists
        var txnId = StringUtils.hasText(request.getTransactionId())
                ? request.getTransactionId()
                : UUID.randomUUID().toString();

        // Construct the Context based on the request parameters
        var context = Context.builder().domain(request.getDomain())
                .action(Context.ActionEnum.select)
                .messageId(messageId)
                .transactionId(txnId)
                .transactionId(UUID.randomUUID().toString())
                .timestamp(new Date().toString())
                .build();

        // Construct the protocol specific object to be passed to the BPP/BG
        // Add the selected item(s) from the catalog to get a draft quote
        var selectRequest = SelectRequest.builder()
                .context(context)
                .message(Message.builder().order(Order.builder()
                        .items(ClientAssembler.of(request.getItems()))
                        .build()).build())
                .build();

        return invokeSelect(selectRequest, headers);
    }
}

BAP server calls protocol select to the network

    public Response invokeSelect(SelectRequest request, HttpHeaders headers) {

        // Call to look up function which returns the the public key and BPP Endpoint to be called
        var url = lookUp(headers);

        // Call BPP Select api from the returned endpoint.
        // Construct request headers with the public key
        var selectResponse = apiClient.post(url[0] + Context.ActionEnum.select,
                constructRequestHeaders(),
                request,
                Response.class);

        // Validate the received response
        if (responseEntity.getBody() == null || responseEntity.getBody().getError() != null ||
                "NACK".equals(responseEntity.getBody().getMessage().getAck().getStatus())) {
            // Return custom error to the client
            return null;
        }
        return selectResponse.getBody();
    }

BAP receives protocol on_select

/*
Example Response JSON:
{
    "context": {
        "domain": "local_retail",
        "country": "IND",
        "city": "std:080",
        "action": "on_select",
        "core_version": "0.9.2",
        "bap_id": "https://mock_bap.com/",
        "bap_uri": "https://mock_bap.com/beckn/",
        "transaction_id": "12837192379",
        "message_id": "12387193123",
        "timestamp": "2021-03-23T10:00:40.065Z"
    },
    "message": {
        "order": {
            "items": [
                {
                    "id": "vit_c",
                    "price" : {
                        "currency": "INR",
                        "value": "500"
                    },
                    "quantity": {
                        "selected": {
                            "count": 1
                        }
                    }
                },
                {
                    "id": "a_500",
                    "price" : {
                        "currency": "INR",
                        "value": "500"
                    },
                    "quantity": {
                        "selected": {
                            "count": 1
                        }
                    }
                }
            ],
            "quote": {
                "price": {
                    "currency": "INR",
                    "value": "1100"
                },
                "breakup": [
                    {
                        "title": "Vitamin C",
                        "price": {
                            "currency": "INR",
                            "value": "500"
                        }
                    }, 
                   {
                        "title": "Antibiotics",
                        "price": {
                            "currency": "INR",
                            "value": "500"
                        }
                    },
                    {
                        "title": "Delivery Charge",
                        "price": {
                            "currency": "INR",
                            "value": "100"
                        }
                    }
                ],
                "ttl": "P1H"
            }
        }
    }
}
*/
    @PostMapping("/bap/on_select")
    public ResponseEntity onSelect(
            @RequestHeader HttpHeaders headers,
            @RequestBody OnSelectRequest request) {
        var response = bapCallbackApplicationService.onSelect(request, headers);
        return ResponseEntity.ok(response);
    }

    public Response onSelect(OnSelectRequest request, HttpHeaders headers) {
        // Validate the headers received
        var isHeadersValid = validateHeaders(headers);
        // Construct and return error if the received headers are invalid
        if (!isHeadersValid) return null;

        // Store the data received based on message id for the client to poll
        saveToDB(request);

        return Response.of("ACK", null);
    }

Client polls BAP to get the on_select results

    // Endpoint for the client to poll the select data based on the message id
    @GetMapping("/healthcare_pharmacy/on_select")
    public ResponseEntity selectByMessageId(
            @PathVariable(ClientRoutes.PARAM_MESSAGE_ID) String messageId,
            @RequestHeader HttpHeaders headers) {
        var data = bapApplicationService.getSelectData(messageId);
        return ResponseEntity.ok(data);
    }