GV Service
Documentation for GV Service module in G1 CRM.
Gift Voucher (GV) Service API Documentation
Overview
The GV Service manages creation, sale, allocation, redemption, and import of Gift Vouchers (physical and e-GVs). It uses MongoDB for persistence and Redis for cart/session/verification and throttling. All routes are protected with permission-based guards unless explicitly skipped.
There are 2 types of gvs.
- Physical GV
- E-GV
Physical GV
Physical GV's are created before selling and is allocated to stores.
E-GV
E-GV are created at the time of selling but it's allocation are provided on each store bases like how many EGV a store can create and sell. This restrictions get refreshed on time to time bases as set in the gv group (i.e every day, week, month).
Pack:
Packs are logical booklet which has GV's. it's like bunch of gv inside single pack. while creating a group you can mention if you want to create a pack or not. (note: only physical gv can have the pack.)
Prerequisites
- Enterprise, Apps (POS/Web), Stores configured in CRM
- Authentication via SSO/App and Bearer token
- Proper permissions granted to caller (see each endpoint)
- Transaction Format (Common Module)
Base URL (Staging)
https://api.dev-engage.ginesys.one/gv/v1/Authentication
Authorization: Bearer <token>
x-tenant-id: <tenantId>Common Headers
x-tenant-id(string, required)Authorization(string, required) Bearer token
Important Notes
- Carts and some verifications expire automatically in Redis (generally 15–20 minutes windows)
- Physical GV sale validates allocation to store/app and voucher status
- EGV sale respects group/channel sale limits and generates on demand
- Redemption honors verification type (None/Pin/OTP), redemption channels, and partial redemption policy
- Most list/get APIs support
includeto enrich payloads
System Components
- Database: MongoDB via repositories under
@libs/gv,@libs/common,@libs/cdp,@libs/butler - Cache: Redis via
@libs/intent/cachewith keys from@libs/gvand@libs/common - Queue/Notifications:
@libs/intent/queueand CommonLib notifications for OTP/PIN and redemption events
Transaction Format APIs
All routes guarded by PermissionGuard.
Transaction format are basically kind of unique ids which are configured for specific gv groups.
Each Group will have one transaction id associated to it for creation of the gvNo.
List Transaction Format
POST common/v1/transaction-formats/list
Permission: 'gift-voucher-group::list', 'transaction-format::list'
Includes: audits
Supports: search. sorting, advanceFilters- Logic: Will List all the transaction format.
Request (example):
curl --location 'https://api.dev-engage.ginesys.one/common/v1/transaction-formats/list?page=1&perPage=1' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'Param:
page: 1
perPage: 10Response:
{
"status": 200,
"success": true,
"data": [
{
"id": "690461d30886f3fa617abcd6",
"name": "Doc",
"type": "gift-voucher",
"isSystemGenerated": false,
"preview": "DCA250001JYXASF",
"associationRefId": "6904571ea5e00a3a761d8628",
"status": "in-use",
"pattern": [
{
"index": 0,
"type": "fix-text",
"value": "DC"
},
{
"index": 1,
"type": "date",
"dateType": "month",
"dateFormat": "MYY",
"isFinancialYear": false,
"value": "A25"
},
{
"index": 2,
"type": "sequence",
"value": "0001",
"sequenceId": "690461d30886f3fa617abcd4",
"length": 4
},
{
"index": 3,
"type": "random",
"value": "GI23",
"length": 4
},
{
"index": 4,
"type": "fix-text",
"value": "SF"
}
]
}
],
"meta": {
"pagination": {
"perPage": 1,
"currentPage": 1,
"total": 469,
"totalPages": 469
}
}
}Create Transaction Format
POST common/v1/transaction-formats
Permission: 'gift-voucher-group::create', 'gift-voucher-group::update','transaction-format::create',
Includes: auditsLogic:
- Will check if Tf with same pattern exist or not.
- Will validate the pattern and create the transaction format.
Request (example):
curl --location 'https://api.dev-engage.ginesys.one/common/v1/transaction-formats' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"name": "Doc 123",
"type": "gift-voucher",
"pattern": [
{
"index": 0,
"type": "fix-text",
"value": "DO"
},
{
"index": 1,
"type": "date",
"value": "2425",
"dateFormat": "YYYY",
"dateType": "year",
"isFinancialYear": true
},
{
"index": 2,
"type": "sequence",
"value": "0001",
"length": 4
},
{
"index": 3,
"type": "random",
"value": "GI23",
"length": 4
},
{
"index": 4,
"type": "fix-text",
"value": "1T"
}
],
"startSequence": 1
}'Param:
{
"name": "Doc 123",
"type": "gift-voucher",
"pattern": [
{
"index": 0,
"type": "fix-text",
"value": "DO"
},
{
"index": 1,
"type": "date",
"value": "2425",
"dateFormat": "YYYY",
"dateType": "year",
"isFinancialYear": true
},
{
"index": 2,
"type": "sequence",
"value": "0001",
"length": 4
},
{
"index": 3,
"type": "random",
"value": "GI23",
"length": 4
},
{
"index": 4,
"type": "fix-text",
"value": "1T"
}
],
"startSequence": 1
}Response:
{
"status": 200,
"success": true,
"data": {
"id": "69049a7e0886f3fa617abd2e",
"name": "Doc 123",
"type": "gift-voucher",
"isSystemGenerated": false,
"preview": "DO25260001XHE11T",
"status": "unused",
"pattern": [
{
"index": 0,
"type": "fix-text",
"value": "DO"
},
{
"index": 1,
"type": "date",
"dateType": "year",
"dateFormat": "YYYY",
"isFinancialYear": true,
"value": "2425"
},
{
"index": 2,
"type": "sequence",
"value": "0001",
"sequenceId": "69049a7e0886f3fa617abd2c",
"length": 4
},
{
"index": 3,
"type": "random",
"value": "GI23",
"length": 4
},
{
"index": 4,
"type": "fix-text",
"value": "1T"
}
]
}
}Update Transaction Format
PUT common/v1/transaction-formats
Permission: 'gift-voucher-group::update', 'transaction-format::update',
Includes: auditsLogic:
- Will check if Tf with same pattern exist or not.
- Will validate the pattern and create the transaction format.
Request (example):
curl --location --request PUT 'https://api.dev-engage.ginesys.one/common/v1/transaction-formats' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"id": "69049a7e0886f3fa617abd2e",
"name": "Doc 123",
"type": "gift-voucher",
"pattern": [
{
"index": 0,
"type": "fix-text",
"value": "DO"
},
{
"index": 1,
"type": "date",
"value": "2425",
"dateFormat": "YYYY",
"dateType": "year",
"isFinancialYear": true
},
{
"index": 2,
"type": "sequence",
"value": "0001",
"length": 4
},
{
"index": 3,
"type": "random",
"value": "GI23",
"length": 4
},
{
"index": 4,
"type": "fix-text",
"value": "1T"
}
],
"startSequence": 1
}'Param:
{
"id": "69049a7e0886f3fa617abd2e",
"name": "Doc 123",
"type": "gift-voucher",
"pattern": [
{
"index": 0,
"type": "fix-text",
"value": "DO"
},
{
"index": 1,
"type": "date",
"value": "2425",
"dateFormat": "YYYY",
"dateType": "year",
"isFinancialYear": true
},
{
"index": 2,
"type": "sequence",
"value": "0001",
"length": 4
},
{
"index": 3,
"type": "random",
"value": "GI23",
"length": 4
},
{
"index": 4,
"type": "fix-text",
"value": "1T"
}
],
"startSequence": 1
}Response:
{
"status": 200,
"success": true,
"data": {
"id": "69049a7e0886f3fa617abd2e",
"name": "Doc 123",
"type": "gift-voucher",
"isSystemGenerated": false,
"preview": "DO25260001TDA21T",
"status": "unused",
"pattern": [
{
"index": 0,
"type": "fix-text",
"value": "DO"
},
{
"index": 1,
"type": "date",
"dateType": "year",
"dateFormat": "YYYY",
"isFinancialYear": true,
"value": "2425"
},
{
"index": 2,
"type": "sequence",
"value": "0001",
"sequenceId": "69049b9e0886f3fa617abd34",
"length": 4
},
{
"index": 3,
"type": "random",
"value": "GI23",
"length": 4
},
{
"index": 4,
"type": "fix-text",
"value": "1T"
}
]
}
}Validate Transaction Format
POST common/v1/transaction-formats/validate
Permission: 'gift-voucher-group::create',
'gift-voucher-group::update',
'transaction-format::create',Logic:
- Will check if Tf with same pattern exist or not.
- Will validate the pattern and create the transaction format.
Request (example):
curl --location 'https://api.dev-engage.ginesys.one/common/v1/transaction-formats/validate' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"name": "doc-2",
"type": "gift-voucher",
"pattern": [
{
"index": 0,
"type": "fix-text",
"value": "DO"
},
{
"index": 1,
"type": "date",
"value": "2425",
"dateFormat": "YYYY",
"dateType": "year",
"isFinancialYear": true
},
{
"index": 2,
"type": "sequence",
"value": "0001",
"length": 4
},
{
"index": 3,
"type": "random",
"value": "GI23",
"length": 4
},
{
"index": 4,
"type": "fix-text",
"value": "1T"
}
],
"startSequence": 1
}'Body:
{
"name": "doc-2",
"type": "gift-voucher",
"pattern": [
{
"index": 0,
"type": "fix-text",
"value": "DO"
},
{
"index": 1,
"type": "date",
"value": "2425",
"dateFormat": "YYYY",
"dateType": "year",
"isFinancialYear": true
},
{
"index": 2,
"type": "sequence",
"value": "0001",
"length": 4
},
{
"index": 3,
"type": "random",
"value": "GI23",
"length": 4
},
{
"index": 4,
"type": "fix-text",
"value": "1T"
}
],
"startSequence": 1
}Response:
{
"status": 200,
"success": true,
"data": {
"isDuplicate": true,
"isNameDuplicate": false,
"warnings": [
"Sequence will reset every year based on date format",
"Sequence can have maximum of 9999 unique transaction number every year"
],
"length": 16,
"maxPossibleNo": 16796160000
}
}Available Sequence
POST common/v1/transaction-formats/:id/available-sequence
Permission: 'gift-voucher::get', 'transaction-format::get'Logic:
- will give the total available sequence.
Request (example):
curl --location 'https://api.dev-engage.ginesys.one/common/v1/transaction-formats/67a9ada8581a7a0177e86f0d/available-sequence' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'Response:
{
"status": 200,
"success": true,
"data": {
"isSequenceAvailable": true,
"count": 9987
}
}Get Transaction Format
POST common/v1/transaction-formats/:id
Permission: 'gift-voucher::get', 'transaction-format::get'Logic:
- will give the existing transaction format.
Request (example):
curl --location 'https://api.dev-engage.ginesys.one/common/v1/transaction-formats/67a9ada8581a7a0177e86f0d?include=audits' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'Response:
{
"status": 200,
"success": true,
"data": {
"id": "67a9ada8581a7a0177e86f0d",
"name": "Secureexchange555483",
"type": "gift-voucher",
"isSystemGenerated": false,
"preview": "OB0012",
"associationRefId": "6904726f8487a84bc0e17be5",
"status": "in-use",
"pattern": [
{
"index": 0,
"type": "fix-text",
"value": "OB"
},
{
"index": 1,
"type": "sequence",
"value": "0012",
"sequenceId": "67a9ada8581a7a0177e86f0b",
"length": 4
}
],
"audits": {
"createdAt": "2025-02-10T07:41:28.123Z",
"updatedAt": "2025-10-31T09:01:09.416Z",
"createdById": "665d43fa8b49af2a7c506ada",
"createActor": "Akshay P"
}
}
}Categories APIs (categories)
All routes guarded by PermissionGuard.
A Category is used to group multiple GV groups under a single tag. By creating a category, you can organize and tag specific GV groups together for better management.
Create Category
POST /categories
Permission: gv-category -> create- Logic: Checks if the Category Exists on the same name or refId and throws error otherwise Creates GV Category
Request (example):
curl 'https://api.dev-engage.ginesys.one/gv/v1/categories' \
-H 'Content-Type: application/json' \
-H 'authorization: Bearer <token>' \
-H 'x-tenant-id: <tenantId>' \
--data-raw '{"name":"Jinendra"}'Body:
{
"name": "Jinendra", (string, required)
"refId": "CAT1" (string, optional)
}Response:
{
"status": 200,
"success": true,
"data": {
"id": "69044caea5e00a3a761d8608",
"name": "jinendra"
}
}List Categories
GET /categories
Permission: gv-category -> list
include: audit- Logic: Paginated search
Request (example):
curl 'https://api.dev-engage.ginesys.one/gv/v1/categories?queryFilter=page=1&perPage=100' \
-H 'authorization: Bearer <token>' \
-H 'x-tenant-id: <tenantId>'Query parameters (via queryFilter):
page(number, default 1)perPage(number, default 10)include(string, optional)
Response:
{
"status": 200,
"success": true,
"data": [
{ "id": "68907c692ee363f7f7a3a531", "name": "demo-101" },
{ "id": "67a323c872752eeaff79e1fe", "name": "physical" }
],
"meta": {
"pagination": {
"perPage": 100,
"currentPage": 1,
"total": 21,
"totalPages": 1
}
}
}Delete Category
DELETE /categories/:id
Permission: gv-category -> delete- Logic: If category is in use by any gv group it will throw an error otherwise Soft delete.
Configs APIs (configs)
All routes guarded by PermissionGuard.
Create Config
POST /configs
Permission: gv-config::create
Body: GVConfigDto- Logic: Creates GV configuration (redemption, multiple GV limits, verification type)
- DB:
gvConfigRepo.new(...) - Cache: none
List Configs
GET /configs
Permission: gv-config::list
Support: Search, Filters, AdvanceFilters, Sorting
Include: audits- Logic: Paginated search
curl --location 'http://localhost:5001/gv/v1/configs' \
--header 'x-tenant-id: <tenantId>' \
--header 'Authorization: Bearer <token>'{
"status": 200,
"success": true,
"data": [
{
"id": "67a08d2f72752eeaff79d06c",
"name": "Dsfg",
"description": "esdhgjkl",
"allowPartialRedemption": true,
"allowMultipleGVInSingleInvoice": false,
"allowReturn": true,
"authenticationType": "pin",
"gvAllowedInSingleInvoice": 0,
"audits": {
"createdAt": "2025-02-03T09:32:31.160Z",
"updatedAt": "2025-02-03T09:32:31.160Z",
"createdById": "665d43fa8b49af2a7c506ada",
"createActor": "665d43fa8b49af2a7c506ada"
}
},...
],
"meta": {
"pagination": {
"perPage": 10,
"currentPage": 1,
"total": 302,
"totalPages": 31
}
}
}Update Config
PUT /configs
Permission: gv-config::update
Include: audits- Logic:
- Checks if the Config is Available or not.
- Checks if config is being used already in the group.
- if yes can't allow to edit and throws error.
- if no Updates config
curl --location --request PUT 'https://api.dev-engage.ginesys.one/gv/v1/configs?include=audits' \
--header 'x-tenant-id: <tenantId>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"id": "69045338a5e00a3a761d8614",
"name": "Demo Config",
"description": "Something meaningful description of this GV Group",
"allowPartialRedemption": false,
"allowMultipleGVInSingleInvoice": false,
"allowReturn": true,
"verificationType": "pin",
"gvAllowedInSingleInvoice":10
}'Body:
{
"id": "69045338a5e00a3a761d8614",
"name": "Demo Config",
"description": "Something meaningful description of this GV Group",
"allowPartialRedemption": false,
"allowMultipleGVInSingleInvoice": false,
"allowReturn": true,
"verificationType": "pin",
"gvAllowedInSingleInvoice": 10
}Response :
{
"status": 200,
"success": true,
"data": {
"id": "69045338a5e00a3a761d8614",
"name": "Demo Config",
"description": "Something meaningful description of this GV Group",
"allowPartialRedemption": false,
"allowMultipleGVInSingleInvoice": false,
"allowReturn": true,
"authenticationType": "pin",
"gvAllowedInSingleInvoice": 10,
"audits": {
"createdAt": "2025-10-31T06:12:08.417Z",
"updatedAt": "2025-10-31T06:12:44.454Z",
"createdById": "665d43fa8b49af2a7c506ada",
"updatedById": "665d43fa8b49af2a7c506ada",
"createActor": "Akshay P",
"updateActor": "Akshay P"
}
}
}Groups APIs (groups)
Routes guarded by PermissionGuard and GvRefIdGuard.
Create Group
POST /groups
Permission: gift-voucher-group -> createpre-requisite:
- To create a gv group we will need gv category, gv config, store cluster created on crm, app connected to crm and transaction format.
Logic:
-
gv group can be for Egv or Physical gv.
-
gv group can have packs. but egv don't have the packs. (optional)
-
gv group has multiple validity optional like limitedTime and lifetime.
-
inside limited time you can choose effective date and validity type
-
In lifetime validity you can only select the effective date as there is no expiry.
-
effective date can be custom date from current date or voucher sales date.
-
There are 2 types of validity custom date and period.
-
In the period you can select the days of periods from the effective date.
-
After the validity date / period voucher inside the group can't be sold or redeemed.
-
There are 2 types of denominations dynamic and fixed.
-
Fixed denomination states the fixes gift value and sale value
-
Dynamic denomination states the gift value percentage of sale value. Means Sale value will be calculated on the bases of gift value and provided denomination percentage of the gift value. dynamic denomination will only have the min value, max value and sales Percentage.
-
validates config, category, denominations, type, validity, transaction format, etc.
Validity:
Life Time with Sales Date
"validity": {
"type": "lifetime",
"effectiveFrom": {
"type": "sales-date"
}
}
Life Time With Custom Date
"validity": {
"type": "lifetime",
"effectiveFrom": {
"type": "calendar-date",
"date": "2025-10-31T08:22:11.502Z"
}
}
Limited Time With Effective and Validity Custom Date
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "calendar-date",
"date": "2025-10-31T08:22:11.502Z"
},
"expiry": {
"type": "calendar-date",
"date": "2025-11-29T18:30:00.000Z",
},
},
Limited Time With Effective Custom Date and Validity In Period
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "calendar-date",
"date": "2025-10-31T08:22:11.502Z"
},
"expiry": {
"type": "period",
"days": 365,
},
},From the above examples you can create multiple combinations.
Dynamic and Fixed Denomination
[
{
"type": "dynamic-value",
"name": "Doc 2",
"minGiftValue": 100,
"maxGiftValue": 1000,
"saleValuePercentageGiftValue": 100
},
{
"type": "fix-value",
"name": "Doc 1",
"giftValue": 10,
"saleValue": 10,
}
]curl --location 'https://api.dev-engage.ginesys.one/gv/v1/groups' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"name": "Demo Documentation group",
"description": "test",
"categoryId": "69044caea5e00a3a761d8608",
"type": "egv",
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "calendar-date",
"date": "2025-12-18T18:30:00.000Z"
},
"expiry": {
"type": "period",
"date": "",
"days": 2,
"tempDays": "2",
"period": "day"
}
},
"createPack": false,
"denominations": [
{
"type": "fix-value",
"name": "d1",
"giftValue": 10,
"saleValue": 20
}
],
"redemptionChannels": [{"appId": "665d43f48b49af2a7c5048aa", "clusterIds": ["679dc39e4d5bc083264ef9db"]}],
"configId": "69045338a5e00a3a761d8614",
"storesList": [],
"transactionFormatId": "67add88ba3137a721e4a1fcf"
}'Body:
{
"name": "Demo Documentation group",
"description": "test",
"categoryId": "69044caea5e00a3a761d8608",
"type": "egv",
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "calendar-date",
"date": "2025-12-18T18:30:00.000Z"
},
"expiry": {
"type": "period",
"date": "",
"days": 2,
"tempDays": "2",
"period": "day"
}
},
"createPack": false,
"denominations": [
{
"type": "fix-value",
"name": "d1",
"giftValue": 10,
"saleValue": 20
}
],
"redemptionChannels": [
{
"appId": "665d43f48b49af2a7c5048aa",
"clusterIds": ["679dc39e4d5bc083264ef9db"]
}
],
"configId": "69045338a5e00a3a761d8614",
"storesList": [],
"transactionFormatId": "67add88ba3137a721e4a1fcf",
"imageSlug": "path to blob" (optional)
}Response:
{
"status": 200,
"success": true,
"data": {
"id": "6904571ea5e00a3a761d8628",
"name": "Demo Documentation Group",
"systemId": "GVG7358",
"description": "test",
"redemptionChannels": [
{
"appId": "665d43f48b49af2a7c5048aa",
"clusterIds": ["679dc39e4d5bc083264ef9db"]
}
],
"status": "voucher-not-created",
"type": "egv",
"categoryId": "69044caea5e00a3a761d8608",
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "calendar-date",
"date": "2025-12-18T18:30:00.000Z"
},
"expiry": {
"type": "period",
"date": null,
"days": 2
},
"expiryDate": "2025-12-20T18:30:00.000Z"
},
"createPack": false,
"transactionFormatId": "67add88ba3137a721e4a1fcf",
"isActive": true,
"stopSales": false
}
}Update Group
PATCH /groups
Permission: gift-voucher-group -> updateLogic:
- if the vouchers are not generated or imported in the group it can be updated. all the validation performed on the create api are being done in the update as well.
- if stopSales is send as true. all the voucher inside the group will not be allows to sell.
curl --location --request PATCH 'https://api.dev-engage.ginesys.one/gv/v1/groups' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"id": "6904571ea5e00a3a761d8628",
"name": "Demo Documentation group",
"description": "Test Import",
"redemptionChannels": [],
"type": "physical-gv",
"categoryId": "69044caea5e00a3a761d8608",
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "sales-date",
"date": "2025-01-03T10:53:26.035Z"
},
"expiry": {
"type": "calendar-date",
"date": "2025-01-03T10:52:31.000Z",
"days": null,
"period": "year"
},
"expiryDate": "2025-01-03T10:52:31.000Z"
},
"createPack": true,
"transactionFormatId": "6777ad3f42b0b29b9a92c796",
"isActive": true,
"stopSales": false,
"denominations": [
{
"type": "fix-value",
"name": "d1",
"giftValue": 10,
"saleValue": 20
}
],
"configId": "69045338a5e00a3a761d8614"
}'Body:
{
"id": "6904571ea5e00a3a761d8628",
"name": "Demo Documentation group", (optional)
"description": "Test Import", (optional)
"redemptionChannels": [], (optional)
"type": "physical-gv", (optional)
"categoryId": "69044caea5e00a3a761d8608", (optional)
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "sales-date",
"date": "2025-01-03T10:53:26.035Z"
},
"expiry": {
"type": "calendar-date",
"date": "2025-01-03T10:52:31.000Z",
"days": null,
"period": "year"
},
"expiryDate": "2025-01-03T10:52:31.000Z"
}, (optional)
"createPack": true, (optional)
"transactionFormatId": "6777ad3f42b0b29b9a92c796", (optional)
"isActive": true,(optional)
"stopSales": false,(optional)
"denominations": [
{
"type": "fix-value",
"name": "d1",
"giftValue": 10,
"saleValue": 20
}
],(optional)
"configId": "69045338a5e00a3a761d8614"(optional)
}Response:
{
"status": 200,
"success": true,
"data": {
"id": "6904571ea5e00a3a761d8628",
"name": "Demo Documentation Group",
"systemId": "GVG7358",
"description": "Test Import",
"redemptionChannels": [],
"status": "voucher-not-created",
"type": "physical-gv",
"categoryId": "69044caea5e00a3a761d8608",
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "sales-date",
"date": "2025-01-03T10:53:26.035Z"
},
"expiry": {
"type": "calendar-date",
"date": "2025-01-03T10:52:31.000Z",
"days": null
},
"expiryDate": "2025-01-03T10:52:31.000Z"
},
"createPack": true,
"transactionFormatId": "6777ad3f42b0b29b9a92c796",
"isActive": true,
"stopSales": false
}
}Activation Status
POST /groups/:id/activation-status
Permission: gift-voucher-group -> updateLogic:
- checks if group exist and updates it's activation status.
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/groups/6904571ea5e00a3a761d8628/activation-status' \
--header 'x-tenant-id: <tenantId>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"isActive": false
}'Body:
{
"isActive": false
}Response:
{
"status": 200,
"success": true,
"data": {
"msg": "Group Deactivated / Activated Successfully"
}
}List Groups
GET /groups/list
Permission: gift-voucher-group -> list
Includes: category,denomination,previewUrl
Supports:Search, Sort, AdvanceFilters, storeId, refCode, gvNocurl --location 'https://api.dev-engage.ginesys.one/gv/v1/groups/list?include=category%2Cdenominations%2CpreviewUrl&perPage=2&page=1' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'Response:
{
"status": 200,
"success": true,
"data": [
{
"id": "6904571ea5e00a3a761d8628",
"name": "Demo Documentation Group",
"systemId": "GVG7358",
"description": "Test Import",
"redemptionChannels": [],
"status": "voucher-not-created",
"type": "physical-gv",
"categoryId": "69044caea5e00a3a761d8608",
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "sales-date",
"date": "2025-01-03T10:53:26.035Z"
},
"expiry": {
"type": "calendar-date",
"date": "2025-01-03T10:52:31.000Z",
"days": null
},
"expiryDate": "2025-01-03T10:52:31.000Z"
},
"createPack": true,
"transactionFormatId": "6777ad3f42b0b29b9a92c796",
"isActive": false,
"stopSales": false,
"category": {
"id": "69044caea5e00a3a761d8608",
"name": "jinendra"
},
"denominations": [
{
"id": "69045a99a5e00a3a761d865e",
"name": "D1",
"type": "fix-value",
"giftValue": 10,
"saleValue": 20
}
]
},
{
"id": "68d3b4163d04ea37346aeeea",
"name": "Testtttt",
"systemId": "GVG7357",
"description": "erew",
"redemptionChannels": [
{
"appId": "665d43f48b49af2a7c5048aa",
"clusterIds": ["679dc39e4d5bc083264ef9eb", "67b8753be73dc050bbeeda77"]
}
],
"status": "voucher-not-created",
"type": "physical-gv",
"categoryId": "679dc3f8388e951ccfcb8e23",
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "sales-date",
"date": null
},
"expiry": {
"type": "period",
"date": null,
"days": 42
}
},
"createPack": true,
"imageSlug": "665d43f38b49af2a7c504865/customer-import/gv/download.png",
"transactionFormatId": "68d3b2a216aee1acaadd2c33",
"isActive": true,
"stopSales": false,
"category": {
"id": "679dc3f8388e951ccfcb8e23",
"name": "dummy_test"
},
"denominations": [
{
"id": "68d3b4163d04ea37346aeeeb",
"name": "Ttt",
"type": "fix-value",
"giftValue": 555,
"saleValue": 55
}
],
"previewUrl": "https://g1crmstagebackendstorage.blob.core.windows.net/customers/665d43f38b49af2a7c504865/customer-import/gv/download.png?sv=2023-11-03&spr=https%2Chttp&st=2025-10-31T06%3A36%3A33Z&se=2025-10-31T07%3A06%3A33Z&sr=b&sp=r&sig=qmcq96N48KQKk%2FPi0Z60q1cxDVPmGB3UcZTEUYg%2B9Cc%3D"
}
],
"meta": {
"pagination": {
"perPage": 2,
"currentPage": 1,
"total": 454,
"totalPages": 227
}
}
}Redemption Channel Details
GET /groups/:id
Permission: gift-voucher-group -> get
Include:denominations,category,config,denominationWiseCountLogic: if want to include the denominationWiseCount we need to provide the store id. otherwise it's optional.
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/groups/6904571ea5e00a3a761d8628?include=denominations%2Ccategory%2Cconfig' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'Response:
{
"status": 200,
"success": true,
"data": {
"id": "6904571ea5e00a3a761d8628",
"name": "Demo Documentation Group",
"systemId": "GVG7358",
"description": "Test Import",
"redemptionChannels": [
{
"appId": "665d43f48b49af2a7c5048aa",
"clusterIds": ["679dc39e4d5bc083264ef9eb"]
}
],
"status": "voucher-not-created",
"type": "physical-gv",
"categoryId": {
"_id": "69044caea5e00a3a761d8608",
"createdBy": "665d43fa8b49af2a7c506ada",
"createActor": "User",
"name": "jinendra",
"createdAt": "2025-10-31T05:44:14.773Z",
"updatedAt": "2025-10-31T05:44:14.773Z",
"__v": 0
},
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "sales-date",
"date": "2025-10-31T10:53:26.035Z"
},
"expiry": {
"type": "calendar-date",
"date": "2025-12-03T10:52:31.000Z",
"days": null
},
"expiryDate": "2025-12-03T10:52:31.000Z"
},
"createPack": true,
"transactionFormatId": "6777ad3f42b0b29b9a92c796",
"isActive": false,
"stopSales": false,
"denominations": [
{
"id": "69045a99a5e00a3a761d865e",
"name": "D1",
"type": "fix-value",
"giftValue": 10,
"saleValue": 20,
"voucherCount": 0
}
],
"category": {
"id": "69044caea5e00a3a761d8608",
"name": "jinendra"
},
"config": {
"id": "69045338a5e00a3a761d8614",
"name": "Demo Config",
"description": "Something meaningful description of this GV Group",
"allowPartialRedemption": false,
"allowMultipleGVInSingleInvoice": false,
"allowReturn": true,
"authenticationType": "pin",
"gvAllowedInSingleInvoice": 10
}
}
}Redemption Channel Details
GET /groups/:id/redemption-channel
Permission: gift-voucher-group -> listLogic: Returns redemption clusters/channels for group
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/groups/6904571ea5e00a3a761d8628/redemption-channel?include=audits%2Cdenominations' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'{
"status": 200,
"success": true,
"data": [
{
"app": {
"id": "665d43f48b49af2a7c5048aa",
"name": "Zwing POS"
},
"storeClusters": [
{
"id": "679dc39e4d5bc083264ef9eb",
"name": "Hhhhhhhhhhh",
"description": "tes",
"systemId": "CL00176"
}
]
}
]
}Allocate GV To Store
POST /groups/:id/allocate
Permission: gift-voucher-group::update
Body: AllocateGVToStoreDtoLogic: Allocates vouchers to stores/apps
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/groups/6904571ea5e00a3a761d8628/allocate' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"mode": "manual-allocation",
"allocation": [
{
"appId": "665d43f48b49af2a7c5048aa",
"storeId": "679dc3594d5bc083264ef9d3",
"fromSequence": 1,
"toSequence": 10,
"denominationId": "69045a99a5e00a3a761d865e"
}
]
}'Body:
Manual Allocation:
{
"mode": "manual-allocation",
"allocation": [
{
"appId": "665d43f48b49af2a7c5048aa",
"storeId": "679dc3594d5bc083264ef9d3",
"fromSequence": 1,
"toSequence": 10,
"denominationId": "69045a99a5e00a3a761d865e"
}
]
}Auto Allocation:
{
"allocation": [
{
"appId": "665d43f48b49af2a7c5048aa",
"storeId": "679dc3594d5bc083264ef9d3",
"count": 10,
"denominationId": "69045a99a5e00a3a761d865e"
}
],
"mode": "auto-allocation"
}Response:
{
"status": 200,
"success": true,
"data": {
"msg": "GVs Allocated to Store Successfully"
}
}Get Available Sequences
GET /groups/:id/available-sequences
Permission: gift-voucher-group::get- Logic: Computes available sequence ranges
- DB: group, vouchers
- Cache: none
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/groups/6904571ea5e00a3a761d8628/available-sequences' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'Response:
{
"status": 200,
"success": true,
"data": [
{
"id": "69045a99a5e00a3a761d865e",
"name": "D1",
"type": "fix-value",
"giftValue": 10,
"saleValue": 20,
"availableSequences": [
{
"start": 1,
"end": 100,
"count": 100
}
]
}
]
}EGV Sales Channel Upsert
POST /groups/egv/sales-channel
Permission: gift-voucher -> create
Body: CreateEGVSaleChannelDtoLogic:
- This will create a sales channel means that it provide the store authority to create and sell the adhoc egv.
- Here we can provide the count of vouchers to be sold in reset duration means a store can only generate and sell the voucher provided in a voucher count in side single refresh window.
- if 100 voucherCount provided and reset duration is of 1 week. A store can only generate 100 voucher in 1 week. This limit refreshes every week.
- This limits are caches in redis.
- Creates/updates EGV group sales channel, limits and reset windows
- Cache: clears
CacheKey.EGVStoreLimit
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/groups/egv/sales-channel' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '
{
"groupId": "6904726f8487a84bc0e17be5",
"transactionFormatId": "67a9ada8581a7a0177e86f0d",
"channels": [
{
"appId": "665d43f48b49af2a7c5048aa",
"storeId": "679dc3594d5bc083264ef9d3",
"voucherCount": 100,
"resetDuration": {
"duration": 1,
"type": "day"
},
"denominationIds": [
"690475098487a84bc0e17c44"
]
}
]
}'Body
{
"groupId": "6904726f8487a84bc0e17be5",
"transactionFormatId": "67a9ada8581a7a0177e86f0d",
"channels": [
{
"appId": "665d43f48b49af2a7c5048aa",
"storeId": "679dc3594d5bc083264ef9d3",
"voucherCount": 100,
"resetDuration": {
"duration": 1,
"type": "day" / "week" / "month" / "year"
},
"denominationIds": ["690475098487a84bc0e17c44"]
}
]
}Response:
{
"groupId": "6904726f8487a84bc0e17be5",
"transactionFormatId": "67a9ada8581a7a0177e86f0d",
"channels": [
{
"appId": "665d43f48b49af2a7c5048aa",
"storeId": "679dc3594d5bc083264ef9d3",
"voucherCount": 100,
"resetDuration": {
"duration": 1,
"type": "day"
},
"denominationIds": ["690475098487a84bc0e17c44"]
}
]
}EGV Sales Channel List
GET /groups/egv/sales-channel
Permission: gift-voucher-group -> list
Include: store, audits
Supports: filters,sorting
Custom: groupIdLogic:
- It has custom groupId filter.
- Paginated list of Enabled sales channels and their limits.
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/groups/egv/sales-channel?include=audits%2Cstore&groupId=6904726f8487a84bc0e17be5' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'{
"status": 200,
"success": true,
"data": [
{
"id": "690479628f1beb0fcc4c2048",
"appId": "667411d50d9855b7d19e8f21",
"groupId": "6904726f8487a84bc0e17be5",
"storeId": null,
"denominationIds": [],
"voucherSaleLimit": 0,
"reSetDuration": {
"duration": 0,
"type": "day"
},
"audits": {
"createdAt": "2025-10-31T08:54:58.094Z",
"updatedAt": "2025-10-31T09:01:09.415Z",
"createdById": "665d43fa8b49af2a7c506ada",
"createActor": "665d43fa8b49af2a7c506ada"
}
},
{
"id": "690479628f1beb0fcc4c204d",
"appId": "665d43f48b49af2a7c5048aa",
"groupId": "6904726f8487a84bc0e17be5",
"storeId": "679dc3594d5bc083264ef9d3",
"denominationIds": ["690475098487a84bc0e17c44"],
"voucherSaleLimit": 100,
"reSetDuration": {
"duration": 1,
"type": "week"
},
"audits": {
"createdAt": "2025-10-31T08:54:58.094Z",
"updatedAt": "2025-10-31T09:01:09.415Z",
"createdById": "665d43fa8b49af2a7c506ada",
"createActor": "665d43fa8b49af2a7c506ada"
},
"store": {
"id": "679dc3594d5bc083264ef9d3",
"name": "Store 102",
"refId": "655",
"address": "baner",
"state": "Maharashtra",
"city": "Pune",
"systemId": "ST02849"
}
}
],
"meta": {
"pagination": {
"perPage": 15,
"currentPage": 1,
"total": 2,
"totalPages": 1
}
}
}Gift Vouchers APIs (gift-vouchers)
Routes guarded by PermissionGuard and GvRefIdGuard.
Create Physical GVs (async generation)
POST /gift-vouchers/physical-gvs
Permission: gift-voucher -> createLogic: GV Generation are done using kafka. While generation is in progress no other GV generation request for the same group is taken. we can get the gv generation progress via progress api. Enqueues generation; async progress available
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-vouchers/physical-gvs' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"denominationMix": [
{
"denominationId": "69045a99a5e00a3a761d865e",
"quantity": 100
}
],
"groupId": "6904571ea5e00a3a761d8628",
"voucherQuantity": 100,
"transactionFormatId": "690461d30886f3fa617abcd6"
}'Body:
Group Without Pack
{
"denominationMix": [
{
"denominationId": "69045a99a5e00a3a761d865e",
"quantity": 100
}
],
"groupId": "6904571ea5e00a3a761d8628",
"voucherQuantity": 100,
"transactionFormatId": "690461d30886f3fa617abcd6"
}
Group With Pack
{
"denominationMix": [
{
"denominationId": "690475c28487a84bc0e17c5e",
"quantity": 10
}
],
"groupId": "690475c28487a84bc0e17c5d",
"voucherQuantity": 10,
"transactionFormatId": "67a9ad8b581a7a0177e86f03",
"packs": 10
}Response:
{
"status": 200,
"success": true,
"data": {
"msg": "Request Accepted. You will receive a notification once the process is completed"
}
}Update GV Status
POST /gift-vouchers/:id/status
Permission: gift-voucher::update- Logic: Updates status (block/unblock/return etc.)
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-vouchers/69046455d8f1b31ccfb61767/status' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"isBlocked": false
}'Body
{
"isBlocked": false / true
}Response
{
"status": 200,
"success": true,
"data": {
"msg": "GV Status Updated."
}
}List Vouchers
GET /gift-vouchers/list
Permission: gift-voucher::list
Includes:blockedAmount,audits,store,app,pack
Supports: search, sort, advanceFilters,
Filters: storeId,packId,groupId,Logic:
- This api has custom filter which can are applied in "and" condition.
- you can filter the gv list directly by storeId, packId and groupId
- In the include there is a term "blockedAmount". it's used when you need the blockedAmount of any voucher for information during transactions.
- Paginated search with includes
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-vouchers/list?groupId=6904571ea5e00a3a761d8628&perPage=1&page=1' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'Response:
{
"status": 200,
"success": true,
"data": [
{
"id": "69046456d8f1b31ccfb6188d",
"sequence": 100,
"gvNo": "DCA250099CS2KSF",
"type": "physical-gv",
"groupId": "6904571ea5e00a3a761d8628",
"denomination": {
"name": "D1",
"type": "fix-value",
"giftValue": 10,
"saleValue": 20,
"_id": "69045a99a5e00a3a761d865e"
},
"redeemedAmount": 0,
"balanceAmount": 10,
"config": {
"createdBy": "665d43fa8b49af2a7c506ada",
"updatedBy": "665d43fa8b49af2a7c506ada",
"createActor": "User",
"updateActor": "User",
"name": "Demo Config",
"description": "Something meaningful description of this GV Group",
"allowPartialRedemption": false,
"allowMultipleGVInSingleInvoice": false,
"allowReturn": true,
"verificationType": "pin",
"gvAllowedInSingleInvoice": 10,
"_id": "69045338a5e00a3a761d8614",
"createdAt": "2025-10-31T07:15:11.912Z",
"updatedAt": "2025-10-31T07:15:11.912Z",
"__v": 0
},
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "sales-date",
"date": "2025-10-31T10:53:26.035Z"
},
"expiry": {
"type": "calendar-date",
"date": "2025-12-03T10:52:31.000Z",
"days": null
},
"expiryDate": "2025-12-03T10:52:31.000Z"
},
"transactions": [],
"redemptionStatus": "not-redeemed",
"isAllocated": false,
"isSold": false,
"isBlocked": false,
"isVoid": false,
"isReturned": false
}
],
"meta": {
"pagination": {
"perPage": 1,
"currentPage": 1,
"total": 100,
"totalPages": 100
}
}
}Get Voucher
GET /gift-vouchers/:id?
Permission: gift-voucher -> get
Include:store,app,audits,recipientLogic:
- You can get the gv by id or gvNo.
Fetch by id or filters, also computes
blockedAmount - Also include the store, app, audits, recipient on include bases.
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-vouchers/69046456d8f1b31ccfb6188d?include=store%2Capp%2Caudits%2Crecipient' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-vouchers/?include=store%2Capp%2Caudits%2Crecipient&gvNo=DCA250099CS2KSF' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'{
"status": 200,
"success": true,
"data": {
"id": "69046456d8f1b31ccfb6188d",
"sequence": 100,
"gvNo": "DCA250099CS2KSF",
"type": "physical-gv",
"groupId": "6904571ea5e00a3a761d8628",
"denomination": {
"name": "D1",
"type": "fix-value",
"giftValue": 10,
"saleValue": 20,
"_id": "69045a99a5e00a3a761d865e"
},
"redeemedAmount": 0,
"balanceAmount": 10,
"blockedAmount": 0,
"config": {
"createdBy": "665d43fa8b49af2a7c506ada",
"updatedBy": "665d43fa8b49af2a7c506ada",
"createActor": "User",
"updateActor": "User",
"name": "Demo Config",
"description": "Something meaningful description of this GV Group",
"allowPartialRedemption": false,
"allowMultipleGVInSingleInvoice": false,
"allowReturn": true,
"verificationType": "pin",
"gvAllowedInSingleInvoice": 10,
"_id": "69045338a5e00a3a761d8614",
"createdAt": "2025-10-31T07:15:11.912Z",
"updatedAt": "2025-10-31T07:15:11.912Z",
"__v": 0
},
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "sales-date",
"date": "2025-10-31T10:53:26.035Z"
},
"expiry": {
"type": "calendar-date",
"date": "2025-12-03T10:52:31.000Z",
"days": null
},
"expiryDate": "2025-12-03T10:52:31.000Z"
},
"transactions": [],
"redemptionStatus": "not-redeemed",
"isAllocated": false,
"isSold": false,
"isBlocked": false,
"isVoid": false,
"isReturned": false,
"audits": {
"createdAt": "2025-10-31T07:25:11.566Z",
"updatedAt": "2025-10-31T07:25:11.566Z",
"createdById": "665d43fa8b49af2a7c506ada",
"createActor": "665d43fa8b49af2a7c506ada"
}
}
}Return GV
POST /gift-vouchers/return
Permission: gift-voucher::update
Body: ReturnGVDto- Logic: Processes returns and updates balances/status
- DB:
giftVoucherRepo.returnGV(...) - Cache: none
Import Flows
- Sample CSV
GET /gift-vouchers/imports/sample-csv
Permission: gift-voucher::list- Upload URLs
POST /gift-vouchers/imports/upload-urls
Permission: gift-voucher::get
Body: GetSignedUrls- Start Import
POST /gift-vouchers/imports
Permission: gift-voucher::create
Body: BulkImportVoucherDto | MigrationBulkImportVoucherDto- Job Progress
GET /gift-vouchers/imports/:id
Permission: gift-voucher::get- Import Issues
GET /gift-vouchers/imports/:id/issues
Permission: customer::import
Query: GetImportJobIssues- Logic: Standard import pipeline; issues paginated
- DB: import job, failed rows
- Cache: none
Voucher Generation Progress
GET /gift-vouchers/:id/progress
Permission: gift-voucher -> getcurl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-vouchers/6904571ea5e00a3a761d8628/progress' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'Response:
{
"status": 200,
"success": true,
"data": {
"progress": 0
}
}Validate Sequences for Allocation
POST /gift-vouchers/sequence/validate
Permission: gift-voucher -> getLogic:
- this api validates the voucher sequence allocation before it's allocated so no rejections are provided from the allocation api.
- allocation can be done in a 2 ways manual and auto.
- In auto allocation crm decides the allocation of the sequence to the stores
- In manual allocation user can choose the particular sequence from the available sequences.
- In auto allocation if quantity is 10 and sequence available has 2 parts first like from 1-10 there is 3 vouchers and 11-17 another 7 vouchers then multiple sequence will be provided in the response to match the quantity.
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-vouchers/sequence/validate' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"type": "auto-allocation",
"groupId": "6904571ea5e00a3a761d8628",
"allocations": [
{
"storeId": "679dc3594d5bc083264ef9d3",
"denominations": [
{
"id": "69045a99a5e00a3a761d865e",
"name": "D1",
"type": "fix-value",
"giftValue": 10,
"saleValue": 20,
"count": 10,
"denominationId": "69045a99a5e00a3a761d865e"
}
]
}
]
}'Auto Allocation:
{
"type": "auto-allocation",
"groupId": "6904571ea5e00a3a761d8628",
"allocations": [
{
"storeId": "679dc3594d5bc083264ef9d3",
"denominations": [
{
"count": 10,
"denominationId": "69045a99a5e00a3a761d865e"
}
]
}
]
}Manual Allocation:
{
"type": "manual-allocation",
"groupId": "6904571ea5e00a3a761d8628",
"allocations": [
{
"storeId": "679dc3594d5bc083264ef9d3",
"denominations": [
{
"denominationId": "69045a99a5e00a3a761d865e",
"start": 1,
"end": 10
}
]
},
{
"storeId": "679dc3594d5bc083264ef9cd",
"denominations": [
{
"start": 13,
"end": 15,
"denominationId": "69045a99a5e00a3a761d865e"
}
]
}
]
}Response:
{
"status": 200,
"success": true,
"data": [
{
"storeId": "679dc3594d5bc083264ef9d3",
"denominations": [
{
"denominationId": "69045a99a5e00a3a761d865e",
"count": 10,
"start": 1,
"end": 10
}
]
}
]
}Auto Multiple Sequence
{
"status": 200,
"success": true,
"data": [
{
"storeId": "679dc3594d5bc083264ef9d3",
"denominations": [
{
"denominationId": "69045a99a5e00a3a761d865e",
"count": 2,
"start": 11,
"end": 12
},
{
"denominationId": "69045a99a5e00a3a761d865e",
"count": 8,
"start": 21,
"end": 28
}
]
}
]
}Restore GVs
POST /gift-vouchers/restore
Permission: gift-voucher::create
Body: RestoreGVDto- Logic: Restores expired/returned GVs when permissible; message includes expired counts
- DB: updates vouchers
GV Pack APIs (gv-pack)
Routes guarded by PermissionGuard and GvRefIdGuard.
List Packs
GET /gv-pack/list
Permission: gift-voucher -> list
Includes:audits,store,app
Supports: Sorting, filters
Custom Filter: groupIdLogic:
- It has a customer filter groupId to filter the list for specific group
- Paginated list of packs
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gv-pack/list?groupId=690475c28487a84bc0e17c5d&include=audits%2Cstore%2Capp' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'Response
{
"status": 200,
"success": true,
"data": [
{
"id": "690475f3d8f1b31ccfb618f8",
"systemId": "GVP123404",
"groupId": "690475c28487a84bc0e17c5d",
"sequence": 123404,
"status": "created",
"audits": {
"createdAt": "2025-10-31T08:40:19.898Z",
"updatedAt": "2025-10-31T08:40:19.898Z",
"createdById": "665d43fa8b49af2a7c506ada",
"createActor": "Akshay P"
}
}
],
"meta": {
"pagination": {
"perPage": 1,
"currentPage": 1,
"total": 10,
"totalPages": 10
}
}
}Validate Pack Sequences
POST /gv-pack/sequence/validate
Permission: gift-voucher::get
Body: PackSequenceAllocationDtoLogic:
- There are two types of sequence allocation auto and manual
- In auto allocation crm decides the sequence.
- In manual allocation user decides the sequence.
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gv-pack/sequence/validate' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"type": "auto-allocation",
"groupId": "690475c28487a84bc0e17c5d",
"allocations": [
{
"storeId": "679dc3594d5bc083264ef9d3",
"count": 10
}
]
}'Body:
Auto Allocation
{
"type": "auto-allocation",
"groupId": "690475c28487a84bc0e17c5d",
"allocations": [
{
"storeId": "679dc3594d5bc083264ef9d3",
"count": 10
}
]
}
Manual Allocation
{
"type": "manual-allocation",
"groupId": "690475c28487a84bc0e17c5d",
"allocations": [
{
"storeId": "679dc3594d5bc083264ef9d3",
"start": 123395,
"end": 123396
}
]
}Sale & Redemption APIs (gift-voucher/sale)
Routes guarded by PermissionGuard and GvRefIdGuard.
Add Physical GV to Cart
POST /gift-voucher/sale/physical-gvs/cart
Permission: gift-voucher::saleOperations: Add GV to Cart (New / Existing) Modes: Auto, Manual
Logic:
- This api can add gv to cart for selling.
- Cart will be created once the gv are added a unique cart id will be provided (sessionId)
- voucher can be added automatic or manual.
- In auto mode voucher gift value and denomination needs to be provided.
- In manual mode gvId or gvNo needs to be provided.
- Cart is stored inside the redis cache
- While adding voucher to cart if cart session id is provided it will not create a new cart and will add the voucher to the provided cart.
- Validates group, voucher status/allocation, locks vouchers, builds cart item(s)
- DB: reads groups, vouchers, packs
- Cache:
- Cart JSON at
CacheKey.GVCart(<sessionId>)(EX 900) - Per-GV cart presence at
CacheKey.GVInCart(<gvId>)(EX 900) - Redis Lua to merge/update cart preserving TTL
- Cart JSON at
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/physical-gvs/cart' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"mode": "auto",
"vouchers": [
{
"voucherCount": 1,
"groupId": "6904571ea5e00a3a761d8628",
"denominationType": "fix-value",
"giftValue": 10
}
],
"storeId": "679dc3594d5bc083264ef9d3"
}'Auto Add
{
"mode": "auto",
"vouchers": [
{
"voucherCount": 1,
"groupId": "6904571ea5e00a3a761d8628",
"denominationType": "fix-value",
"giftValue": 10
}
],
"storeId": "679dc3594d5bc083264ef9d3"
}
Manual Add
{
"sessionId": "e7dee84d-bccf-48f1-8199-32e74666ee5d", (optional if new cart)
"mode": "manual",
"vouchers": [
{
"gvId": "69046454d8f1b31ccfb61764",
"groupId": "6904571ea5e00a3a761d8628"
}
],
"storeId": "679dc3594d5bc083264ef9d3"
}Response:
{
"status": 200,
"success": true,
"data": {
"sessionId": "76dda5a6-c3a7-448e-957c-5ca5165a08e7",
"physicalGVs": [
{
"saleValue": 20,
"giftValue": 10,
"gvId": "69046454d8f1b31ccfb61764",
"groupId": "6904571ea5e00a3a761d8628",
"appId": "665d43f48b49af2a7c5048aa",
"storeId": "679dc3594d5bc083264ef9d3",
"gvNo": "DCA250000NNJXSF",
"sequence": 1,
"type": "physical-gv",
"denominationType": "fix-value",
"denomination": {
"name": "D1",
"type": "fix-value",
"giftValue": 10,
"saleValue": 20,
"_id": "69045a99a5e00a3a761d865e"
},
"verificationType": "pin",
"groupName": "Demo Documentation Group",
"groupDescription": "Test Import"
}
]
}
}Confirm GV Sale
POST /gift-voucher/sale/confirm-sale
Permission: gift-voucher::sale
Body: ConfirmGVSaleDto- Logic: Requires customer tagged in cart; marks vouchers sold, generates PIN for Pin-config, sends notifications, attaches invoice (task)
- Cache: deletes cart key after success
- Notifications: email/SMS via CommonLib; fallback Kafka dispatch
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/confirm-sale' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"sessionId": "e7dee84d-bccf-48f1-8199-32e74666ee5d",
"invoiceId": "e7dee84d-bccf-48f1-8199-32e74666ee5d"
}'Body:
{
"sessionId": "e7dee84d-bccf-48f1-8199-32e74666ee5d",
"invoiceId": "e7dee84d-bccf-48f1-8199-32e74666ee5d"
}Response:
{
"status": 200,
"success": true,
"data": {
"msg": "Items in cart marked as sold."
}
}Add EGV to Cart (on-demand creation)
POST /gift-voucher/sale/e-gvs/cart
Permission: gift-voucher::sale
Body: AddEGVToCartDtoLogic:
- Validates group/channel, checks sale limits, creates EGVs, adds to cart
- While adding the gv in the cart it will create a egv as egv's are adhoc created.
- If GV is not sold it's sequence will be wasted.
DB: inserts vouchers; sequences and transaction numbers via commonLibService
Cache: cart at CacheKey.GVCart(<sessionId>); store limits at CacheKey.EGVStoreLimit(groupId, storeId|appId) with periodic reset
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/e-gvs/cart' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"eGVs": [
{
"voucherCount": 1,
"groupId": "6904726f8487a84bc0e17be5",
"giftValue":100,
"denominationType": "dynamic-value"
}
],
"storeId": "679dc3594d5bc083264ef9d3"
}'Body
{
"eGVs": [
{
"voucherCount": 1,
"groupId": "6904726f8487a84bc0e17be5",
"giftValue": 100,
"denominationType": "dynamic-value"
}
],
"storeId": "679dc3594d5bc083264ef9d3"
}Response:
{
"status": 200,
"success": true,
"data": {
"sessionId": "d38f3c2b-c1c0-4245-a425-7049287e1d7a",
"eGVs": [
{
"gvId": "690488b98487a84bc0e17d8d",
"appId": "665d43f48b49af2a7c5048aa",
"storeId": "679dc3594d5bc083264ef9d3",
"type": "egv",
"groupId": "6904726f8487a84bc0e17be5",
"denomination": {
"name": "Doc 2",
"type": "dynamic-value",
"saleValuePercentageGiftValue": 100,
"minGiftValue": 100,
"maxGiftValue": 1000,
"_id": "690475098487a84bc0e17c44"
},
"giftValue": 100,
"saleValue": 100,
"verificationType": "pin",
"gvNo": "OB0011",
"sequence": 1,
"denominationType": "dynamic-value",
"groupName": "Doc 1",
"groupDescription": "doc 1"
}
]
}
}Redeem GV (direct)
POST /gift-voucher/sale/redeem
Permission: gift-voucher::redeem
Body: RedeemGVDto- Logic: Validates expiry/effective date, sold status, redemption channel, verification (OTP/Pin/None), multiple-GV rules, partial policy; records debit transaction and updates status
- DB:
giftVoucherRepo.redeemGV(...) - Cache: OTP session
OtpCacheKey.Otp(transactionId); Pin verificationCacheKey.GVVerification(gvId, transactionId, GVPinVerification)
Block Amount (pre-authorization)
POST /gift-voucher/sale/block
Permission: gift-voucher::redeem
Body: BlockGVAmountDto- Logic: Checks already-blocked amount, validates like redeem, creates blocked record (30 mins expiry)
- DB:
gvBlockedAmountRepo.new(...) - Cache: OTP/Pin verification as above
Confirm Redemption (for blocked)
POST /gift-voucher/sale/confirm-redeem
Permission: gift-voucher::redeem
Body: ConfirmGVRedemptionDto- Logic: Validates all redemptionIds are valid and from single order; groups by GV, aggregates debits, determines final status, sends notifications, updates GV transactions, removes blocks
- DB:
giftVoucherRepo.redeemBulkGV(...),gvBlockedAmountRepo.unBlockGVAmount(...)
Unblock Amount
POST /gift-voucher/sale/unblock-amount
Permission: gift-voucher::redeem
Body: UnblockGVAmountDto- Logic: Deletes block docs; errors if already redeemed/unblocked
- DB:
gvBlockedAmountRepo.unBlockGVAmountDelete(...)
Send PIN (Pin verification only)
POST /gift-voucher/sale/verification/initiate
Permission: gift-voucher::redeem
Body: GVSendPinDto- Logic: For Pin config, issues a transactionId and caches verification context for 20 minutes; sends PIN via notifications
- Cache:
CacheKey.GVVerification(gvId, transactionId, GVPinVerification)
Verify (Pin)
POST /gift-voucher/sale/verify
Permission: gift-voucher::redeem
Body: GVVerificationDto- Logic: Validates provided PIN, sets cache flag
verify=true - Cache:
CacheKey.GVVerification(gvId, transactionId, GVPinVerification)
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/verify' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"transactionId":"c0f44474-0580-4ca2-abd9-29d2d0a66f6b",
"gvId":"690488b98487a84bc0e17d8d",
"verificationCode":"1463"
}'Body
{
"transactionId": "c0f44474-0580-4ca2-abd9-29d2d0a66f6b",
"gvId": "690488b98487a84bc0e17d8d",
"verificationCode": "1463"
}Response
{
"status": 200,
"success": true,
"data": {
"isVerified": true,
"transactionId": "c0f44474-0580-4ca2-abd9-29d2d0a66f6b"
}
}Cart Helpers
Get cart
GET /gift-voucher/sale/cart/:sessionId/validity (Permission: gift-voucher::sale)curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/cart/76dda5a6-c3a7-448e-957c-5ca5165a08e7' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'Response:
{
"status": 200,
"success": true,
"data": {
"cart": {
"sessionId": "76dda5a6-c3a7-448e-957c-5ca5165a08e7",
"physicalGVs": [
{
"verificationType": "pin",
"type": "physical-gv",
"sequence": 1,
"appId": "665d43f48b49af2a7c5048aa",
"denomination": {
"saleValue": 20,
"type": "fix-value",
"name": "D1",
"_id": "69045a99a5e00a3a761d865e",
"giftValue": 10
},
"groupDescription": "Test Import",
"saleValue": 20,
"groupName": "Demo Documentation Group",
"storeId": "679dc3594d5bc083264ef9d3",
"gvNo": "DCA250000NNJXSF",
"denominationType": "fix-value",
"giftValue": 10,
"gvId": "69046454d8f1b31ccfb61764",
"groupId": "6904571ea5e00a3a761d8628"
}
]
}
}
}Delete cart
DELETE /gift-voucher/sale/cart/:sessionId (Permission: gift-voucher::sale)curl --location --request DELETE 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/cart/ae639831-641e-4104-9bee-1f8f2e6ea3dc' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer <token>'Response:
No Response only api status will be 204.
Cart validity
GET /gift-voucher/sale/cart/:sessionId/validity
(Permission: gift-voucher::sale)curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/cart/76dda5a6-c3a7-448e-957c-5ca5165a08e7/validity' \
--header 'x-tenant-id: <id>' \
--header 'Authorization: Bearer 'Response:
{
"status": 200,
"success": true,
"data": {
"isCartValid": true
}
}Remove Item From cart
POST /gift-voucher/sale/cart/remove (Permission: gift-voucher::sale)curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/cart/remove' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"sessionId": "76dda5a6-c3a7-448e-957c-5ca5165a08e7",
// "groupIds": ["{{gvGroupId}}"]
// "egvIds": ["6780cbf27564116cacdb1e61"]
"pgvIds": ["69046454d8f1b31ccfb61764"]
}'Body
You can remove the egv and pgv via providing the ids or you can remove the gvs of single group. send only key which needs to be remove.
{
"sessionId": "76dda5a6-c3a7-448e-957c-5ca5165a08e7",
"groupIds": ["{{gvGroupId}}"]
"egvIds": ["6780cbf27564116cacdb1e61"]
"pgvIds": ["69046454d8f1b31ccfb61764"]
}Response:
{
"status": 200,
"success": true,
"data": {
"cart": {
"sessionId": "e7dee84d-bccf-48f1-8199-32e74666ee5d",
"physicalGVs": {}
}
}
}Tag Customer to cart
POST /gift-voucher/sale/cart/tag
(Permission: gift-voucher::sale)curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/cart/tag' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"customerId": "66de9e0022f11e899be88f8c",
"sessionId": "e7dee84d-bccf-48f1-8199-32e74666ee5d"
}'Body
{
"customerId": "66de9e0022f11e899be88f8c",
"sessionId": "e7dee84d-bccf-48f1-8199-32e74666ee5d"
}Response:
{
"status": 200,
"success": true,
"data": {
"cart": {
"physicalGVs": [
{
"verificationType": "pin",
"type": "physical-gv",
"sequence": 1,
"groupDescription": "Test Import",
"denomination": {
"saleValue": 20,
"type": "fix-value",
"name": "D1",
"_id": "69045a99a5e00a3a761d865e",
"giftValue": 10
},
"groupId": "6904571ea5e00a3a761d8628",
"saleValue": 20,
"appId": "665d43f48b49af2a7c5048aa",
"storeId": "679dc3594d5bc083264ef9d3",
"gvNo": "DCA250000NNJXSF",
"denominationType": "fix-value",
"giftValue": 10,
"gvId": "69046454d8f1b31ccfb61764",
"groupName": "Demo Documentation Group"
}
],
"sessionId": "e7dee84d-bccf-48f1-8199-32e74666ee5d",
"customerId": "66de9e0022f11e899be88f8c"
}
}
}Attach Recipient to cart
POST /gift-voucher/sale/attach-recipient
(Permission: gift-voucher::sale)Logic:
- Will attach recipient
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/attach-recipient' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data-raw '{
"sessionId": "e7dee84d-bccf-48f1-8199-32e74666ee5d",
"recipients": [
{
"gvId": "69046454d8f1b31ccfb61764",
"email": "jinendra.mehta@indexnine.com",
"phoneNumber": "+919384928458"
}
]
}'Body
{
"sessionId": "{{sessionId}}",
"recipients": [
{
"gvId": "69046454d8f1b31ccfb61764",
"email": "jinendra.mehta@indexnine.com",
"phoneNumber": "+919384928458"
}
]
}Response:
{
"status": 200,
"success": true,
"data": {
"msg": "Recipient attached successfully"
}
}Detach Recipient to cart
POST /gift-voucher/sale/detach-recipient
(Permission: gift-voucher::sale)Logic:
- Will Remove the attached recipient
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/detach-recipient' \
--header 'x-tenant-id: <token>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"sessionId": "e7dee84d-bccf-48f1-8199-32e74666ee5d",
"gvIds": ["69046454d8f1b31ccfb61764"]
}'Body
{
"sessionId": "{{sessionId}}",
"gvIds": ["69046454d8f1b31ccfb61764"]
}Response:
{
"status": 200,
"success": true,
"data": {
"msg": "Recipient detached successfully"
}
}Void Invoice
POST /gift-voucher/sale/invoice/void (Permission: gift-voucher::sale)Logic:
- Upon Voiding the invoice voucher associated with these invoice will be marked as a void and will not be allowed to redeem.
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/invoice/void' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"invoiceId": "e7dee84d-bccf-48f1-8199-32e74666ee5d"
}'Body
{
"invoiceId": "e7dee84d-bccf-48f1-8199-32e74666ee5d"
}Response:
{
"status": 200,
"success": true,
"data": {
"msg": "Invoice void successfully"
}
}Redemption
Block GV Amount
POST gift-voucher/sale/block
(Permission: gift-voucher::redeem)Logic:
- Upon Blocking the amount this amount will be blocked from the voucher and will not be allowed to use anywhere else. if there is remaining amount on the voucher it can be use at other transaction.
- This block is only for the 30 minutes. if not confirmed it will be release for general use.
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/block' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '
{
"gvId": "690488b98487a84bc0e17d8d",
"amount": 100,
"storeId": "679dc3594d5bc083264ef9d3",
"orderId": "ODR101",
"transactionId": "c0f44474-0580-4ca2-abd9-29d2d0a66f6b"
}'Body
{
"gvId": "690488b98487a84bc0e17d8d", (optional if provided gvNo)
"gvNo": "690488b98487a84bc0e17d8d", (Optional if provide gvId)
"amount": 100,
"storeId": "679dc3594d5bc083264ef9d3",
"orderId": "ODR101",
"transactionId": "c0f44474-0580-4ca2-abd9-29d2d0a66f6b"
}Response:
{
"status": 200,
"success": true,
"data": {
"_id": "69048e098487a84bc0e17de1",
"gvId": "690488b98487a84bc0e17d8d",
"amount": 100,
"transaction": {
"transactionId": "c0f44474-0580-4ca2-abd9-29d2d0a66f6b",
"type": "debit",
"debit": 100,
"balanceAmount": 0,
"invoiceId": "ODR101",
"appId": "665d43fa8b49af2a7c506ada",
"storeId": "679dc3594d5bc083264ef9d3",
"transactionTime": "2025-10-31T10:23:05.156Z",
"effectiveFrom": "2025-10-31T08:22:11.502Z",
"validUpto": "2026-10-31T08:22:11.502Z"
},
"orderId": "ODR101",
"deleteIfNotConfirmedAt": "2025-10-31T10:53:05.156Z"
}
}UnBlock GV Amount
POST gift-voucher/sale/unblock-amount
(Permission: gift-voucher::redeem)Logic:
- it will revert the block amount.
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/unblock-amount' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"redemptionIds": ["69048e098487a84bc0e17de1"]}'Body
{
"redemptionIds": ["69048e098487a84bc0e17de1"] (this is the _id provide on block api response)
}Response:
{
"status": 200,
"success": true,
"data": {
"msg": "Amount unblocked successfully"
}
}Confirm GV Redemption
POST gift-voucher/sale/confirm-redeem
(Permission: gift-voucher::redeem)Logic:
- it will confirm the redemption.
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-voucher/sale/confirm-redeem' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"redemptionIds": ["69048ebd8487a84bc0e17e0d"],
"invoiceId": "c0f44474-0580-4ca2-abd9"
}'Body
{
"redemptionIds": ["69048e098487a84bc0e17de1"], (redemptionIds are _id provide on block api response)
"invoiceId": "c0f44474-0580-4ca2-abd9"
}Response
{
"status": 200,
"success": true,
"data": {
"msg": "Redemption confirmed successfully"
}
}Restore GV
POST gift-voucher/restore
(Permission: gift-voucher::redeem)Logic:
- It will restore all the amount redeemed on the provided invoiceId of the gv. it will add the revert transaction and will credit the amounts in the respective gvs.
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-vouchers/restore' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"storeId": "679dc3594d5bc083264ef9d3",
"invoiceId": "c0f44474-0580-4ca2-abd9"
}'Body
{
"storeId": "679dc3594d5bc083264ef9d3",
"invoiceId": "c0f44474-0580-4ca2-abd9"
}Response
{
"status": 200,
"success": true,
"data": {
"msg": "Vouchers have been restored."
}
}Return GV
POST gift-voucher/return
(Permission: gift-voucher::redeem)Logic:
- It will be use if in case of gv is in not-redeemed state and being return to the store to get the cash amount back.
- upon return gv will not be able to redeem.
curl --location 'https://api.dev-engage.ginesys.one/gv/v1/gift-vouchers/return' \
--header 'x-tenant-id: <id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"returnGV":[
{
"refCode":"OB0011",
"reason":"not required",
"invoiceId":"c0f44474-0580-4ca2-abd9return"
}
]
}'Body
{
"returnGV": [
{
"refCode": "OB0011",
"reason": "not required",
"invoiceId": "c0f44474-0580-4ca2-abd9return"
}
]
}Response
{
"status": 200,
"success": true,
"data": [
{
"id": "690488b98487a84bc0e17d8d",
"sequence": 1,
"gvNo": "OB0011",
"type": "egv",
"groupId": "6904726f8487a84bc0e17be5",
"appId": "665d43f48b49af2a7c5048aa",
"denomination": {
"name": "Doc 2",
"type": "dynamic-value",
"saleValuePercentageGiftValue": 100,
"minGiftValue": 100,
"maxGiftValue": 1000,
"_id": "690475098487a84bc0e17c44"
},
"redeemedAmount": 0,
"balanceAmount": 0,
"config": {
"createdBy": "665d43fa8b49af2a7c506ada",
"updatedBy": "665d43fa8b49af2a7c506ada",
"createActor": "User",
"updateActor": "User",
"name": "Demo Config",
"description": "Something meaningful description of this GV Group",
"allowPartialRedemption": false,
"allowMultipleGVInSingleInvoice": false,
"allowReturn": true,
"verificationType": "pin",
"gvAllowedInSingleInvoice": 10,
"_id": "69045338a5e00a3a761d8614",
"createdAt": "2025-10-31T08:36:25.993Z",
"updatedAt": "2025-10-31T08:36:25.993Z",
"__v": 0
},
"validity": {
"type": "limited-time",
"effectiveFrom": {
"type": "calendar-date",
"date": "2025-10-31T08:22:11.502Z"
},
"expiry": {
"type": "period",
"date": "2025-11-29T18:30:00.000Z",
"days": 365
},
"expiryDate": "2026-10-31T08:22:11.502Z"
},
"transactions": [
{
"type": "credit",
"credit": 100,
"balanceAmount": 100,
"appId": "665d43f48b49af2a7c5048aa",
"storeId": "679dc3594d5bc083264ef9d3",
"transactionTime": "2025-10-31T10:06:05.305Z",
"effectiveFrom": "2025-10-31T08:22:11.502Z"
},
{
"transactionId": "c0f44474-0580-4ca2-abd9",
"type": "debit",
"debit": 100,
"balanceAmount": 0,
"invoiceId": "c0f44474-0580-4ca2-abd9",
"appId": "665d43fa8b49af2a7c506ada",
"storeId": "679dc3594d5bc083264ef9d3",
"transactionTime": "2025-10-31T10:26:05.315Z",
"effectiveFrom": "2025-10-31T08:22:11.502Z",
"validUpto": "2026-10-31T08:22:11.502Z"
},
{
"transactionId": null,
"invoiceId": "c0f44474-0580-4ca2-abd9",
"type": "credit",
"balanceAmount": 100,
"credit": 100,
"storeId": "679dc3594d5bc083264ef9d3",
"appId": "665d43fa8b49af2a7c506ada"
},
{
"type": "return",
"balanceAmount": 0,
"invoiceId": "c0f44474-0580-4ca2-abd9return",
"comment": "not required"
}
],
"redemptionStatus": "not-redeemed",
"isAllocated": true,
"isSold": true,
"isBlocked": false,
"isVoid": false,
"isReturned": true,
"invoiceId": "d38f3c2b-c1c0-4245-a425-7049287e1d7a",
"saleDate": "2025-10-31T10:06:05.305Z"
}
]
}Health
GET /health
Auth: SkipAuth