Tracking an order (Java)
In this use case, the user usually clicks on "Track Order" or sometimes, the application automatically renders the tracking screen as part of the order screen. Here the seller usually sends a tracking link to the tracking page of the order.
Code snippets
Client calls the BAP server to trigger track:
@PostMapping("/local_retail/track_order")
public ResponseEntity trackOrder(
@RequestHeader HttpHeaders headers,
@RequestBody ClientOrderRequest request) {
var response = bapApplicationService.trackOrder(request, headers);
return ResponseEntity.ok(response);
}
BAP server generates the protocol request body
/*
Example Request JSON:
{
"context": {
"domain": "nic2004:52110",
"country": "IND",
"city": "std:080",
"action": "track",
"core_version": "0.9.1",
"bap_id": "https://mock_bap.com/",
"bap_uri": "https://mock_bap.com/beckn/",
"bpp_id": "https://mock_bpp.com/",
"bpp_uri": "https://mock_bpp.com/beckn/",
"transaction_id": "1209849124",
"message_id": "12341242347",
"timestamp": "2021-03-23T10:00:40.065Z"
},
"message": {
"order_id": "order_1",
"callback_url": "https://mock_bap.com/order_track?orderId=order_1"
}
}
*/
public Response trackOrder(ClientOrderRequest 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.track)
.messageId(messageId)
.transactionId(txnId)
.transactionId(UUID.randomUUID().toString())
.timestamp(new Date().toString())
.build();
// Construct the protocol specific object to be passed to the BPP
// to track the active order
var trackRequest = TrackRequest.builder()
.context(context)
.message(StatusMessage.builder()
.orderId(request.getOrderId())
.callbackUrl(request.getTrackingCallbackUrl())
.build())
.build();
return invokeTrack(trackRequest, headers);
}
}
BAP server calls protocol track to the network
public Response invokeTrack(TrackRequest 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 Track api from the returned endpoint.
// Construct request headers with the public key
var responseEntity = apiClient.post(url[0] + Context.ActionEnum.track,
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 Response.of("ACK", null);
}
BAP receives protocol on_track
/*
Example Response JSON:
{
"context": {
"domain": "nic2004:52110",
"country": "IND",
"city": "std:080",
"action": "on_track",
"core_version": "0.9.1",
"bap_id": "https://mock_bap.com/",
"bap_uri": "https://mock_bap.com/beckn/",
"bpp_id": "https://mock_bpp.com/",
"bpp_uri": "https://mock_bpp.com/beckn/",
"transaction_id": "1209849124",
"message_id": "12341242343",
"timestamp": "2021-03-23T10:00:40.065Z"
},
"message": {
"tracking": {
"tl_method": "http/get",
"url": "https://track.mock_bpp.com?order_id=order_1",
"status": "active"
}
}
}
*/
@PostMapping("/bap/on_track")
public ResponseEntity onTrack(
@RequestHeader HttpHeaders headers,
@RequestBody OnTrackRequest request) {
var response = bapCallbackApplicationService.onTrack(request, headers);
return ResponseEntity.ok(response);
}
public Response onTrack(OnTrackRequest 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_track results
// Endpoint for the client to poll the order tracking based on the message id
@GetMapping("/local_retail/on_track_order")
public ResponseEntity onTrackOrder(
@PathVariable(ClientRoutes.PARAM_MESSAGE_ID) String messageId,
@RequestHeader HttpHeaders headers) {
var data = bapApplicationService.get(messageId);
return ResponseEntity.ok(data);
}