> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tesouro.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment records

> Learn how to track and keep a history of payments.

## Overview

Payment records are a way to track the payment history of [payables](/finops/support/glossary#payable) (bills) and [accounts receivable invoices](/finops/guides/accounts-receivable/invoices/index). The `/payment-records` endpoint allows you to take note of every payment made towards a payable or an invoice.

If you use Tesouro payment rails together with account payables or accounts receivable, Tesouro automatically stores all payment information for payables and receivable invoices. However, when using external payment rails, you must manually create records for each payment instance - full or partial - made towards invoices.

## Roles and permissions

To use the `/payment-records*` endpoints with an [organization user token](/finops/guides/organizations/users#get-organization-user-token), this organization user must have a [role](/finops/guides/organizations/users#create-role) with the `payment_record` permission.

If using a [partner-level token](/finops/guides/authentication/client-credentials), no special permissions are needed.

## Payment record types

There are two types of payment records:

* **Tesouro-created payment records** -
  These are created automatically for all payments made via the [Tesouro payment links](/finops/guides/payments/payment-links).
  Each payment intent gets an associated payment record that is used to reconciliate this payment with the related payable or receivable invoice.

  Tesouro-created payment records have the `is_external` field set to `false`.
  These payment records can only be retrieved, but not modified directly by users.

* [**External payment records**](#external) - can be created and updated by the organization.
  These are intended for organizations that use their own payment rails, and are meant to record information about full or partial payments made via external channels.

  External payment records can have different [statuses](#statuses) to mirror the payment procesing status from external systems.
  They can also store information about future [scheduled payments](#scheduled).

Organizations that use Tesouro payment rails can also create external payment records to reflect payments made outside the Tesouro platform.

## Get all payment records

To get a list of all payment records, call [`GET /payment-records`](/finops/reference/openapi/payment-records/get-payment-records):

```sh lines theme={null}
curl -X GET 'https://api.sandbox.tesouro.com/v1/payment-records' \
     -H 'X-Finops-Version: 2025-06-23' \
     -H 'X-Organization-Id: ORGANIZATION_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN'
```

The successful request returns a paginated history of all payment records—both Tesouro-created and external.

To get only Tesouro-created or only external payment records, use the `is_external` query parameter.
For example, the following snippet returns only payment records created using Tesouro payment rails:

```sh lines theme={null}
curl -X GET 'https://api.sandbox.tesouro.com/v1/payment-records?is_external=false' \
     -H 'X-Finops-Version: 2025-06-23' \
     -H 'X-Organization-Id: ORGANIZATION_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN'
```

You can [sort and filter](/finops/api/concepts/pagination-sorting-filtering#sorting) the results of this request by invoice type (payable or receivable), payment record status, and other parameters.
For the full list of available sort and filter parameters, see the description of the [`GET /payment-records`](/finops/reference/openapi/payment-records/get-payment-records) endpoint.

## Get payment records for an invoice

To find all payment records associated with a specific payable or receivable invoice, call [`GET /payment-records`](/finops/reference/openapi/payment-records/get-payment-records) and specify the invoice ID in the `object_id` query parameter:

```sh lines theme={null}
curl -X GET 'https://api.sandbox.tesouro.com/v1/payment-records?object_id=1877d46f-2f16-484d-a44a-b537b30c2f34' \
     -H 'X-Finops-Version: 2025-06-23' \
     -H 'X-Organization-Id: ORGANIZATION_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN'
```

## External payment records

### Payment record statuses

External payment records are allocated with a status that indicates their progress in the external payment system.

```mermaid expandable lines theme={null}
stateDiagram
    classDef block fill: white, text-transform: lowercase
    %% classDef start color: blue, stroke: blue
    classDef start stroke: black
    classDef success color: green, stroke: green
    classDef failure color: red, stroke: red

    direction LR
    [*] --> succeeded
    [*] --> created
    [*] --> processing
    created --> succeeded
    created --> processing
    processing --> succeeded
    created --> canceled
    processing --> canceled

    class created, processing start
    class succeeded success
    class canceled failure
    class created, processing, succeeded, canceled block
```

#### `created`

This is the status for draft payment records that are created manually.
The payment record exists and is linked to an invoice but has not been applied yet, so it does not affect the invoice’s status or amount due.
Payment records in the `created` status can be fully edited.

#### `processing`

This status is used for payments that are being processed by the bank or financial institution.
To move the payment record to this status, call [`POST /payment-records/{payment_record_id}/start-processing`](/finops/reference/openapi/payment-records/post-payment-records-id-start-processing).

Payment records in the `processing` status cannot be modified but is still not applied to the invoice.
You must manually move it to `succeeded` or `canceled` status once the external payment completes.

#### `succeeded`

This is a final status that indicates successful payments and sucessful refunds.
To move a payment record to this status, call [`POST /payment-records/{payment_record_id}/mark-as-succeeded`](/finops/reference/openapi/payment-records/post-payment-records-id-mark-as-succeeded) passing the `paid_at` field in the body request.

Succeeded payment records modify the amount due and status of the linked invoice:

* Records with a positive amount increase the invoice's `amount_paid` and reduce the `amount_due`.
* Records with a negative amount (that is, refunds) reduce the invoice's `amount_paid` and increase the `amount_due`.

#### `canceled`

Payment records in the `created` and `processing` statuses can be canceled.
Once canceled, the payment record will not be applied to the invoice and cannot be modified further.
This is a final status.

### Create a payment record

To create a payment record for a payable or receivable invoice, call [`POST /payment-records`](/finops/reference/openapi/payment-records/post-payment-records) with the following request fields:

* `object.type` - the invoice type (`payable` or `receivable`) for which the payment was made.
* `object.id` - ID of the payable or receivable invoice.
* `amount` and `currency` - use a positive `amount` value for payments made toward the invoice, and negative values for refunds.
* For records in the `created` status that indicate future [scheduled payments](#scheduled):
  * `planned_payment_date` - scheduled date for a future payment, required when the payment is planned but not yet executed.
* For records in the `succeeded` status:
  * `paid_at` - date and time when the payment was made.
* `payment_intent_id` - the external payment reference number or transaction ID for the payment.
  Required for records in the `processing` and `succeeded` statuses.
  Currently `payment_intent_id` must be a UUID, you can use a random UUID.

Additional optional fields:

* `status` - the [status](#statuses) of the payment record.
  You can create records in the `created`, `processing`, or `succeeded` status.
  If omitted, defaults to `succeeded`.
* `payment_intent_status` - the status of the corresponding payment or payment intent in the partner's payment rails. A user-defined string.
* `payment_method` - payment method used or planned for the transaction. A user-defined string.

```sh expandable lines theme={null}
curl -X POST 'https://api.sandbox.tesouro.com/v1/payment-records' \
     -H 'X-Finops-Version: 2025-06-23' \
     -H 'X-Organization-Id: ORGANIZATION_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN' \
     -H 'Content-Type: application/json' \
     -d '{
       "object": {
         "type": "receivable",
         "id": "1877d46f-2f16-484d-a44a-b537b30c2f34"
       },
       "amount": 500,
       "currency": "USD",
       "status": "succeeded",
       "paid_at": "2025-08-12T07:30:00Z",
       "payment_intent_id": "a7964c0a-cee6-4c2f-9dd3-bdc8f09eeffa"
     }'
```

The response also contains a unique `id` assigned to this payment record.
Tesouro automatically updates the `status` of the specified invoice to reflect the payment made and returns the old and new statuses in the response:

```json {16-17} expandable lines theme={null}
{
  "id": "7d3e16c4a133-b2ed-17b8-4462-2724e6bf",
  "amount": 500,
  "currency": "USD",
  "entity_user_id": "c8192600-d792-4f2d-aaf8-cdd123563619",
  "history": [
    {
      "entity_user_id": "c8192600-d792-4f2d-aaf8-cdd123563619",
      "status": "succeeded",
      "timestamp": "2025-08-12T08:57:45.722038+00:00"
    }
  ],
  "is_external": true,
  "object": {
    "id": "1877d46f-2f16-484d-a44a-b537b30c2f34",
    "new_status": "paid",
    "old_status": "issued",
    "type": "receivable"
  },
  "overpaid_amount": 0,
  "paid_at": "2025-08-12T07:30:00Z",
  "payment_intent_id": "a7964c0a-cee6-4c2f-9dd3-bdc8f09eeffa",
  "payment_intent_status": null,
  "payment_method": null,
  "planned_payment_date": null,
  "status": "succeeded"
}
```

### Update or cancel a payment record

External payment records in the `created` status can be manually canceled or updated:

* To update a payment record, call [`PATCH /payment-records/{payment_record_id}`](/finops/reference/openapi/payment-records/patch-payment-records-id).
* To cancel a payment record in the `created` or `processing` statuses, call [`POST /payment-records/{payment_record_id}/cancel`](/finops/reference/openapi/payment-records/post-payment-records-id-cancel).
  Succeeded payment records cannot be canceled.

### Refunds

If a succeeded payment record has been refunded, you can record the refund by [creating a new payment record](#create) with a negative value in the `amount` field.
This reduces the invoice's `amount_paid`, increase the `amount_due`, and also updates the invoice's `status` if needed.

## Scheduled payment records

Scheduled external payment records represent invoice payments that are planned but not yet made.
The payment can be full or partial.

Tesouro does not trigger payments based on scheduled payment records.
The payment is supposed to be made by the organization itself via their preferred channel.
The purpose of scheduled payment records is to record the fact that the payment is planned, and to mirror the payment status from the external system so that Tesouro can reconciliate the external payment with the associated invoice.

### Create a scheduled payment

To create a schedule payment, call [`POST /payment-records`](/finops/reference/openapi/payment-records/post-payment-records) and provide the following fields in addition to the required ones:

* `status` - set to `created`,
* `planned_payment_date` - use the `YYYY-MM-DD` format,
* `payment_method` - (optional) a user-defined identifier of the payment method that will be used, for example, `bank_transfer`, `card`, or `cash`.

```sh {13-14} expandable lines theme={null}
curl -X POST 'https://api.sandbox.tesouro.com/v1/payment-records' \
     -H 'X-Finops-Version: 2025-06-23' \
     -H 'X-Organization-Id: ORGANIZATION_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN' \
     -H 'Content-Type: application/json' \
     -d '{
       "object": {
         "type": "payable",
         "id": "41b3d21c-d113-4ca7-8be0-698da4b409fe"
       },
       "amount": 50000,
       "currency": "USD",
       "status": "created",
       "planned_payment_date": "2025-08-15",
       "payment_method": "bank_transfer"
     }'
```

The created payment record has the [`created`](#created) status and will not affect the invoice's status or amounts until it's marked as succeeded.

### Update scheduled payment details

While a scheduled payment record is still in the `created` status and has not started processing, you can update its details in Tesouro: `amount`, `planned_payment_date`, `payment_method`, and other fields.
To update the scheduled payment details, call [`PATCH /payment-records/{payment_record_id}`](/finops/reference/openapi/payment-records/patch-payment-records-id).

### Start processing a scheduled payment

When a scheduled payment begins processing in your external system, call [`POST /payment-records/{payment_record_id}/start-processing`](/finops/reference/openapi/payment-records/post-payment-records-id-start-processing) to move the corresponding payment record to the `processing` status.
In the request body, you can optionally provide the `payment_intent_status` field containing the payment status in the external system (as an arbitrary user-defined string):

```sh lines theme={null}
curl -X POST 'https://api.sandbox.tesouro.com/v1/payment-records/60b58b07-e29d-43fd-822f-f6474820f8b2/start-processing' \
     -H 'X-Finops-Version: 2025-06-23' \
     -H 'X-Organization-Id: ORGANIZATION_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN' \
     -H 'Content-Type: application/json' \
     -d '{
       "payment_intent_status": "approved"
     }'
```

While a payment record is in the `processing` status, the invoice status and amounts are still not updated until the payment is marked as succeeded.

### Complete a scheduled payment

When the external payment succeeds, call [`POST /payment-records/{payment_record_id}/mark-as-succeeded`](/finops/reference/openapi/payment-records/post-payment-records-id-mark-as-succeeded) to apply the payment to the invoice.
In the request body, provide the `paid_at` value and, optionally, the new external `payment_intent_status`:

```sh lines theme={null}
curl -X POST 'https://api.sandbox.tesouro.com/v1/payment-records/60b58b07-e29d-43fd-822f-f6474820f8b2/mark-as-succeeded' \
     -H 'X-Finops-Version: 2025-06-23' \
     -H 'X-Organization-Id: ORGANIZATION_ID' \
     -H 'Authorization: Bearer ACCESS_TOKEN' \
     -H 'Content-Type: application/json' \
     -d '{
       "paid_at": "2025-08-15T09:30:00Z",
       "payment_intent_status": "completed"
     }'
```

This moves the payment record to `succeeded` status and updates the invoice's `amount_paid`, `amount_due`, and `status` accordingly.

### Cancel a scheduled payment

To cancel a scheduled payment that hasn't been executed, call [`POST /payment-records/{payment_record_id}/cancel`](/finops/reference/openapi/payment-records/post-payment-records-id-cancel).
You can cancel payment records in the `created` and `processing` statuses.
