Skip to main content

Integration Guide — Points Configuration

Microservice: XDPeople.Soba.WebAPI (Core API)
Authentication: Bearer token (JWT) and tenant context — see Combined Login


Introduction

This guide describes the integration with the API to manage points configurations (rules for assigning points per document or per line).

The field criteriaType (PointsConfigCriteriaType) defines which nested criterion must be filled in the request:

ValueNameJSON Object
0HeaderdefaultHeaderCriteria (rule at the document header level).
1DefaultDetailsWithItemSearchCriteriadefaultDetailsItemCriteria (details with search by item).
2DefaultDetailsWithFamilySearchCriteriadefaultDetailsFamilyCriteria (details with search by family).

The other two criteria objects must be null or omitted, so that only the branch corresponding to criteriaType is defined in the body.


Available Endpoints

Public prefix: /gateway/points-config.

MethodURLBrief Description
GET/gateway/points-configLists configurations with optional pagination (page, pageSize); see pagination rules.
GET/gateway/points-config/{id}Retrieves a configuration by Guid.
GET/gateway/points-config/next-orderReturns the next suggested order number for a new entry.
POST/gateway/points-configCreates a configuration; response 201 Created with Guid in the body.
PUT/gateway/points-configUpdates an existing configuration; the id is in the body (PointsConfigDTO.Id); response 204 No Content.
DELETE/gateway/points-config/{id}Deletes by Guid; response 204 No Content.

List Configurations

URL: /gateway/points-configMethod: GET

See more →

Get by Identifier

URL: /gateway/points-config/{id}Method: GET

See more →

Next Order

URL: /gateway/points-config/next-orderMethod: GET

See more →

Create

URL: /gateway/points-configMethod: POST

See more →

Update

URL: /gateway/points-configMethod: PUT (identifier in body, not in route)

See more →

Delete

URL: /gateway/points-config/{id}Method: DELETE

See more →


Body Structure (PointsConfigDTO)

FieldTypeDescription
idGuid?Required on update; omitted or empty on create.
orderintPresentation / priority order (validation: see validations section).
descriptionstringDescription (required in the model).
activeboolActive configuration.
cumulativeboolAllow accumulation with other assignments.
allowDecimalPointsboolAllow decimal points.
startDatedate-timeStart of validity.
endDatedate-timeEnd of validity.
criteriaTypeint (enum)Criteria type (table above).
defaultHeaderCriteriaobject?Header criterion; see below.
defaultDetailsItemCriteriaobject?Item detail criterion; see below.
defaultDetailsFamilyCriteriaobject?Family detail criterion; see below.

Auxiliary listing fields (StartDateHolder, EndDateHolder, ActiveHolder, IsPreCompiled, etc.) may exist in the generated contract; for REST integration focus on the fields above and the nested criteria.

Common Base for Criteria (BaseCriteriaDTO)

Present in any non-null criterion:

FieldTypeDescription
totalPointsdecimalTotal points (model; often 0 on creation).
pointsBasedecimalPoints base (numeric validation in DTO).
eachYdecimalDenominator “Y” when the formula is X per Y; otherwise typically 0.
formulaBaseint (enum)0 = XTimes, 1 = XForY.

defaultHeaderCriteria (DefaultHeaderCriteriaDTO)

Includes the fields from BaseCriteriaDTO plus:

FieldTypeDescription
documentFieldint (enum)Document field used as the calculation base (document total, net, taxes, amount paid, etc.).

defaultDetailsItemCriteria / defaultDetailsFamilyCriteria

Extend BaseCriteriaDTO with:

FieldTypeDescription
detailFieldint (enum)Detail line field (quantity, prices, totals, etc.).
searchTypeint (enum)0 = list, 1 = individual.
searchPoolarraySet of references; each element follows DefaultDetailsItemDTO (item) or DefaultDetailsFamilyDTO (family), depending on the criterion.

searchPool Elements

CriterionElement DTOProperties
defaultDetailsItemCriteriaDefaultDetailsItemDTOid, description, keyId
defaultDetailsFamilyCriteriaDefaultDetailsFamilyDTOid, description, idParent (ancestor in the family hierarchy)

The searchType field in the detail criterion indicates the search mode (0 = list, 1 = individual). The persistence service mainly validates that searchPool is not empty when the corresponding criterion is present; keep searchType consistent with business intent and model consumers.

Enums (numeric values in JSON)

Expected values in the JSON body.

PointsConfigCriteriaType (criteriaType): 0 Header, 1 Item detail, 2 Family detail.

FormulaBaseEnum (formulaBase in criteria): 0 XTimes, 1 XForY.

SearchTypeEnum (searchType in detail criteria): 0 List, 1 Individual.

DocumentFieldsEnum (documentField in defaultHeaderCriteria):

ValueMeaning
0Document total
1Net total
2Taxes total
3Amount paid

DetailFieldsEnum (detailField in detail criteria):

ValueMeaning
0Quantity
1Price with VAT
2Line total with VAT
3Price without VAT
4Line total without VAT

Payload Requirements and Consistency

By criteriaType and formulaBase

criteriaTypeCriterion to sendsearchPooldocumentField / detailField
0 (Header)defaultHeaderCriteria filled; other criteria null / omitted.Not applicable.documentField required in the criterion object.
1 (Item detail)defaultDetailsItemCriteria filled; others null.Non-empty list when criterion is not null (server validation).detailField required in the object.
2 (Family detail)defaultDetailsFamilyCriteria filled; others null.Non-empty list when criterion is not null (server validation).detailField required in the object.
formulaBaseAdditional requirement (server + model)
0 (XTimes)eachY can be 0; focus on pointsBase.
1 (XForY)eachY must be strictly greater than zero (eachY > 0) whenever the nested criterion exists and is validated; values 0 or negative fail with PointsConfig.InvalidEachY (on server the condition is eachY <= 0).

Unknown or unmapped criteriaType

If criteriaType has a value not present in the service’s internal validator dictionary, ValidateCriteria does not execute any type-specific validators and returns success at this stage (only date validation continues to apply). For valid integrations, always use 0, 1, or 2 according to the PointsConfigCriteriaType enum.

Date Range

  • startDate cannot be after endDate. Otherwise: PointsConfig.InvalidDateRange.

null Criterion on Server

If the criterion object corresponding to the criteriaType is null, the specific validation branch (empty pool, eachY by type) is not executed and returns success for that part. For consistent data, always send the criterion aligned with criteriaType following the rules above.


Validations:

Create and Update

Applied before persisting. On update, if the id does not exist in ConfigList, the API returns PointsConfig.NotFound after loading definitions and before saving.

RuleError Code
startDate > endDatePointsConfig.InvalidDateRange
Header type, non-null criterion, formulaBase == XForY and eachY <= 0PointsConfig.InvalidEachY
Item detail type, non-null criterion, empty searchPoolPointsConfig.InvalidItemSearchPool
Item detail type, non-null criterion, XForY and eachY <= 0PointsConfig.InvalidEachY
Family detail type, non-null criterion, empty searchPoolPointsConfig.InvalidFamilySearchPool
Family detail type, non-null criterion, XForY and eachY <= 0PointsConfig.InvalidEachY

Other Error Results

CodeWhen it occurs (summary)
PointsConfig.NotFoundGET/PUT/DELETE with non-existent identifier in saved list.
PointsConfigCreate.FailException or unexpected failure on creation.
PointsConfigUpdate.FailException or unexpected failure on update.
PointsConfigDelete.FailException or unexpected failure on deletion.
PointsConfigSave.FailIConfigProvider.UpdateAsync returned false when saving definitions.
PointsGetAll.FailFailure listing (e.g., exception in GetAllAsync).
PointsGetById.FailFailure retrieving by id (e.g., exception).
PointsGetNextOrder.FailFailure calculating next order.
CreateDefaultSettingsFail.FailFailure creating default settings when none exist yet.
Config.NotFoundConstant in error module; associated with missing configurations in configuration scenarios.

Listing Validations (GET)

In GetAllAsync, query parameters are normalized in memory:

ParameterBehavior
pageIf omitted or less than 1, page 1 is used.
pageSizeIf omitted or less than or equal to 0, 20 is used; otherwise the requested value is applied up to a maximum of 100 (MaxPageSize).

Body Examples (POST / PUT)

URL: POST /gateway/points-config (create) or PUT /gateway/points-config (update with id in body).
Properties in camelCase. The other two criteria must be null (as below) or omitted.

Header — X times formula (criteriaType: 0, formulaBase: 0)

{
"order": 1,
"description": "One point per euro on the document total",
"active": true,
"cumulative": true,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 0,
"defaultHeaderCriteria": {
"totalPoints": 0,
"pointsBase": 1,
"eachY": 0,
"formulaBase": 0,
"documentField": 0
},
"defaultDetailsItemCriteria": null,
"defaultDetailsFamilyCriteria": null
}

documentField: 0 document total, 1 net total, 2 taxes total, 3 amount paid.

Header — X per Y formula (criteriaType: 0, formulaBase: 1)

eachY must be greater than zero; otherwise the server returns PointsConfig.InvalidEachY.

{
"order": 2,
"description": "10 points for every 50 € of net total",
"active": true,
"cumulative": false,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 0,
"defaultHeaderCriteria": {
"totalPoints": 0,
"pointsBase": 10,
"eachY": 50,
"formulaBase": 1,
"documentField": 1
},
"defaultDetailsItemCriteria": null,
"defaultDetailsFamilyCriteria": null
}

Detail by Item (criteriaType: 1, defaultDetailsItemCriteria)

searchPool cannot be empty when the criterion is filled (PointsConfig.InvalidItemSearchPool). Each element: id, description, keyId (item identifier in the system).

List (searchType: 0) — points apply to lines whose item belongs to the defined set.

{
"order": 3,
"description": "One point per quantity unit on selected items",
"active": true,
"cumulative": true,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 1,
"defaultHeaderCriteria": null,
"defaultDetailsItemCriteria": {
"totalPoints": 0,
"pointsBase": 1,
"eachY": 0,
"formulaBase": 0,
"detailField": 0,
"searchType": 0,
"searchPool": [
{ "id": 101, "description": "Item A", "keyId": "ART-001" },
{ "id": 102, "description": "Item B", "keyId": "ART-002" }
]
},
"defaultDetailsFamilyCriteria": null
}

Individual search (searchType: 1) — same structure; searchPool usually has a single item when the business rule is “a specific item”.

{
"order": 4,
"description": "2 points per euro on the line total (VAT) — single item",
"active": true,
"cumulative": false,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 1,
"defaultHeaderCriteria": null,
"defaultDetailsItemCriteria": {
"totalPoints": 0,
"pointsBase": 2,
"eachY": 0,
"formulaBase": 0,
"detailField": 2,
"searchType": 1,
"searchPool": [
{ "id": 200, "description": "Premium item", "keyId": "PREM-01" }
]
},
"defaultDetailsFamilyCriteria": null
}

Item detail with X per YformulaBase: 1 and eachY > 0.

{
"order": 5,
"description": "1 point for every 5 € of price with VAT on lines of listed items",
"active": true,
"cumulative": true,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 1,
"defaultHeaderCriteria": null,
"defaultDetailsItemCriteria": {
"totalPoints": 0,
"pointsBase": 1,
"eachY": 5,
"formulaBase": 1,
"detailField": 1,
"searchType": 0,
"searchPool": [
{ "id": 301, "description": "Cola soft drink 33cl", "keyId": "BEB-001" }
]
},
"defaultDetailsFamilyCriteria": null
}

Detail by Family (criteriaType: 2, defaultDetailsFamilyCriteria)

searchPool cannot be empty (PointsConfig.InvalidFamilySearchPool). Each element: id, description, idParent (ancestor in the family hierarchy).

{
"order": 6,
"description": "Points per quantity on lines of selected families",
"active": true,
"cumulative": true,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 2,
"defaultHeaderCriteria": null,
"defaultDetailsItemCriteria": null,
"defaultDetailsFamilyCriteria": {
"totalPoints": 0,
"pointsBase": 1,
"eachY": 0,
"formulaBase": 0,
"detailField": 0,
"searchType": 0,
"searchPool": [
{ "id": 10, "description": "Grocery", "idParent": 0 },
{ "id": 11, "description": "Beverages", "idParent": 10 }
]
}
}

Family with X per Y on line total without VAT (detailField: 4):

{
"order": 7,
"description": "3 points for every 2 € of line total without VAT (listed families)",
"active": false,
"cumulative": false,
"allowDecimalPoints": false,
"startDate": "2026-01-01T00:00:00",
"endDate": "2026-12-31T23:59:59",
"criteriaType": 2,
"defaultHeaderCriteria": null,
"defaultDetailsItemCriteria": null,
"defaultDetailsFamilyCriteria": {
"totalPoints": 0,
"pointsBase": 3,
"eachY": 2,
"formulaBase": 1,
"detailField": 4,
"searchType": 0,
"searchPool": [
{ "id": 20, "description": "Promotional bellflower", "idParent": 0 }
]
}
}

Replace id, keyId, idParent, and descriptions with valid values in your tenant.


Integration Notes

  • Use GET /gateway/points-config/next-order to fill order in new configurations.
  • On update, send id with the same Guid that identifies the record.
  • Keep one nested criterion consistent with criteriaType; avoid sending all three objects filled if the product expects exclusivity.
  • order >= 1 is recommended, consistent with [Range] in PointsConfigDTO and the value suggested by GET .../next-order.

Conclusion

Points configuration management exposes CRUD over /gateway/points-config with validations dependent on criteriaType, formulaBase, and date range. Test in staging combinations of header vs detail, list vs minimal set in searchPool, and XTimes vs XForY formulas before production.


Last updated: May 14, 2026