Updating a pharmaceutical item’s quantity on an active order and receiving updated order with payment terms (Node.js)
In this use case, the user changes the quantity of one or more items after the order has been confirmed. If the user has already made the payment, the pharmacy sends additional payment terms that the user needs to fulfill before the quantity gets updated. In case the order is postpaid, the pharmacy can update the total amount to be paid after the fulfillment of the order.
Code snippets
Client calls the BAP server to trigger Update:
router.post("/health_pharmacy/update_quantity", updateQuantity);
async function updateQuantity({ body }, res) {
try {
// .. Validate the client request before below function
await generateUpdateOrderRequest(body)
} catch (error) {
res.status(500).send(httpResponse("NACK", error));
}
};
BAP server generates the protocol request body
// Code to generate the protocol request body i.e. function generateUpdateOrderRequest() specified above
async function generateUpdateOrderRequest(clientRequestBody) {
/*
Example Request JSON :
{
"context": {
"domain": "nic2004:52311",
"country": "IND",
"city": "std:080",
"action": "update",
"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": {
"update_target": "items",
"order": {
"id": "order_1",
"state": "Active",
"items": [
{
"id": "vit_c",
"price" : {
"currency": "INR",
"value": "500"
},
"quantity": {
"selected": {
"count": 2
}
}
},
{
"id": "a_500",
"price" : {
"currency": "INR",
"value": "500"
},
"quantity": {
"selected": {
"count": 1
}
}
}
],
"billing": {
"name": "Jane Doe",
"address": {
"door": "21A",
"name": "ABC Apartments",
"locality": "HSR Layout",
"city": "Bengaluru",
"state": "Karnataka",
"country": "India",
"area_code": "560102"
},
"email": "[email protected]",
"phone": "+919876523210"
},
"fulfillment": {
"type": "HOME-DELIVERY",
"start": {
"location": {
"id": "abc_medicines_koramangala",
"descriptor": {
"name": "ABC Medicines"
},
"gps": "12.9349377,77.6055586"
},
"contact": {
"phone": "+919999999999",
"email": "[email protected]"
}
},
"end": {
"location": {
"gps": "12.914028, 77.638698",
"address": {
"door": "21A",
"name": "ABC Apartments",
"locality": "HSR Layout",
"city": "Bengaluru",
"state": "Karnataka",
"country": "India",
"area_code": "560102"
}
},
"time": {
"range": {
"start": "2021-06-15T07:11:36.212Z",
"end": "2021-06-15T07:12:36.212Z"
}
},
"instructions": {
"name": "drop off instructions",
"short_desc": "Leave at door step"
},
"contact": {
"phone": "+919876543210",
"email": "[email protected]"
}
},
"customer": {
"person":{
"name": "John Doe",
"image": "https://mock_bap.com/prescription1.jpg",
"dob": "1991-08-12"
}
}
},
"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"
},
"payment": {
"uri": "https://api.bpp.com/pay?amt=$amount&txn_id=ksh87yriuro34iyr3p4&mode=upi&vpa=bpp@upi",
"tl_method": "http/get",
"params": {
"transaction_id": "ksh87yriuro34iyr3p4",
"amount": "1100",
"mode": "upi",
"vpa": "bpp@upi"
},
"type": "ON-FULFILLMENT",
"status": "NOT-PAID"
}
}
}
}
*/
//The below code generates the above example JSON.
const transactionId = _.get(clientRequestBody, "transactionId");
// Returns the Context including MessageId
const orderId = _.get(clientRequestBody, orderId);
const userBillingDetails = _.get(clientRequestBody, "userBillingDetails");
const locationDetails = _.get(clientRequestBody, "locationDetails");
const pickupInstructions = _.get(clientRequestBody, "pickupInstructions");
const dropInstructions = _.get(clientRequestBody, "dropInstructions");
const updateRequestBody = {
context,
message: {
// Construct from the request
};
};
//call protocol update order
const response = await callUpdate(updateRequestBody);
res
.status(200)
.send({ ...response.data, messageId: context["message_id"] });
}
BAP server calls protocol update to the network
async function callUpdate(updateRequestBody) {
// It lookups the registry for BG OR BPP
let uri = lookup();
// Construct Header
const headers = constructAuthHeader(); // Auth Header with digital Signature
return axios({ url: `${uri}/health_pharmacy/updare`, method: "POST", headers, data: updateRequestBody });
}
BAP receives protocol on_update
/*
Example Response JSON:
{
"context": {
"domain": "nic2004:52311",
"country": "IND",
"city": "std:080",
"action": "on_update",
"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": {
"id": "order_1",
"state": "Active",
"items": [
{
"id": "vit_c",
"price" : {
"currency": "INR",
"value": "500"
},
"quantity": {
"selected": {
"count": 2
}
}
},
{
"id": "a_500",
"price" : {
"currency": "INR",
"value": "500"
},
"quantity": {
"selected": {
"count": 1
}
}
}
],
"billing": {
"name": "Jane Doe",
"address": {
"door": "21A",
"name": "ABC Apartments",
"locality": "HSR Layout",
"city": "Bengaluru",
"state": "Karnataka",
"country": "India",
"area_code": "560102"
},
"email": "[email protected]",
"phone": "+919876523210"
},
"fulfillment": {
"type": "HOME-DELIVERY",
"start": {
"location": {
"id": "abc_medicines_koramangala",
"descriptor": {
"name": "ABC Medicines"
},
"gps": "12.9349377,77.6055586"
},
"contact": {
"phone": "+919999999999",
"email": "[email protected]"
}
},
"end": {
"location": {
"gps": "12.914028, 77.638698",
"address": {
"door": "21A",
"name": "ABC Apartments",
"locality": "HSR Layout",
"city": "Bengaluru",
"state": "Karnataka",
"country": "India",
"area_code": "560102"
}
},
"time": {
"range": {
"start": "2021-06-15T07:11:36.212Z",
"end": "2021-06-15T07:12:36.212Z"
}
},
"instructions": {
"name": "drop off instructions",
"short_desc": "Leave at door step"
},
"contact": {
"phone": "+919876543210",
"email": "[email protected]"
}
},
"customer": {
"person":{
"name": "John Doe",
"image": "https://mock_bap.com/prescription1.jpg",
"dob": "1991-08-12"
}
}
},
"quote": {
"price": {
"currency": "INR",
"value": "1700"
},
"breakup": [
{
"title": "Vitamin C",
"price": {
"currency": "INR",
"value": "1000"
}
},
{
"title": "Antibiotics",
"price": {
"currency": "INR",
"value": "500"
}
},
{
"title": "Delivery Charge",
"price": {
"currency": "INR",
"value": "100"
}
}
],
"ttl": "P1H"
},
"payment": {
"uri": "https://api.bpp.com/pay?amt=$amount&txn_id=ksh87yriuro34iyr3p4&mode=upi&vpa=bpp@upi",
"tl_method": "http/get",
"params": {
"transaction_id": "ksh87yriuro34iyr3p4",
"amount": "1700",
"mode": "upi",
"vpa": "bpp@upi"
},
"type": "ON-FULFILLMENT",
"status": "NOT-PAID"
}
}
}
}
*/
// Auth middleware authenticates the digital signature of the incoming request
router.post("/health_pharmacy/on_update", auth, onTrack);
async function onTrack({ body }, res) {
// Save the response to Database
await saveToDb(body);
};
Client polls BAP to get the on_update results
// Endpoint for the client to poll the search data based on the message id
async function getMessageById(req) {
try {
const messageId = _.get(req, "messageId");
// Get the data using message Id
const response = await getData(messageId);
res.status(200).send(httpResponse('ACK', "", response));
} catch(error) {
res.status(500).send(httpResponse("NACK", error));
}
};