Adding an offer the cart and receiving a discounted quote (Node.js)

In this use case, the user applies an offer to a cart to avail a discount on a particular item or the total cart value. This offer is usually entered by the user as a code that when added, requests the seller to update the quote. Sometimes, the code may be used to avail additional services like free shipping, free packaging etc

Select

Code snippets

Client calls the BAP server to trigger select:

    router.post("/local_retail/add_offer", addOffer);

    async function addOffer({ body }, res) {
        try {
            //  .. Validate the client request before below function
            await generateSelectRequest(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 generateSelectRequest() specified above

    async function generateSelectRequest(clientRequestBody) {
/*
Example Request JSON :
{
    "context": {
        "domain": "local_retail",
        "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": {
            "offers": [
                {
                    "id": "offer_1"
                }
            ]
        }
    }
}
*/
        //The below code generates the above example JSON.
        const transactionId = _.get(body, "transactionId");
        // Returns the Context including MessageId
        const context = createContext(transactionId);
        // Construct Header
        const headers = constructAuthHeader(); // Auth Header
        const selectRequestBody = {
            context,
            message:  {
                // Construct from the request
            }
        };
        //call protocol select
        const response = await callSelect(selectRequestBody);
        res
        .status(200)
        .send({ ...response.data, messageId: context["message_id"] });
    }

BAP server calls protocol select to the network


    async function callSelect(selectRequestBody) {
        // 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}/local_retail/select`, method: "POST", headers, data: selectRequestBody });
    }

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": "1239890342",
        "message_id": "123793824",
        "timestamp": "2021-03-23T10:00:40.065Z"
    },
    "message": {
        "order": {
            "items": [
                {
                    "id": "item_1",
                    "price" : {
                        "currency": "INR",
                        "value": "40"
                    },
                    "quantity": {
                        "selected": {
                            "count": 1
                        }
                    }
                },
                {
                    "id": "item_4",
                    "price" : {
                        "currency": "INR",
                        "value": "60"
                    },
                    "quantity": {
                        "selected": {
                            "count": 2
                        }
                    }
                }
            ],
            "offers": [
                {
                    "id": "offer_1"
                }
            ],
            "quote": {
                "price": {
                    "currency": "INR",
                    "value": "110"
                },
                "breakup": [
                    {
                        "title": "Brown Bread 400 gm",
                        "price": {
                            "currency": "INR",
                            "value": "40"
                        }
                    },
                    {
                        "title": "Good Life Toned Milk 1L",
                        "price": {
                            "currency": "INR",
                            "value": "120"
                        }
                    },
                    {
                        "title": "50 rupees off",
                        "price": {
                            "currency": "INR",
                            "value": "-50"
                        }
                    }
                ],
                "ttl": "P4D"
            }
        }
    }
}
*/
    // Auth middleware authenticates the digital signature of the incoming request
    router.post("/local_retail/on_select", auth, onSelect);
    async function onSelect({ body }, res) {
        // Save the response to Database
        await saveToDb(body);
    };

Client polls BAP to get the on_select 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));
        }
    };