1.2.3 • Published 7 months ago

pos-validation-sdk v1.2.3

Weekly downloads
-
License
MIT
Repository
-
Last release
7 months ago

8112 Validation Functions

This document provides information on how to use the libraries defined in (AI) 8112 Validation Function for Point Of Sale.

📌 Functions


Inject Redis Client

This is optional step. If you want to use local database for optimization, inject a ioredis client to the SDK library. You will have to configure the ioredis client with the correct host, port, and password and then inject it to the SDK library.

Function Signature:

set_redis_client(redis_client);

Example Usage:

const redis = require('ioredis');
const redisClient = new redis({ host: 'localhost', port: 6379, password: 'password' });
set_redis_client(redisClient);

Configure API Client

This is required step. You will have to configure the API client with the correct endpoint, timeout, number of retries, and retry interval.

Function Signature:

configure_api_client(tcb_endpoint, http_timeout, no_of_retries, retry_interval);

Example Usage:

10000 - 10 seconds timeout 3 - 3 retries 1000 - 1 second retry interval

configure_api_client('https://api.try.thecouponbureau.org', 10000, 3, 1000);

🔑 Get Access Token

Function Signature:

get_access_token(access_key, secret_key);

The access_key and secret_key are the credentials of the TCB backend.

The function returns an access token which is used in other functions.

If the function fails, it will throw an exception.

Example Usage:

const access_token = get_access_token('access_key', 'secret_key');

Response:

{
  "token": "ACCESS_TOKEN"
}

🔑 Set Access Token

Function Signature:

This is required step to use the SDK. Once you get the access token, initialize the SDK with the access token before using other functions.

set_access_token(access_key, access_token);

🛒 Get Coupons Valid for Basket (coupons_valid_for_basket)

Function Signature:

coupons_valid_for_basket(
  input,
  retailer_email_domain
);

Input Format:

{
  "basket": [
    {
      "product_code": "5012345678900",
      "price": 0.25,
      "quantity": 2,
      "unit": "item"
    },
    {
      "product_code": "037000934677",
      "price": 1.34,
      "quantity": 3,
      "unit": "item"
    }
  ],
  "coupons": [
    "8112009988459000019133983841900001", 
    "8112009988459000019133983841900002"
  ]
}

The basket contains the items a user has bought, and coupons include the 8112 coupons scanned at the checkout counter. This can be a bundle ID, fetch code, single serialized data string, FSI coupon, or any combination.

retailer_email_domain is the email domain of the retailer. It must be provided to validate the coupons using accelerator API. If you are using retailer API, you can skip this parameter (pass null).

The function calculates the discount, makes necessary API calls to the TCB backend, and selects the optimal possible discount. It returns:

Output Format:

{
  "basket_validation_output": {
    "discount_in_cents": 200,
    "applied_coupons": [
      {
        "coupon_code": "8112009988459000019133983841900001",
        "face_value_in_cents": 100,
        "product_codes": {
          "gtins": [
            "5012345678900"
            "037000934677"
          ]
        }
      },
      {
        "coupon_code": "8112009988459000019133983841900002",
        "face_value_in_cents": 100,
        "product_codes": {
          "gtins": [
            "037000934677"
          ]
        }
      }
    ]
  },
  "execution_time_in_ms": 1000
}

Description:

  • discount_in_cents → Total discount applied.
  • applied_coupons → List of applied coupons.
    • face_value_in_cents → Discount per coupon.
    • product_codes → Basket items used to calculate the discount.

Example POS Receipt Representation:

1 coupon applied.          - $1

The discount_in_cents value can be used to reduce the total payable amount.


🛒 Redeem Coupons (redeem_coupons)

This function is used to redeem coupons. Execute this function only after you have validated the coupons using coupons_valid_for_basket function and applied the discount to the basket. As soon as you finish the transaction, execute this function to redeem the coupons in TCB backend.

Function Signature:

redeem_coupons(
  coupons,
  retailer_email_domain
);

coupons is the list of coupons to redeem.

retailer_email_domain is the email domain of the retailer. It must be provided to validate the coupons using accelerator API. If you are using retailer API, you can skip this parameter (pass null).

The function returns the list of successfully redeemed coupons.

Example Usage:

const redeemed_coupons = redeem_coupons(coupons, retailer_email_domain);

Response:

{
  "redeemed_coupons": ["8112009988459000019133983841900001", "8112009988459000019133983841900002"],
  "execution_time_in_ms": 1000
}

🔄 Rollback Coupons

Use this function to rollback coupons. This function is used to rollback coupons if transaction fails.

Function Signature:

rollback_coupons(coupons, retailer_email_domain);

coupons is the list of coupons to rollback.

retailer_email_domain is the email domain of the retailer. It must be provided to validate the coupons using accelerator API. If you are using retailer API, you can skip this parameter (pass null).

The function returns the list of successfully rolled back coupons.

Example Usage:

const rolled_back_coupons = rollback_coupons(coupons, retailer_email_domain);

Response:

{
  "rolled_back_coupons": ["8112009988459000019133983841900001", "8112009988459000019133983841900002"],
  "execution_time_in_ms": 1000
}

📦 Populate Local Database

This function is used to populate the local database with all the master offer files purchase requirements. This is useful if you are using local database for optimization. Sample code to populate the local database is given below. Change the dates appropriately to get the master offer files for the desired date range.

Function Signature:

populate_local_database(from_date, to_date);

Example Usage:

const dotenv = require('dotenv');
dotenv.config();

const ioredis = require('ioredis');
const { get_access_token, set_access_token, configure_api_client, set_redis_client, populate_local_database } = require("../index");

const tcb_endpoint = process.env.TBC_ENDPOINT;
const tcb_access_key = process.env.TBC_ACCESS_KEY;
const tcb_secret_key = process.env.TBC_SECRET_KEY;

const redisConnObj = {
    host: process.env.REDIS_HOST,
    port: process.env.REDIS_PORT,
};

const redisClient = new ioredis(redisConnObj);

(async() => {
    await configure_api_client(tcb_endpoint, 10000, 3, 1000);
    const token = await get_access_token(tcb_access_key, tcb_secret_key);;
    set_access_token(tcb_access_key, token);
    set_redis_client(redisClient);

    // Check if the database is synched once, if not, sync last 6 months data else last 2 days data
    const last_synced_date = await redisClient.get("LAST_SYNCED_DATE");
    if (!last_synced_date) {
        let six_months_ago = new Date();
        six_months_ago.setMonth(six_months_ago.getMonth() - 6);
        console.log("Syncing last 6 months data");
        await populate_local_database(six_months_ago.toISOString().split('T')[0], new Date().toISOString().split('T')[0]);
    } else {
        console.log("Syncing last 2 days data");
        let two_days_ago = new Date();
        two_days_ago.setDate(two_days_ago.getDate() - 2);   
        await populate_local_database(two_days_ago.toISOString().split('T')[0], new Date().toISOString().split('T')[0]);
    }

    await redisClient.set("LAST_SYNCED_DATE", new Date().toISOString().split('T')[0]);

    process.exit(0);
})();

📦 Express Server

This is a sample express server to demonstrate how to use the SDK. It is a simple server that validates the coupons and redeems them.

Create a new directory and initialize the project with the following commands:

npm init -y

Install Dependencies:

npm install dotenv express ioredis pos-validation-sdk

Sample Code:

const dotenv = require('dotenv');
dotenv.config();

const express = require("express");
const ioredis = require('ioredis');
const { get_access_token, set_access_token, coupons_valid_for_basket, redeem_coupons, rollback_coupons, configure_api_client, set_redis_client } = require("pos-validation-sdk");
const app = express();

const tcb_endpoint = process.env.TBC_ENDPOINT;

app.use(express.json());

let redisConnObj = {
    host: process.env.REDIS_HOST,
    port: process.env.REDIS_PORT,
};

// const redisClient = null;
const redisClient = new ioredis(redisConnObj);

function return_error_response(res, error) {
    if (error.response) {
        delete error.response.data.execution_start_time;
        delete error.response.data.execution_time_in_ms;
        return res.status(error.response.status).json(error.response.data);
    }
    return res.status(500).json({ status: "error", message: error.message });
}

app.post("/get_access_token", async (req, res) => {
    try {
        const { access_key, secret_key } = req.body;
        await configure_api_client(tcb_endpoint, 10000, 3, 1000);
        const token = await get_access_token(access_key, secret_key);
        res.json({ token });
    } catch (error) {
        return return_error_response(res, error);
    }
});

app.post("/coupons_valid_for_basket", async (req, res) => {
    try {
        const start_time = performance.now();
        const input = req.body;
        const { retailer_email_domain, access_key, access_token, use_redis } = req.headers;
        await configure_api_client(tcb_endpoint, 10000, 3, 1000);
        set_access_token(access_key, access_token);
        if ( use_redis ) set_redis_client(redisClient);
        const basket_validation_output = await coupons_valid_for_basket(input, retailer_email_domain);
        const end_time = performance.now();
        res.json({ basket_validation_output, execution_time_in_ms: Math.round(end_time - start_time) });
    } catch (error) {
        return return_error_response(res, error);
    }
});

app.post("/redeem_coupons", async (req, res) => {
    try {
        const start_time = performance.now();
        const { coupons, retailer_email_domain } = req.body;
        const { access_key, access_token, use_redis } = req.headers;
        await configure_api_client(tcb_endpoint, 10000, 3, 1000);
        set_access_token(access_key, access_token);
        if ( use_redis ) set_redis_client(redisClient);
        const redeemed_coupons = await redeem_coupons(coupons, retailer_email_domain);
        const end_time = performance.now();
        res.json({ redeemed_coupons, execution_time_in_ms: Math.round(end_time - start_time) });
    } catch (error) {
        return return_error_response(res, error);
    }
});

app.post("/rollback_coupons", async (req, res) => {
    try {
        const start_time = performance.now();
        const { coupons, retailer_email_domain } = req.body;
        const { access_key, access_token } = req.headers;
        await configure_api_client(tcb_endpoint, 10000, 3, 1000);
        set_access_token(access_key, access_token);
        const rolled_back_coupons = await rollback_coupons(coupons, retailer_email_domain);
        const end_time = performance.now();
        res.json({ rolled_back_coupons, execution_time_in_ms: Math.round(end_time - start_time) });
    } catch (error) {
        return return_error_response(res, error);
    }
});

app.listen(process.env.PORT, () => {
    console.log(`Server is running on port ${process.env.PORT}`);
});

This code is secure and uses the access_key and secret_key to get the access token. Without a valid access_key and secret_key, the server will not validate the coupons.

Run the Server:

node index.js

Test the Server:

Get access token from the server.

curl -X POST 'http://SERVER_IP/get_access_token' \
-H 'Content-Type: application/json' \
--data '{ 
    "access_key": "ACCESS_KEY", 
    "secret_key": "SECRET_KEY" 
}'

Validate coupons for a basket.

curl -X POST 'http://SERVER_IP/coupons_valid_for_basket' \
-H 'Content-Type: application/json' \
-H 'use_redis: yes' \
-H 'access_key: ACCESS_KEY' \
-H 'access_token: ACCESS_TOKEN' \
--data '{
            "basket": [
              {
                "product_code": "037000930396",
                "price": 1.29,
                "quantity": 12,
                "unit": "item"
              },
              {
                "product_code": "7106919588011",
                "price": 1.81,
                "quantity": 13,
                "unit": "item"
              },
              {
                "product_code": "030772036433",
                "price": 5.44,
                "quantity": 2,
                "unit": "item"
              }
            ],
            "coupons": [
              "8112009988459000129133768829435944",
              "8112009988459000229133701244303366",
              "8112009988459000259133185516163434",
              "811200998845900014913380504049555",
              "8112009988459000239133444997582211"
            ]
          }'

Redeem coupons.

curl -X POST 'http://SERVER_IP/redeem_coupons' \
-H 'Content-Type: application/json' \
-H 'use_redis: yes' \
-H 'access_key: ACCESS_KEY' \
-H 'access_token: ACCESS_TOKEN' \
--data '{
            "coupons": [
              "8112009988459000129133768829435944",
              "8112009988459000229133701244303366",
              "8112009988459000259133185516163434",
              "811200998845900014913380504049555",
              "8112009988459000239133444997582211"
            ]
          }'

Rollback coupons.

curl -X POST 'http://SERVER_IP/rollback_coupons' \
-H 'Content-Type: application/json' \
-H 'access_key: ACCESS_KEY' \
-H 'access_token: ACCESS_TOKEN' \
--data '{
            "coupons": [
              "8112009988459000129133768829435944",
              "8112009988459000229133701244303366",
              "8112009988459000259133185516163434",
              "811200998845900014913380504049555",
              "8112009988459000239133444997582211"
            ]
          }'

📦 Hosted Sever

We have hosted the server on AWS. You can use the following link to test the server. Server IP: 107.21.121.102.

Use this IP address to test the server from the test commands given above.


✅ Conclusion

This document outlines how to use 8112 validation functions for point-of-sale systems, including get coupons valid for basket, redeem coupons and roll back coupons. For further details, refer to The Coupon Bureau (TCB) API Documentation.


📄 License

This project follows MIT License.

1.2.3

7 months ago

1.2.2

7 months ago

1.2.1

7 months ago

1.2.0

7 months ago

1.1.9

7 months ago

1.1.8

7 months ago

1.1.7

7 months ago

1.1.6

7 months ago

1.1.5

7 months ago

1.1.4

7 months ago

1.1.3

7 months ago

1.1.2

7 months ago

1.1.1

7 months ago

1.1.0

7 months ago

1.0.9

7 months ago

1.0.8

7 months ago

1.0.7

7 months ago

1.0.6

7 months ago

1.0.5

7 months ago

1.0.4

7 months ago

1.0.3

7 months ago

1.0.2

7 months ago

1.0.1

7 months ago

1.0.0

7 months ago