> For the complete documentation index, see [llms.txt](https://docs.tendar.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tendar.co/documentation/recollection/recollection.md).

# Recollection

Record repayments against a loan — manually or through a payment provider.

When a borrower makes a payment toward their loan, you need a way to record that repayment, update the loan balance, and keep your repayment schedule in sync. That's what the Recollection API does. It sits between your application and Tendar's loan engine, handling the bookkeeping so you don't have to.

A recollection can be as simple as logging a cash payment your field agent received, or as automated as charging a customer's saved card and letting Tendar reconcile the repayment across outstanding installments. Either way, the outcome is the same: the loan balance goes down, the repayment schedule updates, and your system gets notified.

### The recollection object

***

When you create a recollection, Tendar returns an object with the following fields:

| Field             | Type      | Description                                                                                                            |
| ----------------- | --------- | ---------------------------------------------------------------------------------------------------------------------- |
| `id`              | string    | Internal Tendar ID for the recollection.                                                                               |
| `user`            | object    | The user who made the repayment. Populated from the loan.                                                              |
| `user_id`         | string    | The user's ID (e.g. `usr-cheltgfnqt`).                                                                                 |
| `loan`            | string    | The ID of the loan the repayment was applied to.                                                                       |
| `status`          | string    | One of `pending`, `success`, or `failed`.                                                                              |
| `amount`          | number    | The repayment amount. Defaults to the loan's remaining balance if not provided.                                        |
| `currency`        | string    | The currency of the recollection (e.g. `NGN`). Inherited from the loan.                                                |
| `payment_service` | string    | The payment provider used (e.g. `paystack`, `flutterwave`, `stripe`). Empty for manual recollections.                  |
| `payment_channel` | string    | The channel through which payment was made (e.g. `cash`, `checkout`, `card`, `direct_debit`).                          |
| `reference`       | string    | A unique reference for the recollection. Auto-generated (prefixed with `rec-`) if you do not provide one.              |
| `message`         | string    | A status message from the payment provider, or a custom message.                                                       |
| `with_provider`   | boolean   | Whether the recollection was routed through a payment provider.                                                        |
| `callback_url`    | string    | A URL Tendar will POST webhook events to for this specific recollection.                                               |
| `repaid_at`       | timestamp | When the repayment was made. You can set this for manual recollections; for provider-backed ones, it is set by Tendar. |
| `card`            | string    | The ID of the tokenized card used for the charge. Only present for `card` payment channel.                             |
| `direct_debit`    | string    | The ID of the direct debit authorization used. Only present for `direct_debit` payment channel.                        |
| `checkout`        | object    | Checkout session details, including the `url` to redirect the customer. Only present for `checkout` payment channel.   |
| `metadata`        | object    | A flexible key-value store for any custom data you want to attach.                                                     |
| `created_at`      | timestamp | When the recollection record was created.                                                                              |
| `updated_at`      | timestamp | When the recollection record was last updated.                                                                         |

### Before you begin

***

To use the Recollection API, you need:

1. **An active Tendar account** with a valid API key.
2. **A disbursed loan** — recollections can only be recorded against loans that have been disbursed and are not yet fully paid.
3. **(Optional) A saved payment method** — if you want Tendar to charge the customer automatically, the borrower needs a [tokenized card](/documentation/recollection/card.md) or an active [direct debit](/documentation/recollection/direct-debit.md) on file.

### Two ways to recollect

***

The Recollection API supports two distinct flows, controlled by the `with_provider` flag:

#### Manual recollection

Set `with_provider` to `false` when the payment has already been received outside of Tendar — cash, bank transfer, POS, or any other offline channel. Tendar won't attempt to move money; it will simply record the repayment, update the loan, and process the repayment schedule.

This is the most common flow for lending businesses that collect payments in person or through channels Tendar doesn't directly control.

```json
POST /api/v1/recollection/create

{
  "loan": "6685d6600defdf0d7eea6699",
  "amount": 3500,
  "payment_channel": "cash",
  "with_provider": false,
  "repaid_at": "2024-07-03T15:04:05Z",
  "metadata": {
    "collected_by": "agent-042"
  }
}
```

When the request succeeds, the recollection is created with a `success` status immediately. There is no pending state — the payment has already happened, so Tendar records it as complete.

```json
{
  "data": {
    "id": "6685da7174fd91511e0778c6",
    "user_id": "usr-cheltgfnqt",
    "loan": "6685d6600defdf0d7eea6699",
    "status": "success",
    "amount": 3500,
    "currency": "NGN",
    "payment_channel": "cash",
    "reference": "rec-clcuswkusv",
    "with_provider": false,
    "repaid_at": "2024-07-03T15:04:05Z",
    "metadata": {
      "collected_by": "agent-042"
    }
  },
  "error": false,
  "message": "Recollection created successfully"
}
```

#### Provider-backed recollection

Set `with_provider` to `true` when you want Tendar to charge the customer through a payment provider. In this flow, Tendar creates the recollection in a `pending` state, initiates the charge, and updates the status once the payment settles.

You have three `payment_channel` options:

| Channel        | What happens                                                                                                |
| -------------- | ----------------------------------------------------------------------------------------------------------- |
| `checkout`     | Tendar initializes a payment session and returns a checkout URL. Redirect the customer to complete payment. |
| `card`         | Tendar charges the customer's default (or specified) tokenized card immediately. No redirect needed.        |
| `direct_debit` | Tendar debits the customer's default (or specified) direct debit authorization. No redirect needed.         |

#### Charging via checkout

When using checkout, you must include the `checkout` object with a `success_url` (where the customer is sent after payment) and optionally a `cancel_url`.

```json
POST /api/v1/recollection/create

{
  "loan": "6685d6600defdf0d7eea6699",
  "amount": 3500,
  "with_provider": true,
  "payment_channel": "checkout",
  "checkout": {
    "success_url": "https://yourapp.com/payment/success",
    "cancel_url": "https://yourapp.com/payment/cancel"
  },
  "callback_url": "https://yourapp.com/webhooks/tendar"
}
```

The response will include a `checkout.url` — redirect your customer there to complete the payment.

#### Charging a saved card

If the borrower already has a tokenized card, you can charge it directly. Pass the card ID, or omit it to charge the customer's default card.

```json
POST /api/v1/recollection/create

{
  "loan": "6685d6600defdf0d7eea6699",
  "amount": 3500,
  "with_provider": true,
  "payment_channel": "card",
  "card": "66859a3ca53c1ca520a7b26d",
  "callback_url": "https://yourapp.com/webhooks/tendar"
}
```

#### Charging via direct debit

Same idea as card, but pulls from the customer's bank account. Pass the direct debit ID, or omit it to use the default.

```json
POST /api/v1/recollection/create

{
  "loan": "6685d6600defdf0d7eea6699",
  "amount": 3500,
  "with_provider": true,
  "payment_channel": "direct_debit",
  "callback_url": "https://yourapp.com/webhooks/tendar"
}
```

### What happens behind the scenes

***

When a recollection is created, Tendar doesn't just record a number. It runs through a series of steps to keep your loan data consistent:

1. **Validates the loan** — confirms the loan exists, has been disbursed, and is not already fully paid.
2. **Processes repayments** — walks through the borrower's unpaid repayment schedule (sorted by due date) and applies the payment amount across installments, oldest first. Partial payments are supported — if the amount doesn't cover a full installment, the remaining balance on that installment is updated accordingly.
3. **Updates the loan** — adjusts `amount_paid`, `amount_remaining_to_pay`, `last_pay_date`, and `next_pay_date` on the loan record. If the entire balance has been covered, the loan is marked as `paid`.
4. **Creates a transaction** — logs a transaction record for audit and reporting purposes.
5. **Updates credit score** — publishes an event to the credit score service so the borrower's repayment behavior is reflected in their score.
6. **Sends webhooks** — fires a `recollection.success` (or `recollection.failed`) event to your company webhook URL and, if provided, to the `callback_url` on the recollection itself.

All of this happens atomically for the loan — Tendar uses distributed locking to ensure that concurrent recollection requests against the same loan are processed one at a time.

### Handling the amount

***

The `amount` field is optional. If you omit it, Tendar defaults to the full remaining balance on the loan (`amount_remaining_to_pay`). If you provide an amount that exceeds the remaining balance, Tendar will cap the repayment at what is owed — you won't accidentally overpay a loan.

Partial payments are fully supported. If a borrower pays ₦3,500 on a loan with four monthly installments of ₦3,500 each, Tendar marks the first installment as paid and moves the `next_pay_date` forward.

### Using references

***

Every recollection gets a unique `reference` (e.g., `rec-clcuswkusv`). You can provide your own reference or let Tendar generate one. If you provide a reference that already exists, the request will be rejected — this prevents duplicate recollections.

References are useful for idempotency. If your network drops after sending a recollection request, you can safely retry with the same reference and Tendar will tell you it already exists rather than creating a duplicate.

### Listening for webhooks

***

For provider-backed recollections (especially checkout), the payment may not settle immediately. When it does, Tendar sends a webhook event to your registered URL:

| Event                  | When it fires                                                 |
| ---------------------- | ------------------------------------------------------------- |
| `recollection.success` | The payment settled and the loan has been updated.            |
| `recollection.failed`  | The payment failed (declined card, insufficient funds, etc.). |

The webhook payload includes the full recollection object, so you can update your UI or trigger downstream processes without making additional API calls.

If you set a `callback_url` on the recollection, Tendar will also send the event there — useful if different loans route to different systems.

### Fetching recollections

***

You can retrieve recollections at any time to check their status, display repayment history, or reconcile your records.

**Fetch by ID:**

```
GET /api/v1/recollection/fetch/:id
```

**Fetch by reference:**

```
GET /api/v1/recollection/fetch/reference/:ref
```

When fetching by reference, the response includes the full loan object populated inline, giving you a snapshot of the loan state alongside the recollection details.

**List all recollections:**

```
GET /api/v1/recollection/list?page=1&limit=20
```

The list endpoint supports pagination, sorting, and filtering. You can filter by `user_id`, `loan`, or `date-created_at`, and sort by `created_at` or `updated_at`.

### Recollection statuses

***

| Status    | Meaning                                                                                                                |
| --------- | ---------------------------------------------------------------------------------------------------------------------- |
| `pending` | The recollection has been created but the payment is not yet confirmed. Only applies to provider-backed recollections. |
| `success` | The payment has been confirmed and the loan has been updated.                                                          |
| `failed`  | The payment attempt failed. The loan balance is unchanged.                                                             |

### Automated recollection

***

If a borrower has a **default card** or **default direct debit** saved on the platform, Tendar can automatically charge the borrower when a repayment is due — no API call required on your end.

Here's how it works:

1. A loan is disbursed and has an active repayment schedule.
2. When an installment's due date arrives, Tendar checks whether the borrower has a default card or default direct debit on file.
3. If a saved payment method exists, Tendar automatically initiates a provider-backed recollection for the installment amount.
4. On success, the loan balance is updated and a `recollection.success` webhook is sent. On failure, a `recollection.failed` webhook is sent so you can notify the borrower or trigger a retry.

You don't need to build a cron job or scheduler — Tendar handles the timing and execution. All you need to do is make sure your borrowers have a [tokenized card](/documentation/recollection/card.md) or an active [direct debit](/documentation/recollection/direct-debit.md) authorization before the first repayment is due.

> **Note:** Automated recollections follow the same behind-the-scenes steps as any other recollection — repayment schedule updates, loan balance adjustments, transaction logging, credit score updates, and webhook delivery all happen automatically.

### Charges and billing

***

Recollection charges depend on how the repayment is recorded:

| Scenario                                        | Charge item                 | Details                                                                                                                                                                                |
| ----------------------------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Manual recollection**                         | No charge                   | You are simply recording a payment that already happened. Tendar does not move money or charge a fee.                                                                                  |
| **Provider-backed recollection (you initiate)** | No platform charge          | When you call the API with `with_provider: true`, Tendar does not charge your wallet. The payment provider may charge transaction fees according to their own pricing.                 |
| **Automated card recollection**                 | `recollection.card`         | When Tendar automatically charges a borrower's default card on a due date, a platform fee is deducted from your Tendar wallet.                                                         |
| **Automated direct debit recollection**         | `recollection.direct_debit` | When Tendar automatically debits a borrower's default bank account on a due date, a platform fee is deducted from your Tendar wallet.                                                  |
| **Collect**                                     | `recollection.collect`      | If you use the [Collect](/documentation/recollection/collect.md) feature to automate installment-based collections via mandates, each collection is billed under its own pricing item. |
| **Failed charge**                               | No charge                   | If a card or direct debit charge fails (declined, insufficient funds, etc.), no platform fee is applied.                                                                               |

The charge amount for automated recollections depends on your subscription plan. Tendar checks your wallet balance before processing the charge — if your wallet does not have enough funds, the automated recollection fails. Make sure to keep your wallet topped up, especially if you have many loans with upcoming due dates.

The charge is finalized after the recollection completes successfully. If the charge fails for any reason, the fee is not applied.

### Error handling

Here are the most common errors you might encounter when creating a recollection, and what to do about them:

| Error                               | HTTP status | Cause                                                                               | Resolution                                                                                                                   |
| ----------------------------------- | ----------- | ----------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `loan not found`                    | 404         | The loan ID does not exist or does not belong to your company.                      | Verify the loan ID and ensure it was created under the correct company.                                                      |
| `loan already been paid completely` | 400         | The loan has already been fully repaid.                                             | Check the loan's `paid` status. No further recollections are needed.                                                         |
| `loan has not been disbursed`       | 400         | The loan exists but has not been disbursed yet.                                     | Disburse the loan first through the [Disbursement Service](/documentation/disbursement/disbursement.md) before recollecting. |
| `reference already exists`          | 400         | A recollection with this reference already exists.                                  | Use a different reference, or omit it to let Tendar auto-generate one.                                                       |
| `invalid payment channel provided`  | 400         | The `payment_channel` is not one of `checkout`, `card`, or `direct_debit`.          | Use a supported payment channel value.                                                                                       |
| `checkout details required`         | 400         | `payment_channel` is `checkout` but no `checkout` object was provided.              | Include a `checkout` object with at least a `success_url`.                                                                   |
| `amount mismatch`                   | 400         | During verification, the payment amount does not match the recollection amount.     | Ensure the payment provider charge matches the recollection amount exactly.                                                  |
| `currency mismatch`                 | 400         | During verification, the payment currency does not match the recollection currency. | Ensure the payment currency matches the loan's currency.                                                                     |
| `payment is still pending`          | 400         | The payment has not settled yet when verification is attempted.                     | Wait for the payment to settle before retrying verification, or listen for the webhook event.                                |
| Insufficient wallet balance         | 400         | Your Tendar wallet does not have enough funds to cover the recollection charge.     | Top up your wallet from the Tendar dashboard.                                                                                |

### Putting it all together

***

Here's a typical integration flow for a lending application:

1. **Disburse a loan** through the Disbursement Service.
2. **Tokenize the borrower's card** using the [Card API](/documentation/recollection/card.md), or set up a [Direct Debit](/documentation/recollection/direct-debit.md) authorization.
3. **On each due date**, call `POST /recollection/create` with `with_provider: true` and `payment_channel: "card"` to automatically charge the borrower.
4. **Listen for webhooks** — on `recollection.success`, update your dashboard. On `recollection.failed`, trigger a retry or notify the borrower.
5. **For offline payments**, call `POST /recollection/create` with `with_provider: false` and the appropriate `payment_channel` (cash, transfer, etc.) to keep the loan balance accurate.
6. **Fetch the loan** at any time to see the up-to-date balance, next payment date, and full repayment history.

### Next steps

***

* [Card Tokenization](/documentation/recollection/card.md) — Save a customer's card for automated charges.
* [Direct Debit](/documentation/recollection/direct-debit.md) — Set up bank account authorizations.
* [Accept Payments](/documentation/recollection/payments.md) — Initialize standalone payment sessions.
* [Collect](/documentation/recollection/collect.md) — Automate installment-based collections with mandates.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.tendar.co/documentation/recollection/recollection.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
