# Transactions and receipts (/guides/operate/transactions)

A **transaction** records one paid access attempt: the resource, price, payer, amounts, times, current status, and `payment_request_id`. Each variable records whether it came from input or was reported by the handler.

| Outcome | Meaning for your application |
| --- | --- |
| `succeeded` | Payment completed. Return the protected result and use the receipt when you need payment evidence. |
| `pending`, `authorized`, `settling`, or `reconciling` | Payment is not finished. Keep the protected result private. |
| `failed` | The work or payment did not complete. Do not return the protected result as paid. |

## Read transactions

The Python examples assume the [client is installed and configured](/sdks/python/client/); direct HTTP integrations can use [List transactions](/api-reference/transactions/payments.transactions.list/) and [Get a transaction](/api-reference/transactions/payments.transactions.get/).

```python
from recuut import Recuut

with Recuut() as client:
    transactions = client.transactions.list(page_size=50)
    for transaction in transactions.items:
        print(
            transaction.id,
            transaction.status,
            transaction.payment_request_id,
        )
```

Filter by status or payer when you need a smaller list:

```python
from recuut import Recuut
from recuut.merchant_api import ListOrder, TransactionFilter, TransactionStatus

with Recuut() as client:
    failed = client.transactions.list(
        filter=TransactionFilter(
            status=TransactionStatus.FAILED,
            payer_id="pyr_00000000000070008000000000000000",
        ),
        order=ListOrder.NEWEST,
        page_size=25,
    )
```

## Receipts

Use the transaction ID to read details and get the receipt for a successful payment:

```python
from recuut import Recuut

with Recuut() as client:
    transactions = client.transactions.list(page_size=1)
    if not transactions.items:
        raise RuntimeError("Complete a payment before requesting its receipt.")
    detail = client.transactions.get(transaction_id=transactions.items[0].id)
    if receipt := detail.receipt:
        print(receipt.model_dump_json())
        print(
            receipt.payment.transaction_hash,
            receipt.payment.settled_atomic,
            receipt.payment.asset,
            receipt.payment.network,
        )
```

A receipt is a permanent record of one successful payment. It includes the seller, resource, price, test or live data, parties, and payment reference. A pending, authorized, settling, reconciling, or failed transaction has no receipt.

Amounts ending in `_atomic` are integer strings in the settlement asset's smallest unit. Base Sepolia USDC uses six decimal places: `10000` is 0.01 USDC and `1000000` is 1 USDC. Use the receipt's `asset`, `asset_id`, and `network` before formatting an amount for people.

The SDK validates receipts when reading transactions and completing payment. It rejects a receipt that disagrees with the transaction, completion response, or `PAYMENT-RESPONSE`.

## Pending transactions

An application timeout does not prove that payment failed. For a pending transaction, query the same ID with bounded waits and honor `Retry-After` when provided, or use a short bounded backoff when it is absent. Stop on `succeeded` or `failed`.

`payment_request_id` helps you match a transaction to your own logs. Store it when useful. Do not parse it or infer payment status from its shape.

[Inspect payers →](/guides/operate/payers/)
