Debt Management
Feature used to ensure balances are positive
A debt is created as soon as the authorization balance goes negative. As a consequence, debts can only be created on offline transaction and P2P.
It is important to note that the debt carries two concepts:
- The creation of an internal transfert completed to cover the balance shortfall
- The notion of debt owed by the end user to the partner, with its own status.
Attibute definition
The DebtCreatedOrUpdated callback is received in 2 cases:
- a debt was created
- an existing debt changed
The remainingAmount or/and the recoveryStatus changed.
The internalDebtTransfer is dedicated to the internal transfer created from the P&L account to the enduser's account to cover the balance shortfall.
Debt status
stateDiagram [*] --> InProgress InProgress --> ClosedWithRecovery InProgress --> ClosedWithoutRecovery ClosedWithRecovery --> [*] ClosedWithoutRecovery --> [*]
Debt operation in the webdesk
A line labeled "Debt" is created when the debt is initiated. This line simultaneously represents the InternalDebtTransfer and the current status of the debt.
The operation status is "Completed" even if the debt status (visible in the Webdesk) initially shows as "In Progress."
Debt creation use cases
Internal transfer
When the processUnpaid attribute is set to true, if the amount of the internal transfer exceeds the account balance, a debt is created.
Example:
sequenceDiagram
autoNumber
Participant Partner
Participant XPO
Note over Partner, XPO: Accounting balance 20€ <br/> Authorisation balance 20€ <br/> Total debt: 0€
Partner ->> XPO: POST /api/v2.0/internal-transfers <br/> {amount: 30€, processUnpaid = true}
XPO ->> Partner: HTTP/200
XPO -->> Partner: Callback InternalTransfer
Note over Partner, XPO: The authorization balance can NOT be negative.<br/> A debt is created, with <br/> debt amount = inital P2P amount - authorisation balance
XPO ->> XPO: Internal debt transfer <br/> {accountId:partner's profit&loss account, <br/>recipient: user, <br/>amount: 10€}
XPO -->> Partner: Callback InternalDebtTransferCreated
XPO ->> XPO: Debt Creation
XPO -->> Partner: Callback DebtCreatedOrUpdated
Note over Partner, XPO: Accounting balance 0€ <br/> Authorisation balance 0€ <br/> Total debt: 10€
Offline card operations
sequenceDiagram
autoNumber
Participant Merchant
Actor User
Participant Partner
Participant XPO
Note over Merchant, XPO: Accounting balance 20€ <br/> Authorisation balance 20€ <br/> Total debt: 0€
User ->> Merchant : Offline Transaction 30€
break wainting for the clearing
Merchant-->>XPO: Clearing
end
XPO -->> Partner: Callback CardOperationCreatedOrUpdated
Note over Partner, XPO: The authorization balance can NOT be negative. <br/> A debt is created, with <br/> debt amount = clearing amount - authorisation balance
XPO ->> XPO: Internal debt transfer <br/> {accountId:partner's profit&loss account, <br/>recipient: user, <br/>amount: 10€}
XPO -->> Partner: Callback InternalDebtTransferCreated
XPO ->> XPO: Debt Creation
XPO -->> Partner: Callback DebtCreatedOrUpdated
Note over Partner, XPO: Accounting balance 0€ <br/> Authorisation balance 0€ <br/> Total debt: 10€
Note about offline operation (refer to the dedicated topic for more details)
Card X0X
X0X cards have almost systematic authorisation. Exceptions are made in certain cases:
- parking
- toll
- aircraft
In these cases, if the Payment Temrinal does not request authorisation, the transactions will still be accepted.
Card X2X
X2X cards are systematic authorisation cards. This information is written directly onto the chip. It will therefore be impossible to make payments on tpe that do not require authorisation.
Forced operation on the TPE
Despite this feature of the chip, there are POS terminals that allow you to force the operation offline.In this case, no preventive action is possible on the Xpollens side: the transaction is carried out, the compensation is received and deducted from the enduser's account.
R-transactions
Recall SDD OUT during the first 8 weeks afer the payment date
If an SDD credited to the Xpollens account is recalled by the debtor bank within 8 weeks, Xpollens is obliged to return the funds regardless of the account balance. This can therefore create a debt.
Debt recovery
The management of debt collection is entirely up to you.You can debit the account, adjust the remaining balance, or update the debt status as needed.
Xpollens does not take any action.
It is important to note that debts must be closed transaction by transaction (debt by debt).
Debt recovery: as soon as the account balance is positive, recovered with fund recovery
Here is a proposed debt recovering sequence:
- As soon as funds are deposited into the account
- Review the outstanding debts
- Recover as much as possible while there are funds available
sequenceDiagram
autoNumber
Actor User
Participant Partner
Participant XPO
Note over User, XPO: Accounting balance 0€ <br/> Authorisation balance 0€ <br/> Total debt: X€
User ->> XPO : bank account loading (topup, sct in, ip in, ...)
XPO -->> Partner: Callback associated to the transaction type
Partner ->> Partner: existing open debts ?<br/> (internal request in your backend)
alt Level 1: If existing open debt(s)
Partner ->> XPO : GET /api/v3.0/debts {userId}
XPO -->> Partner: list debt amounts {remainingAmount, recoveryStatus}
alt Level 2: as long as sum open debt amounts != 0€ & user balance > 0€
loop Level 3: Recover the funds & close the debt.
Partner ->> XPO: POST /api/v2.0/internal-transfers <br/>{accountId: userId, recipient: partner's P&L account, amount = Y}
XPO -->> Partner: Callback InternalTransfer
Partner ->> XPO: PATCH /api/v3.0/debts/{debtId} <br/> {remainingAmount:0, status: ClosedWithRecovery}
XPO -->> Partner: Callback DebtCreatedOrUpdated
end
else Level 2: when sum open debt amounts = 0€ or user balance = 0€, stop the loop
else Level 1: No open debt
end
end
The debt must be recorded in the partner's accounts.
Transaction IN to monitor to recover debt
- Top-up card
- SCT IN & IP IN
- SCT OUT cancellation
- Refund SCT OUT & IP OUT
- SDD OUT
- SDD IN refund
- SDD OUT cancellation
- Card operation IN
- Card authorisation expiration
Debt recovery: recovey without fund recovery
You can decide to close the debt without recovering the funds. The losses will then be your responsibility.
sequenceDiagram
autoNumber
Actor User
Participant Partner
Participant XPO
Note over User, XPO: Accounting balance 0€ <br/> Authorisation balance 0€ <br/> Total debt: X€
Partner ->> XPO : GET /api/v3.0/debts/{debtId}
XPO -->> Partner: debt {remainingAmount, recoveryStatus}
Partner ->> XPO: PATCH /api/v3.0/debts/{debtId} <br/> {remainingAmount:X, status: ClosedWithoutRecovery}
XPO -->> Partner: Callback DebtCreatedOrUpdated
Note over User, XPO: loop if you want to close more than 1 debt without recovery
Technical information
Internal Debt transfer
The payload is essentially the same as for internal transfer.
About the callback : 🔗InternalDebtTransferCreated
Debt
- Get a debt by a debt public Id :🔗Debt
- Get a partial list of debts :🔗Debt list
- Modify a debt : 🔗Modify a debt
Best pratice: how to display debt in your app
Display a debt balance in addition to the account balance
sequenceDiagram
autoNumber
Actor User
Participant Partner
Participant XPO
Note over User, XPO: Accounting balance 0€ <br/> Authorisation balance 0€ <br/> debt Balance: X€
User ->> Partner : display account balance
Partner ->> XPO : GET /api/v2.0/accounts/{accountId}
XPO ->> Partner : {availableBalance= 0€}
Partner ->> Partner: existing debt? Yes
Partner ->> XPO : GET /api/v3.0/accounts/{accountId}/debt-balance
XPO -->> Partner: value (X)
Partner ->> User: display 2 balances separately: account balance & debt balance
Debt displayed on account statements
The amount of the debt is not shown on the account statement.
The InternalDebtTransfer as the InternalTransfer are marked "Paiement" in the bank statement.
How to test
Create a debt with a P2P - example Account management fees
1- GET /api/v3.0/accounts/accountId
{
[...]
"authorizationBalance": "authorizationBalance",
[...]
}
2- Create a P2P that respects the limits, with an amount greater than the balance
POST /api/v2.0/internal-transfers
"Payload": {
"internalTransferId": "ExternalP2PRef",
"accountId": {{accountId}},
"amount": {
"value": authorizationBalance+1,
"currency": "EUR"
},
"recipient": {
"accountId": "Profit_and_lost_accountId"
},
"extraDatas": {
"description": "Custom description",
"label1": "Label",
"label2": "SubLabel",
"label3": "Tag"
},
"processUnpaid": true,
}3- You receive the callback
{
"type": "DebtCreatedOrUpdated",
"data": {
"debtId": debtId,
"originTransactionId": "ExternalP2PRef",
"accountId": {{accountId}},
"accountHolderId": {appuserId},
"creationDate": "YYYY-MM-DDTHH:MM:SS.000Z",
"amount": {
"value": "1.00",
"currency": "EUR"
},
"remainingAmount": {
"value": "1.00",
"currency": "EUR"
},
"recoveryStatus": "InProgress"
}
}Create a debt with an offline operation
1- GET /api/v3.0/accounts/accountId
{
[...]
"authorizationBalance": "authorizationBalance",
[...]
}
2- Create an offline operation that respects the limits, with an amount greater than the balance POST /v2.0/card-operations/simulate-offline-settlement
{
"cardId": {{cardId}},
"amount": {
"value": authorizationBalance+1,
"currency": "EUR"
},
"operationDate": "2024-07-02T07:23:36.915Z",
"direction": "Debit", // Debit Credit
"merchantName": "Discraft Disc",
"merchantCategoryCode": "5941"
}3- You receive the callback
{
"type": "DebtCreatedOrUpdated",
"data": {
"debtId": debtId,
"originTransactionId": "x",
"accountId": {{accountId}},
"accountHolderId": {{appuserId},
"creationDate": "YYYY-MM-DDTHH:MM:SS.000Z",
"amount": {
"value": "1.00",
"currency": "EUR"
},
"remainingAmount": {
"value": "1.00",
"currency": "EUR"
},
"recoveryStatus": "InProgress"
}
}FAQ
Updated 4 months ago