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

# Submit and Track USDC Settlements on Arc

> Settle invoices onchain by submitting a Retempo settlement. The backend executes a real Arc transaction and marks the invoice paid only after confirmation.

Settlements close out invoices by recording proof of payment onchain. When you submit a settlement, Retempo doesn't just log a record — it executes a real transaction against the Arc protocol, waits for the receipt, and only marks the invoice `PAID` once the `SettlementRecorded` event is observed. Every USDC settlement you see as `CONFIRMED` maps to a verifiable onchain transaction.

<Warning>
  Retempo never fabricates transaction hashes or confirms settlements without a real Arc receipt. A settlement that reaches `CONFIRMED` status always corresponds to a real, observable onchain event.
</Warning>

## What happens when you settle

When you `POST` a new settlement, Retempo executes the following steps automatically:

<Steps>
  <Step title="Create the settlement record">
    Retempo creates a settlement record with status `PENDING`, linking it to the invoice, payer, and merchant you specified.
  </Step>

  <Step title="Submit to Arc">
    The backend calls `RetempoSettlement.recordSettlement()` on the Arc smart contract, submitting the settlement onchain.
  </Step>

  <Step title="Wait for the transaction receipt">
    Retempo waits for the Arc transaction to be mined and retrieves the onchain receipt. If the transaction reverts or times out, the settlement moves to `FAILED`.
  </Step>

  <Step title="Observe the SettlementRecorded event">
    Once the receipt confirms success, Retempo checks that the `SettlementRecorded` event was emitted by the Arc contract. If the event is observed, the settlement moves to `CONFIRMED`.
  </Step>

  <Step title="Mark the invoice PAID">
    With a `CONFIRMED` settlement, Retempo automatically updates the linked invoice status to `PAID`. No further action is required on your end.
  </Step>
</Steps>

## Creating a settlement

To create a settlement, send a `POST` request to `/api/v1/settlements`. You must supply an `invoiceId` and a `referenceHash`. The `referenceHash` must be a 32-byte hex value — the `0x` prefix followed by exactly 64 hexadecimal characters.

You also need to supply `payerAddress` (the subscriber's wallet) and `merchantAddress` (the service owner's wallet). Retempo validates that the `payerId` matches the invoice's `userId` and that the `merchantId` matches the service's `ownerId` before submitting to Arc.

```curl theme={null}
curl --request POST \
  --url https://api.retempo.xyz/api/v1/settlements \
  --header 'Content-Type: application/json' \
  --data '{
    "invoiceId": "inv_01hx9r5js9tv0w6eb7zpg8x",
    "referenceHash": "0xabc123def456abc123def456abc123def456abc123def456abc123def456abcd",
    "payerAddress": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b",
    "merchantAddress": "0xdeadbeefcafe1234567890abcdef1234567890ab",
    "amount": "49.000000",
    "currency": "USDC",
    "recordedAt": "2025-01-14T13:05:00.000Z"
  }'
```

The response includes both the settlement record and a `chain` object that contains the raw Arc transaction details:

```json theme={null}
{
  "settlement": {
    "id": "stl_01hx9s6kt0uw1x7fc8aqh9y",
    "invoiceId": "inv_01hx9r5js9tv0w6eb7zpg8x",
    "serviceId": "svc_01hx9kz3v8mq2t4yw6npd7e",
    "payerId": "usr_01hx9n2fp8qt6s3bz4wmd5k",
    "merchantId": "usr_01hx9kz0a3bq1r7fm5ctd2w",
    "status": "CONFIRMED",
    "amount": "49.000000",
    "currency": "USDC",
    "referenceHash": "0xabc123def456abc123def456abc123def456abc123def456abc123def456abcd",
    "transactionHash": "0x9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e",
    "recordedAt": "2025-01-14T13:05:00.000Z",
    "createdAt": "2025-01-14T13:04:42.000Z",
    "invoice": {
      "id": "inv_01hx9r5js9tv0w6eb7zpg8x",
      "status": "PAID",
      "amount": "49.000000",
      "currency": "USDC"
    },
    "service": {
      "id": "svc_01hx9kz3v8mq2t4yw6npd7e",
      "name": "DataStream Pro"
    },
    "payer": {
      "id": "usr_01hx9n2fp8qt6s3bz4wmd5k",
      "email": "agent@example.io"
    },
    "merchant": {
      "id": "usr_01hx9kz0a3bq1r7fm5ctd2w",
      "email": "billing@datastream.io"
    }
  },
  "chain": {
    "transactionHash": "0x9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e",
    "receiptStatus": "success",
    "eventObserved": true,
    "executor": "0xretempo_executor_address",
    "circleTransactionId": null,
    "circleTransactionState": null
  }
}
```

## Settlement statuses

A settlement transitions through the following statuses as it moves from creation to finality:

| Status      | Meaning                                                                                                                                                              |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PENDING`   | The settlement record has been created. The transaction has not yet been submitted to Arc.                                                                           |
| `SUBMITTED` | The transaction has been sent to Arc and Retempo is waiting for a receipt.                                                                                           |
| `CONFIRMED` | Arc returned a successful receipt and the `SettlementRecorded` event was observed. The linked invoice has been marked `PAID`.                                        |
| `FAILED`    | The transaction failed onchain, timed out, or the `SettlementRecorded` event was not observed. The invoice remains unpaid. You may create a new settlement to retry. |

## Fetching a settlement

To retrieve the current state of a settlement along with its linked invoice, service, payer, and merchant, send a `GET` request with the settlement ID:

```curl theme={null}
curl --request GET \
  --url https://api.retempo.xyz/api/v1/settlements/stl_01hx9s6kt0uw1x7fc8aqh9y \
  --header 'Content-Type: application/json'
```

```json theme={null}
{
  "settlement": {
    "id": "stl_01hx9s6kt0uw1x7fc8aqh9y",
    "invoiceId": "inv_01hx9r5js9tv0w6eb7zpg8x",
    "serviceId": "svc_01hx9kz3v8mq2t4yw6npd7e",
    "payerId": "usr_01hx9n2fp8qt6s3bz4wmd5k",
    "merchantId": "usr_01hx9kz0a3bq1r7fm5ctd2w",
    "status": "CONFIRMED",
    "amount": "49.000000",
    "currency": "USDC",
    "referenceHash": "0xabc123def456abc123def456abc123def456abc123def456abc123def456abcd",
    "transactionHash": "0x9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e",
    "recordedAt": "2025-01-14T13:05:00.000Z",
    "createdAt": "2025-01-14T13:04:42.000Z",
    "invoice": {
      "id": "inv_01hx9r5js9tv0w6eb7zpg8x",
      "status": "PAID",
      "amount": "49.000000",
      "currency": "USDC"
    },
    "service": {
      "id": "svc_01hx9kz3v8mq2t4yw6npd7e",
      "name": "DataStream Pro"
    },
    "payer": {
      "id": "usr_01hx9n2fp8qt6s3bz4wmd5k",
      "email": "agent@example.io"
    },
    "merchant": {
      "id": "usr_01hx9kz0a3bq1r7fm5ctd2w",
      "email": "billing@datastream.io"
    }
  }
}
```

<Info>
  If you fetch a settlement with status `SUBMITTED`, Retempo automatically re-checks Arc for the latest receipt before returning the response. The status you receive reflects the most up-to-date onchain state — no need to poll separately.
</Info>

## Idempotency

If you submit a `POST /api/v1/settlements` request with an `invoiceId` and `referenceHash` that already correspond to a `CONFIRMED` settlement, Retempo returns `200` with the existing settlement record instead of creating a duplicate. You do not need to track whether a settlement has already been confirmed — Retempo handles this for you.

This means it is safe to retry a settlement request if you experience a network timeout or are unsure whether your first request landed. If the settlement is already confirmed, you'll get the existing record back at no cost.
