Skip to main content

Debit Agreement Guide

Routes:

  • Listing: GET /gateway/debit-agreement
  • Processing: POST /gateway/debit-agreement/save
  • Ignore: POST /gateway/debit-agreement/ignore

Authentication: Bearer token (JWT) and tenant context — see Combined Login

Overview

Debit Agreements is the operational step that follows the configuration of Covenant Agreement Models. After models are created and assigned to Entities, this module lets you:

  1. List all assignments due for processing on a given date
  2. Process selected agreements — generating the corresponding sales documents and advancing NextDate
  3. Ignore selected agreements — skipping the current occurrence and advancing NextDate without creating a document

The debit flow covers three operations: listing agreements due for processing, processing them to generate documents, and ignoring them to skip an occurrence.


Workflow


Step 1 — List Due Agreements

Retrieves all covenant agreement assignments whose NextDate falls on or before the specified processDate.

GET /gateway/debit-agreement?processDate={date}
Authorization: Bearer {token}

Parameters

ParameterTypeRequiredDescription
processDatedatetime✅ YesCut-off date. Only agreements with NextDate ≤ processDate are returned
customerInitialstringNoFilters agreements starting from the customer with this ID
customerFinalstringNoFilters agreements up to the customer with this ID
pageintNoPage of results to return. Defaults to 1
pageSizeintNoNumber of records per page

Example — All Agreements Due by End of Month

GET /gateway/debit-agreement?processDate=2026-01-31T23:59:59
Authorization: Bearer {token}

Example — With Entity Range and Pagination

GET /gateway/debit-agreement?processDate=2026-01-31T23:59:59&customerInitial=1&customerFinal=100&page=1&pageSize=50
Authorization: Bearer {token}

Response 200 OK

{
"totalCount": 3,
"pageSize": 50,
"currentPage": 1,
"totalPages": 1,
"data": [
{
"customerCovenantAgreementId": "a1b2c3d4-1111-2222-3333-aabbccddeeff",
"covenantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "Monthly IT Support",
"description": "Monthly technical support and maintenance contract",
"extraReference": null,
"extraReference2": null,
"entityKeyId": "1",
"entityName": "Acme Technologies, Ltd",
"documentSerieDescription": "FT 2026",
"documentTypeDescription": "Invoice",
"lastProcessDate": "2025-12-31T00:00:00",
"nextDate": "2026-01-31T00:00:00",
"documentNumber": "",
"totalAmount": null,
"finalDate": "2026-12-31T00:00:00"
},
{
"customerCovenantAgreementId": "b5c6d7e8-4444-5555-6666-112233445566",
"covenantId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"name": "Annual IT Maintenance Package",
"description": "Annual hardware and software maintenance package",
"extraReference": null,
"extraReference2": null,
"entityKeyId": "2",
"entityName": "TechVision Solutions",
"documentSerieDescription": "FT 2026",
"documentTypeDescription": "Invoice",
"lastProcessDate": "2025-01-31T00:00:00",
"nextDate": "2026-01-31T00:00:00",
"documentNumber": "",
"totalAmount": null,
"finalDate": null
}
]
}

Listing Fields

FieldDescription
customerCovenantAgreementIdUnique ID of the Entity-Covenant assignment — used in Save/Ignore calls
covenantIdID of the covenant agreement model
nameName of the covenant agreement model
descriptionDescription of the model
extraReference / extraReference2Optional extra references on the assignment
entityKeyIdEntity/Customer ID
entityNameEntity/Customer name
documentSerieDescriptionDocument series description
documentTypeDescriptionDocument type description
lastProcessDateLast date this assignment was processed or ignored
nextDateNext due date for processing
documentNumberPopulated after processing with the generated document number
totalAmountPopulated after processing with the document total
finalDateEnd date of the assignment (null = indefinite)

Step 2 — Process Agreements (Save)

Creates sales documents for the selected agreements and advances NextDate to the next scheduled occurrence.

POST /gateway/debit-agreement/save
Content-Type: application/json
Authorization: Bearer {token}
Idempotency-Key: 3fa85f64-5717-4562-b3fc-2c963f66afa6
Idempotency

Idempotency ensures that resending the same request does not generate duplicate documents. Include a unique GUID in the Idempotency-Key header on each operation.

Request Body

{
"processDate": "2026-01-31T00:00:00",
"documentDate": "2026-01-31T00:00:00",
"loadDate": "2026-01-31T00:00:00",
"customerCovenantAgreementIds": [
"a1b2c3d4-1111-2222-3333-aabbccddeeff",
"b5c6d7e8-4444-5555-6666-112233445566"
]
}

Request Fields

FieldTypeRequiredDescription
processDatedatetime✅ YesReference date for determining due agreements
documentDatedatetime✅ YesOfficial date to stamp on generated documents
loadDatedatetime✅ YesLoad/shipment date — must be ≥ documentDate
customerCovenantAgreementIdsstring[]✅ YesNon-empty list of unique CustomerCovenantAgreementId values from the listing

Response 200 OK

{
"successCount": 2,
"failureCount": 0,
"results": [
{
"customerCovenantAgreementId": "a1b2c3d4-1111-2222-3333-aabbccddeeff",
"success": true,
"newNextDate": "2026-02-28T00:00:00",
"lastProcessDate": "2026-01-31T00:00:00",
"documentNumber": "FT 2026/1",
"documentId": 10042,
"totalAmount": 184.50,
"errorMessage": null
},
{
"customerCovenantAgreementId": "b5c6d7e8-4444-5555-6666-112233445566",
"success": true,
"newNextDate": "2027-01-31T00:00:00",
"lastProcessDate": "2026-01-31T00:00:00",
"documentNumber": "FT 2026/2",
"documentId": 10043,
"totalAmount": 922.50,
"errorMessage": null
}
]
}

Partial Failure Example

If one agreement fails, the others still succeed. The failed entry has success: false and an errorMessage:

{
"successCount": 1,
"failureCount": 1,
"results": [
{
"customerCovenantAgreementId": "a1b2c3d4-1111-2222-3333-aabbccddeeff",
"success": true,
"newNextDate": "2026-02-28T00:00:00",
"lastProcessDate": "2026-01-31T00:00:00",
"documentNumber": "FT 2026/1",
"documentId": 10042,
"totalAmount": 184.50,
"errorMessage": null
},
{
"customerCovenantAgreementId": "b5c6d7e8-4444-5555-6666-112233445566",
"success": false,
"newNextDate": null,
"lastProcessDate": null,
"documentNumber": null,
"documentId": null,
"totalAmount": null,
"errorMessage": "CustomerCovenantAgreement not found."
}
]
}

Result Fields

FieldDescription
customerCovenantAgreementIdID of the processed assignment
successWhether this agreement was successfully processed
newNextDateNext due date after this processing cycle
lastProcessDateDate stamped as the last processing date
documentNumberGenerated document number (e.g., "FT 2026/1")
documentIdInternal ID of the generated document
totalAmountTotal amount of the generated document
errorMessageError details if success is false

Step 3 — Ignore Agreements (Skip)

Advances NextDate to the next scheduled occurrence without creating a document. Useful when a billing cycle needs to be skipped for a specific period.

POST /gateway/debit-agreement/ignore
Content-Type: application/json
Authorization: Bearer {token}
Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7
Idempotency

Include a unique GUID in the Idempotency-Key header to prevent the same occurrence from being skipped more than once.

Request Body

{
"processDate": "2026-01-31T00:00:00",
"customerCovenantAgreementIds": [
"c9d0e1f2-7777-8888-9999-aabbccddeeff"
]
}

Request Fields

FieldTypeRequiredDescription
processDatedatetime✅ YesReference date used to calculate the next due date
customerCovenantAgreementIdsstring[]✅ YesNon-empty list of unique CustomerCovenantAgreementId values

Response 200 OK

{
"successCount": 1,
"failureCount": 0,
"results": [
{
"customerCovenantAgreementId": "c9d0e1f2-7777-8888-9999-aabbccddeeff",
"success": true,
"newNextDate": "2026-02-28T00:00:00",
"lastProcessDate": "2026-01-31T00:00:00",
"errorMessage": null
}
]
}

Result Fields

FieldDescription
customerCovenantAgreementIdID of the ignored assignment
successWhether the ignore operation succeeded
newNextDateNext due date after skipping this occurrence
lastProcessDateDate stamped as the last processing date (even though no document was created)
errorMessageError details if success is false

NextDate Calculation

After each Save or Ignore, NextDate is automatically recalculated based on the agreement's periodicity configuration:

Periodicity TypeCalculation Logic
Daily (1)Advances to the next day whose weekday bit is set in periodicityValue (bitmask)
Weekly (2)Advances by periodicityValue × 7 days, aligned to initialDate
Monthly (3)Advances by periodicityValue months, aligned to the day of initialDate
Yearly (4)Advances by periodicityValue years
Monthly alignment

For monthly and weekly periodicities, NextDate is always aligned to the day of the original initialDate. For example, if initialDate is 2026-01-15 and periodicity is monthly, NextDate will always fall on the 15th of each month.

Daily Bitmask Reference

The same weekday bitmask used when creating covenant agreement models:

ValueDay
1Sunday
2Monday
4Tuesday
8Wednesday
16Thursday
32Friday
64Saturday

Example: Monday–Friday = 2+4+8+16+32 = 62


Validation Rules

Save Command

RuleDescription
processDate requiredCannot be empty or default
documentDate requiredCannot be empty or default
loadDate requiredCannot be empty or default
loadDate ≥ documentDateLoad date must be on or after document date
customerCovenantAgreementIds requiredMust have at least one ID
IDs not emptyEach ID in the list must be a non-empty string
IDs uniqueNo duplicate IDs in the same request

Ignore Command

RuleDescription
processDate requiredCannot be empty or default
customerCovenantAgreementIds requiredMust have at least one ID
IDs not emptyEach ID in the list must be a non-empty string
IDs uniqueNo duplicate IDs in the same request

Error Responses

Listing

HTTP CodeDescription
401Unauthorized — invalid or missing token
500Internal server error

Save / Ignore

HTTP CodeDescription
400Validation error — see validation rules above
401Unauthorized — invalid or missing token
404One or more CustomerCovenantAgreementId values not found
500Internal server error
Agreement-level vs Request-level errors

A 404 at the HTTP level means the entire request was rejected (e.g., none of the IDs were found or the request was malformed).
Individual agreement failures within a valid request are reported in results[].success = false with results[].errorMessage, while the HTTP response remains 200 OK.


Best Practices

  • Always call the listing endpoint first with the target processDate to identify what is due
  • Use customerInitial / customerFinal to process large volumes in smaller batches
  • Check results[].success per agreement — a 200 OK response does not guarantee all agreements were processed
  • Retry only the failed customerCovenantAgreementIds (those with success: false) to avoid duplicating already processed entries
  • Use idempotency keys when retrying to prevent duplicate document generation
  • Confirm loadDate ≥ documentDate before submitting the save command

❌ Avoid

  • Submitting all agreements in a single massive batch — prefer pagination or range-based batching
  • Assuming 200 OK means full success — always inspect failureCount and individual results
  • Sending duplicate customerCovenantAgreementIds in the same request (blocked by validation)
  • Using processDate beyond the agreement's finalDate — assignments past their end date will not appear in the listing

Common Scenarios

End-of-Month Processing

Process all agreements due by the last day of the month:

  1. List: GET /gateway/debit-agreement?processDate=2026-01-31T23:59:59
  2. Collect the customerCovenantAgreementId of all returned items
  3. Save: POST /gateway/debit-agreement/save with all collected IDs

Selective Processing with Exceptions

Process most agreements but skip a specific customer's agreement this month:

  1. List: Get all due agreements
  2. Separate: Identify IDs to skip (ignore) vs process (save)
  3. Ignore: POST /gateway/debit-agreement/ignore with the skip IDs
  4. Save: POST /gateway/debit-agreement/save with the remaining IDs

Large Volume — Batching by Entity Range

For tenants with thousands of agreements, process in ranges:

Batch 1: GET /gateway/debit-agreement?processDate=...&customerInitial=1&customerFinal=500
Batch 2: GET /gateway/debit-agreement?processDate=...&customerInitial=501&customerFinal=1000
Batch 3: ...

Integration with Covenant Agreement Models

The debit process reads the agreement's configuration at the time of processing:

  • documentType and documentSerie — determine which document type and series to use
  • periodicityType and periodicityValue — used to calculate the new NextDate
  • items — copied directly to the generated document lines
  • priceType, withTax, ignoreCustomerDiscount — applied during document pricing
Snapshot vs Live

The generated document captures the agreement's item prices and configuration at the moment of processing. Subsequent changes to the covenant agreement model do not retroactively affect already-processed documents.



Last Updated: June 2, 2026