Skip to main content

Act on Performance Transactions

If you have Performance Dreams enabled, settling a transaction means that you should also update the corresponding account's balances, such as currentValue. In order to minimize the risk of an End User seeing an inconsistent state between settled transactions and their account balance, this can be done atomically in a single request.

Instead of sending a PATCH request to the /transactions/{id} endpoint (see Act on SharedSavings Transactions), you can update both accounts and transactions simultaneously by using PATCH /users/{id}.

sequenceDiagram participant des as DES Backend participant bbe as Bank Backend opt Webhook registered des -->> bbe: POST /webhooks/transactions end bbe ->>+ des: GET /transactions?state=requested des -->>- bbe: List of transactions bbe ->> bbe: Settle or Fail each transaction async bbe ->> des: PATCH /users/{id} des -->> bbe: 200 OK

Here's an example of requested Deposit transaction in JSON format:

{
"type": "Deposit",
"id": <transactionId>,
"externalId": null,
"user": {
"type": "User",
"id": <userId>,
"externalId": <your user id>
}
"amountCents": 12300,
"toAccount": {
"type": "SharedSavings",
"id": <accountId>,
"externalId": <your account id>
}
"toDream": {
"type": "SavingsDream",
"id": <dreamId>
}
"state": "requested"
"requestedAt": 2023-03-27T16:41:00Z,
"settledAt": null,
"failedAt": null,
"errors": []
}

Most fields can normally be ignored though. The fields of interest in order to act on a Deposit to a Performance account are:

{
"type": "Deposit",
"id": <transactionId>,
"user": {
"externalId": <your user id>
},
"toAccount": {
"type": "Performance",
"externalId": <your account id>
}
"amountCents": 12300,
}

This tells you that this particular user (with your externalId) has the intent to Deposit the amount amountCents from their current account to the Performance account (with your externalId).

Withdrawals are exactly analogous to Deposits, with the only difference that the type is "Withdrawal" and toAccount is replaced with fromAccount.

Internal transaction between Dreams has both a toAccount and a fromAccount.

Settling a Transaction

In order to settle a transaction, update the transaction's settledAt timestamp as well as the affected Account(s)' balance(s).

PATCH /user/{id}
{
"accounts": [
{
"id": <accountId>
"balanceCents": 712345,
"liquidCents": 12300,
"performanceCents": 100045,
"performancePercent": 16.67,
"valuationFrom": 2022-12-31T23:55:34Z,
"valuationAt": 2023-03-27T17:30:10Z
}
],
"transactions": [
"id": <transactionId>
"settledAt": <DateTime>
]
}

See the Impact Finance API specification for a detailed description of the Performance account fields and their semantics.

NOTE 1: You can also use this method to settle or fail multiple transaction at the same time, e.g. if you are processing them in batches.

NOTE 2: In case of an Internal transaction between two Performance Dreams, this endpoint allows updating both affected account balances atomically.

Failing a Transaction

In order to fail a transaction, you just have to set the failedAt timestamp on the current account:

PATCH /user/{id}
{
"transactions": [
"id": <transactionId>,
"failedAt": <DateTime>,
]
}