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

# Transactions

> Process and manage payment transactions

Transactions represent payment operations processed through the Rinne platform. Each transaction is linked to a merchant, processed through a provider affiliation, and can support various payment methods.

## Transaction basics

A transaction requires:

* An active provider affiliation
* Transaction amount (in cents)
* Payment method (PIX, credit card, etc.)
* Capture method (e-commerce, POS, etc.)
* Unique request ID for idempotency

### Entity relationships

```mermaid theme={null}
graph LR
    M[Merchant] -->|creates| T[Transaction]
    T -->|uses| A[Affiliation]
    A -->|via| P[Provider]
    T -->|generates| LE[Ledger Entries]
    T -->|can have| R[Refunds]
    T -->|applies| FP[Fee Policy]
    T -->|applies| CP[Cost Policy]
    T -->|paid by| C[Consumer]

    style M fill:#7B89FF,color:#fff
    style T fill:#5B68EB,color:#fff
    style A fill:#4A56D9,color:#fff
    style P fill:#7B89FF,color:#fff
    style LE fill:#5B68EB,color:#fff
    style R fill:#7B89FF,color:#fff
    style FP fill:#4A56D9,color:#fff
    style CP fill:#4A56D9,color:#fff
    style C fill:#7B89FF,color:#fff
```

## Creating transactions

### PIX transaction

#### PIX guidelines

* **Installments**: Must be 1 for PIX (defaults to 1 if not sent).
* **When `pix_data.due_date` is provided**: `consumer` is required with `full_name`, `document_number`, and `document_type`. Use `expiration_in_days_after_due_date`; do not send `expiration_in_seconds`.
* **When `pix_data.due_date` is not provided**: Use `expiration_in_seconds`; do not send `expiration_in_days_after_due_date`.

#### Immediate PIX payment

```bash theme={null}
curl -X POST https://api-sandbox.rinne.com.br/core/v1/merchants/MERCHANT_ID/transactions \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "CELCOIN",
    "request_id": "unique-request-123",
    "amount": 10000,
    "currency": "BRL",
    "capture_method": "ECOMMERCE",
    "payment_method": "PIX",
    "pix_data": {
      "description": "Payment for order #123",
      "expiration_in_seconds": 3600
    },
    "consumer": {
      "full_name": "João Silva",
      "email": "joao@example.com",
      "document_type": "CPF",
      "document_number": "81146431023"
    }
  }'
```

The response includes a QR code for the customer to scan:

```json theme={null}
{
    "id": "tx_123456789",
    "status": "WAITING_PAYMENT",
    "amount": 10000,
    "pix_data": {
        "qr_code": "00020126580014br.gov.bcb.pix...",
        "expires_at": "2025-01-21T11:00:00Z"
    }
}
```

#### PIX with due date

For invoice payments, you can create PIX transactions with a due date and pricing modifiers:

```bash theme={null}
curl -X POST https://api-sandbox.rinne.com.br/core/v1/merchants/MERCHANT_ID/transactions \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "CELCOIN",
    "request_id": "invoice-456",
    "amount": 100000,
    "currency": "BRL",
    "capture_method": "ECOMMERCE",
    "payment_method": "PIX",
    "pix_data": {
      "description": "Invoice payment",
      "due_date": "2025-12-31",
      "expiration_in_days_after_due_date": 30,
      "interest": {
        "percentage": 2.0,
        "modality": "PERCENTAGE_PER_MONTH"
      },
      "fine": {
        "percentage": 5.0,
        "modality": "PERCENTAGE"
      },
      "discount": {
        "modality": "PERCENTAGE_UNTIL_DATE",
        "discount_dates_config": [
          {
            "until_date": "2025-12-15",
            "percentage": 10.0
          }
        ]
      }
    },
    "consumer": {
      "full_name": "Maria Santos",
      "email": "maria@example.com",
      "document_type": "CPF",
      "document_number": "12345678901"
    }
  }'
```

**Due date features:**

* `due_date`: Expected payment date (YYYY-MM-DD format)
* `expiration_in_days_after_due_date`: Days after due date before expiration (1-365, default: 30)
* `interest`: Applied when paid after due date
* `fine`: One-time charge when paid after due date
* `discount`: Reduces amount when paid early
* `abatement`: Permanent amount reduction

<Note>
  When using `due_date`, consumer information (`full_name`, `document_number`, `document_type`) is
  required.
</Note>

### BolePix transaction

BolePix is a hybrid payment method that generates both a boleto (bank slip) and a PIX QR code. Customers can pay using either method.

```bash theme={null}
curl -X POST https://api-sandbox.rinne.com.br/core/v1/merchants/MERCHANT_ID/transactions \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "CELCOIN",
    "request_id": "bolepix-order-123",
    "amount": 50000,
    "currency": "BRL",
    "capture_method": "ECOMMERCE",
    "payment_method": "BOLEPIX",
    "bolepix_data": {
      "due_date": "2025-12-31",
      "expiration_in_days_after_due_date": 30,
      "discount": {
        "amount": 5000,
        "modality": "FIXED",
        "until_date": "2025-12-25"
      },
      "fine_percentage": 2.0,
      "monthly_interest_percentage": 1.0
    },
    "consumer": {
      "full_name": "Maria Silva",
      "email": "maria@email.com",
      "document_type": "CPF",
      "document_number": "81146431023",
      "address": {
        "country": "076",
        "state": "SP",
        "city": "São Paulo",
        "zipcode": "01310100",
        "street": "Av Paulista",
        "street_number": "1000"
      }
    }
  }'
```

The response includes both boleto and PIX payment data:

```json theme={null}
{
    "id": "tx_123456789",
    "status": "WAITING_PAYMENT",
    "amount": 50000,
    "bolepix_data": {
        "due_date": "2025-12-31",
        "bar_code": "00190000090299993600000000000000185830000050000",
        "bank_line": "00190.00009 02999.936001 00000.000001 8 58300000050000",
        "pix_emv": "00020126580014br.gov.bcb.pix..."
    }
}
```

#### BolePix requirements

* **Minimum amount**: 500 cents (R\$ 5.00)
* **Maximum amount**: 1,500,000,000 cents (R\$ 15,000,000.00)
* **Installments**: Must be 1 (no installment support)
* **Consumer**: Required with `full_name`, `document_type`, `document_number`, and full address including `street_number`

#### BolePix-specific fields

* `due_date`: Payment due date in YYYY-MM-DD format (required, must be today or later)
* `expiration_in_days_after_due_date`: Days after due date before expiration (0-59, default: 0)
* `discount`: Optional discount configuration
  * `amount`: Fixed discount amount in cents (for FIXED modality)
  * `percentage`: Discount percentage (for PERCENTAGE modality)
  * `modality`: `FIXED` or `PERCENTAGE`
  * `until_date`: Date until which discount applies (must be before or equal to due\_date)
* `fine_percentage`: Fine percentage applied after due date (0.01-100%)
* `monthly_interest_percentage`: Monthly interest divided by 30 and applied per day after due date (0.01-100%)

<Note>
  The minimum amount after discount is applied must be at least 500 cents (R\$ 5.00).
</Note>

### Card transaction

<Info>
  Use [Card transactions](/guides/card-transactions), [Wallet transactions](/guides/wallet-transactions), and [3D Secure authentication](/guides/three-d-secure-authentication) for production-ready implementation details.
</Info>

For credit and debit card transactions, you'll need to provide card data including either the card number or a network token (for tokenized payments like Apple Pay or Google Pay). Card credentials are accepted only in encrypted form — these values must come from the rinne-js secure components, which encrypt them so raw card data never touches your systems and you avoid PCI scope issues.

For example, a tokenized wallet transaction:

```bash theme={null}
curl -X POST https://api-sandbox.rinne.com.br/core/v1/merchants/MERCHANT_ID/transactions \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "RINNE",
    "request_id": "unique-request-456",
    "amount": 25000,
    "currency": "BRL",
    "capture_method": "ECOMMERCE",
    "installments": 3,
    "payment_method": "CREDIT_CARD",
    "card_data": {
      "network_token": "ev:encrypted:network_token",
      "cryptogram": "ev:encrypted:cryptogram",
      "expiry_month": "12",
      "expiry_year": "2025",
      "cardholder_name": "Maria Santos",
      "last_digits": "1111",
      "authentication_type": "3DS",
      "wallet_type": "APPLE_PAY",
      "display_name": "Visa •••• 1111"
    },
    "consumer": {
      "full_name": "Maria Santos",
      "email": "maria@example.com",
      "document_type": "CPF",
      "document_number": "12345678901"
    }
  }'
```

#### Card data requirements

The `card_data` field is **required** for `CREDIT_CARD` and `DEBIT_CARD` payment methods and has the following validation rules:

* **Either** `number` (card PAN) **or** `network_token` must be provided (mutually exclusive)
* `number`, `cvv`, `network_token`, and `cryptogram` must arrive encrypted from rinne-js; plaintext values are rejected with `400 VALIDATION_ERROR`
* `expiry_month`: Two-digit month (01-12)
* `expiry_year`: Four-digit year (YYYY)
* `cardholder_name`: Name of the cardholder as it appears on the card
* `last_digits`: Last 4 digits of the card number (exactly 4 digits)
* `cryptogram`: Required for authenticated/tokenized 3DS flows (directly or injected from `three_d_secure_session_id`)
* `authentication_type`: Currently only `3DS` is supported

#### 3DS challenge strategy flags

Card transaction creation supports two optional flags:

* `require_3ds`: Forces immediate `AWAITING_3DS` status and defers provider authorization until `/authenticate` is called with an authenticated 3DS session.
* `refuse_on_challenge`: Refuses challenge-triggered paths immediately (`REFUSED`) instead of moving to `AWAITING_3DS`.

These flags let you tune 3DS policy without changing your entire checkout architecture:

* Use `require_3ds` to enforce 3DS while staying in a pure transaction-first flow (no separate session-first policy path required).
* Use `refuse_on_challenge` to fail fast when you intentionally do not support challenge handling for a merchant or transaction segment.

When `refuse_on_challenge` blocks a challenge-triggered path, the transaction uses:

* `status`: `REFUSED`
* `status_reason`: `CHALLENGE_NOT_ALLOWED`

When `refuse_on_challenge` is enabled, non-challenge transactions still follow normal provider processing.

<Warning>
  `require_3ds` and `refuse_on_challenge` cannot both be `true` in the same transaction request.
</Warning>

#### Tokenized payments

For digital wallet payments (Apple Pay, Google Pay), use the `network_token` field instead of the card number:

* Set `wallet_type` to `APPLE_PAY` or `GOOGLE_PAY`
* Provide the `network_token` from the wallet provider
* Include the `cryptogram` for secure authentication
* Optionally include `display_name` for user-friendly card identification

<Tip>
  Use [rinne-js](/rinne-js) to easily integrate Apple Pay and Google Pay buttons in your web
  application. The SDK handles wallet authentication and provides encrypted card data ready for
  transaction processing.
</Tip>

## Transaction status

Transactions move through different statuses during their lifecycle:

```mermaid theme={null}
stateDiagram-v2
    [*] --> PROCESSING: Create transaction
    PROCESSING --> WAITING_PAYMENT: PIX QR code generated
    PROCESSING --> AUTHORIZED: Card authorized
    PROCESSING --> AWAITING_3DS: 3DS required
    AWAITING_3DS --> PROCESSING: Transaction authenticated
    PROCESSING --> REFUSED: Payment declined
    PROCESSING --> FAILED: Provider error
    AWAITING_3DS --> REFUSED: Authentication failed
    WAITING_PAYMENT --> APPROVED: Customer pays
    WAITING_PAYMENT --> EXPIRED: Payment timeout
    WAITING_PAYMENT --> PENDING_CANCELLATION: Cancel requested
    PENDING_CANCELLATION --> CANCELLED: Cancellation confirmed
    AUTHORIZED --> APPROVED: Capture payment
    APPROVED --> PENDING_REFUND: Refund initiated
    PENDING_REFUND --> PARTIALLY_REFUNDED: Partial refund completed
    PENDING_REFUND --> REFUNDED: Full refund completed
    APPROVED --> CHARGEDBACK: Dispute
    REFUSED --> [*]
    FAILED --> [*]
    EXPIRED --> [*]
```

| Status                 | Description                                                  |
| ---------------------- | ------------------------------------------------------------ |
| `PROCESSING`           | Transaction is being processed                               |
| `WAITING_PAYMENT`      | Awaiting customer payment (PIX)                              |
| `AWAITING_3DS`         | Awaiting 3DS authentication                                  |
| `AUTHORIZED`           | Payment authorized but not captured                          |
| `APPROVED`             | Payment successfully processed                               |
| `REFUSED`              | Payment declined by provider/acquirer for a business reason  |
| `FAILED`               | Provider HTTP call errored (4xx/5xx, timeout, network error) |
| `EXPIRED`              | Payment window expired                                       |
| `PENDING_REFUND`       | Refund is being processed                                    |
| `REFUNDED`             | Fully refunded                                               |
| `PARTIALLY_REFUNDED`   | Partially refunded                                           |
| `CHARGEDBACK`          | Disputed and reversed                                        |
| `PENDING_CANCELLATION` | Cancellation in progress (BOLEPIX only)                      |
| `CANCELLED`            | Transaction cancelled before payment (BOLEPIX only)          |

<Note>
  **REFUSED vs FAILED:** `REFUSED` means the provider explicitly declined the transaction for a
  business reason (e.g., insufficient funds, invalid card). `FAILED` means the HTTP call to the
  provider errored (4xx/5xx, timeout, network failure). Both are terminal states.
</Note>

For `REFUSED` outcomes, `status_reason` can include values such as `PROVIDER`, `ACQUIRER`,
`ANTIFRAUD`, `NO_ACQUIRER`, `ACQUIRER_TIMEOUT`, and `CHALLENGE_NOT_ALLOWED`.

## Cancelling BOLEPIX transactions

You can cancel BOLEPIX transactions that are in `WAITING_PAYMENT` status before the customer pays:

```bash theme={null}
curl -X POST https://api-sandbox.rinne.com.br/core/v1/transactions/TRANSACTION_ID/cancel \
  -H "x-api-key: YOUR_API_KEY"
```

Or for a specific merchant's transaction:

```bash theme={null}
curl -X POST https://api-sandbox.rinne.com.br/core/v1/merchants/MERCHANT_ID/transactions/TRANSACTION_ID/cancel \
  -H "x-api-key: YOUR_API_KEY"
```

### Cancellation behavior

When you cancel a BOLEPIX transaction:

1. The transaction status changes to `PENDING_CANCELLATION`
2. A cancellation request is sent to the provider
3. If successful, the status changes to `CANCELLED`
4. If the provider times out, the status remains `PENDING_CANCELLATION`

<Note>
  **Non-terminal cancellation:** The cancellation may be non-terminal. If the provider times out, the transaction remains in `PENDING_CANCELLATION`. Final reconciliation to `CANCELLED` is performed asynchronously when the provider sends the `bolepix.cancelled` webhook. Poll the transaction or subscribe to the `transaction.status-changed` webhook rather than assuming immediate finality.
</Note>

### Cancellation requirements

* **Payment method**: Only BOLEPIX transactions can be cancelled
* **Status**: Transaction must be in `WAITING_PAYMENT` status
* **Permissions**: Requires `transaction.cancel` or `merchant.transaction.cancel` permission

## Amounts in cents

All monetary values in the API are represented in cents (integer values):

* `10000` = R\$ 100.00
* `1050` = R\$ 10.50
* `99` = R\$ 0.99

<Warning>
  Always use integers for amounts. Never use decimal values or floating-point numbers.
</Warning>

### Minimum amount validation

Transaction amounts must be greater than the calculated fee. When creating a transaction, the system validates that the amount covers the fee based on the merchant's fee policy. If the amount is insufficient, the API returns a validation error:

```json theme={null}
{
    "error": {
        "code": "VALIDATION_ERROR",
        "message": "Validation error",
        "status": 400,
        "details": {
            "issues": [
                {
                    "field": "amount",
                    "type": "OUT_OF_RANGE",
                    "value": 100,
                    "constraints": {
                        "minimumAmount": 351,
                        "calculatedFee": 350
                    }
                }
            ]
        }
    }
}
```

The `constraints` object provides:

* `minimumAmount`: The minimum amount required for the transaction (calculated fee + 1 cent)
* `calculatedFee`: The total fee that would be charged for this transaction

<Tip>
  To avoid this error, ensure your transaction amount is strictly greater than the calculated fee. You can use the fee policy details to estimate fees before creating transactions.
</Tip>

## Request ID for idempotency

The `request_id` field ensures idempotent transaction creation. If you retry a request with the same `request_id`, you'll receive the existing transaction instead of creating a duplicate.

```bash theme={null}
# First request - creates transaction
POST /v1/transactions
{ "request_id": "order-123", "amount": 10000, ... }
# Response: 201 Created

# Retry with same request_id - returns existing transaction
POST /v1/transactions
{ "request_id": "order-123", "amount": 10000, ... }
# Response: 200 OK (same transaction)
```

## Automatic anticipation

Each transaction includes an `automatic_anticipation` boolean field, set at creation time based on the affiliation's `anticipation_type`. When the affiliation uses `AUTOMATIC` anticipation, this field is `true`; otherwise it is `false`. The value is immutable after creation.

This field can be used as a condition in [pricing rules](/concepts/pricing#transaction-fields) to apply different fee rates depending on whether a transaction is automatically anticipated.

## Transaction pricing

Each transaction has associated fees and costs:

```json theme={null}
{
    "pricing": {
        "fee": {
            "percentage": 3.5,
            "flat": 0,
            "minimum_price": 0
        },
        "cost": {
            "percentage": 0.5,
            "flat": 0,
            "minimum_price": 0
        }
    }
}
```

* **Fee**: Amount charged to the merchant (your revenue)
* **Cost**: Amount paid to the provider (your cost)

Pricing is calculated using fee and cost policies configured for the merchant.

## Refunds

You can refund approved PIX, credit card, and debit card transactions partially or fully through the same endpoint. The request body is identical regardless of payment method:

```bash theme={null}
curl -X POST https://api-sandbox.rinne.com.br/core/v1/merchants/MERCHANT_ID/transactions/TRANSACTION_ID/refunds \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "refund_amount": 5000,
    "refund_reason": "CUSTOMER_REQUEST",
    "description": "Customer requested refund",
    "metadata": {
      "refund_source": "customer_request",
      "ticket_id": "support-123"
    }
  }'
```

### Supported payment methods

| Payment method               | Refund support                                                                                         |
| ---------------------------- | ------------------------------------------------------------------------------------------------------ |
| `PIX`                        | Full and partial; multiple refunds allowed up to the remaining refundable amount                       |
| `CREDIT_CARD` / `DEBIT_CARD` | One successful refund per transaction. Full any day; partial only from D+1 onward (see warnings below) |
| `BOLEPIX`                    | Not supported                                                                                          |

### Refund rules

* BOLEPIX transactions do not support refunds.
* Only `APPROVED` or `PARTIALLY_REFUNDED` transactions can be refunded.
* Refund amount cannot exceed: `approved_amount - refunded_amount`.
* When a refund is initiated, the transaction status changes to `PENDING_REFUND`.
* Partial refunds change the transaction status to `PARTIALLY_REFUNDED`; full refunds change it to `REFUNDED`.
* Only one refund can be in progress at a time per transaction (`PENDING`, `PROCESSING`, or `TIMEOUT` status).
* Card transactions accept only one successful refund. Once a `CREDIT_CARD` or `DEBIT_CARD` transaction has any `COMPLETED` refund, it is treated as terminally refunded and any further refund request is rejected synchronously with `HTTP 400`. PIX transactions are not subject to this rule.
* Balance is checked before processing refunds to ensure sufficient funds.

<Warning>
  **Card transactions accept only one successful refund.** Once a `CREDIT_CARD` or `DEBIT_CARD` transaction has a refund in `COMPLETED` status, any additional refund request — partial or full — is rejected synchronously with `HTTP 400`. Plan the refund amount up front: if you need to refund a card transaction in pieces, the first successful refund must cover the full remaining amount you intend to return.

  Prior refunds in `FAILED` or `CANCELLED` status do not count toward this rule, so you can submit a new refund after a failed attempt.
</Warning>

<Warning>
  **Same-day partial refunds are not allowed for card transactions.** When the refund request lands on the same calendar day as the transaction's `approved_at` (D0), only a refund for the **full remaining refundable amount** is accepted. Partial refunds are allowed only from the next calendar day (D+1) onward.

  Same-day partial requests fail synchronously with `HTTP 400`. On D0 you can still issue a full refund, and on D+1 (or later) any partial amount up to the remaining refundable balance is accepted. See [Refunding card transactions](/guides/card-transactions#refunding-card-transactions) for an example.
</Warning>

### Refund reasons

| Reason                           | Description                    |
| -------------------------------- | ------------------------------ |
| `CUSTOMER_REQUEST`               | Customer requested refund      |
| `FRAUD`                          | Fraudulent transaction         |
| `BANKING_ERROR`                  | Banking system error           |
| `PIX_WITHDRAWAL_OR_CHANGE_ERROR` | PIX withdrawal or change error |

### Refund processing semantics

The refund response always includes the current refund status. How that status is determined depends on the payment method.

#### PIX refunds

PIX refunds are processed asynchronously to improve reliability:

1. A refund record is created with `PENDING` status.
2. The transaction status changes to `PENDING_REFUND`.
3. The system attempts to process the refund with the provider.
4. On success, the refund status updates to `COMPLETED`.
5. On timeout, the refund status updates to `TIMEOUT` and is queried again later.
6. On other transient errors, the refund stays `PENDING` for automatic retry.

<Note>
  For PIX, transient provider errors (timeout, insufficient balance, etc.) cause the refund to be automatically retried until it succeeds or is manually cancelled.
</Note>

#### Card refunds

Card refunds resolve as far as possible on the same API call:

* A definitive provider response (success or rejection) returns synchronously with the refund already in its terminal state — `COMPLETED` for a successful cancel, `FAILED` for a definitive rejection (for example, an acquirer business decline). `FAILED` card refunds are **terminal and not retried**; submit a new refund request to try again.
* An uncertain outcome (acquirer 5xx or network timeout) triggers an inline status query against the acquirer. If that query resolves the outcome, you still get `COMPLETED` or `FAILED` on the same call. Otherwise the refund moves to `TIMEOUT` and is reconciled asynchronously.
* A `PENDING_REFUND` response on a card transaction means the request reached us but did not produce a definitive answer; we will retry the (idempotent) cancel.

### Cancelling a pending refund

You can cancel a refund that is in `PENDING` status:

```bash theme={null}
curl -X PATCH https://api-sandbox.rinne.com.br/core/v1/transactions/TRANSACTION_ID/refunds/cancel \
  -H "x-api-key: YOUR_API_KEY"
```

When a refund is cancelled:

* The refund status changes to `CANCELLED`
* The transaction status reverts based on remaining refunds:
  * `APPROVED` if no other completed refunds exist
  * `PARTIALLY_REFUNDED` if other completed refunds exist

<Warning>
  Only refunds with `PENDING` status can be cancelled. Refunds that are `PROCESSING`, `COMPLETED`,
  `FAILED`, or `TIMEOUT` cannot be cancelled.
</Warning>

### Refund information in transaction response

When you retrieve a transaction with full details, the response includes a `refunds` array with complete refund information:

```json theme={null}
{
    "id": "tx_123456789",
    "status": "PARTIALLY_REFUNDED",
    "amount": 10000,
    "refunded_amount": 5000,
    "refunds": [
        {
            "id": "ref_123456789",
            "transaction_id": "tx_123456789",
            "request_id": "req_refund_123",
            "amount": 5000,
            "status": "COMPLETED",
            "reason": "CUSTOMER_REQUEST",
            "description": "Customer requested partial refund",
            "provider_refund_identification": "D13935893202307271346SPpDyb4f123",
            "metadata": {
                "refund_source": "customer_request",
                "ticket_id": "support-123"
            },
            "created_at": "2023-12-01T10:00:00.000Z",
            "updated_at": "2023-12-01T10:00:00.000Z"
        }
    ]
}
```

Each refund includes:

* **id**: Unique refund identifier
* **amount**: Refund amount in cents
* **status**: Refund status (`PENDING`, `PROCESSING`, `COMPLETED`, `FAILED`, `TIMEOUT`, `CANCELLED`)
* **reason**: Reason for the refund
* **description**: Optional additional description (nullable)
* **provider\_refund\_identification**: Provider-specific identifier for the refund, such as E2E ID for PIX or ARN for cards (nullable)
* **metadata**: Optional custom key-value pairs for tracking and integration (nullable)
* **created\_at** / **updated\_at**: Timestamps

### Refund status lifecycle

| Status       | Description                                  |
| ------------ | -------------------------------------------- |
| `PENDING`    | Refund created, awaiting processing or retry |
| `PROCESSING` | Refund is being processed by the provider    |
| `COMPLETED`  | Refund successfully processed                |
| `FAILED`     | Refund failed permanently                    |
| `TIMEOUT`    | Provider request timed out, will be retried  |
| `CANCELLED`  | Refund was manually cancelled                |

### Automatic refund processing

Rinne automatically monitors and processes refunds through background jobs:

* **Pending refunds**: Processed every 30 minutes. PENDING refunds older than 2 minutes are retried with the provider.
* **Timeout refunds**: Checked every 5 minutes. TIMEOUT refunds are queried at the provider to sync their status. If not found, they revert to PENDING for reprocessing.

This ensures refund statuses stay synchronized with payment providers without manual intervention.

## Retrieving transactions

### Get a specific transaction

You can retrieve a transaction by ID without specifying the merchant ID:

```bash theme={null}
curl "https://api-sandbox.rinne.com.br/core/v1/merchants/transactions/TRANSACTION_ID" \
  -H "x-api-key: YOUR_API_KEY"
```

This endpoint returns full transaction details including ledger entries, refunds, and settlement information. The transaction must belong to a merchant within your authenticated organization.

### List transactions for a specific merchant

```bash theme={null}
curl "https://api-sandbox.rinne.com.br/core/v1/merchants/MERCHANT_ID/transactions?status=APPROVED&page=1&limit=20" \
  -H "x-api-key: YOUR_API_KEY"
```

### List transactions for all merchants (organization)

```bash theme={null}
curl "https://api-sandbox.rinne.com.br/core/v1/merchants/transactions?created_at_from=2025-01-01T00:00:00Z&created_at_to=2025-01-31T23:59:59Z" \
  -H "x-api-key: YOUR_ORG_API_KEY"
```

## Filtering and sorting

Transactions support extensive filtering:

* `status`: Filter by transaction status (array)
* `payment_method`: Filter by payment method
* `amount_from` / `amount_to`: Filter by amount range
* `created_at_from` / `created_at_to`: Filter by date range
* `provider`: Filter by provider
* `sort`: Sort by fields (e.g., `-created_at,amount`)

## Transaction metadata

Store custom data with transactions using the `metadata` field:

```json theme={null}
{
    "metadata": {
        "order_id": "order-123",
        "customer_id": "cust-456",
        "store_location": "SP-001"
    }
}
```

Metadata is returned with the transaction and can be used for reconciliation and reporting.

## Transaction receipts

Generate PDF receipts for completed PIX transactions, including both original payments and refunds.

### Receipt eligibility

Receipts are available for transactions that meet these requirements:

* **Status**: `APPROVED`, `REFUNDED`, or `PARTIALLY_REFUNDED`
* **Payment method**: PIX only (currently supported)
* **Payer information**: Transaction must have payer data
* **End-to-end ID**: Transaction must have a valid PIX end-to-end identifier

### Receipt types

* **PAYMENT**: Receipt for the original transaction payment
* **REFUND**: Receipt for each completed refund with a provider identification

### Generating receipts

```bash theme={null}
curl "https://api-sandbox.rinne.com.br/core/v1/transactions/TRANSACTION_ID/receipt" \
  -H "x-api-key: YOUR_API_KEY"
```

Or for a specific merchant's transaction:

```bash theme={null}
curl "https://api-sandbox.rinne.com.br/core/v1/merchants/MERCHANT_ID/transactions/TRANSACTION_ID/receipt" \
  -H "x-api-key: YOUR_API_KEY"
```

### Receipt response

The response includes a list of receipts (payment and any refunds):

```json theme={null}
{
    "receipts": [
        {
            "type": "PAYMENT",
            "transaction_id": "tx_123456789",
            "refund_id": null,
            "amount": 10000,
            "currency": "BRL",
            "identification": "E12345678202501211034567890",
            "created_at": "2025-01-21T10:00:00.000Z",
            "payer": {
                "name": "John Doe",
                "document": "***.456.789-**",
                "bank_name": "BCO SANTANDER (BRASIL) S.A.",
                "ispb": "90400888",
                "branch": "0001",
                "account": "12345678"
            },
            "receiver": {
                "name": "Company Name Ltda",
                "document": "12.345.678/0001-90",
                "bank_name": "BCO DO BRASIL S.A.",
                "ispb": "00000000",
                "branch": "1234",
                "account": "00012345"
            },
            "pdf_file_base64": "JVBERi0xLjQK..."
        },
        {
            "type": "REFUND",
            "transaction_id": "tx_123456789",
            "refund_id": "ref_987654321",
            "amount": 5000,
            "currency": "BRL",
            "identification": "D13935893202601271529YV9B1m6o2Ih",
            "created_at": "2025-01-22T14:30:00.000Z",
            "payer": {
                "name": "Company Name Ltda",
                "document": "12.345.678/0001-90",
                "bank_name": "BCO DO BRASIL S.A.",
                "ispb": "00000000",
                "branch": "1234",
                "account": "00012345"
            },
            "receiver": {
                "name": "John Doe",
                "document": "***.456.789-**",
                "bank_name": "BCO SANTANDER (BRASIL) S.A.",
                "ispb": "90400888",
                "branch": "0001",
                "account": "12345678"
            },
            "pdf_file_base64": "JVBERi0xLjQK..."
        }
    ]
}
```

### Payer/receiver direction

* **Payment receipts**: Payer is the customer, receiver is the merchant
* **Refund receipts**: Payer is the merchant, receiver is the customer (reversed)

<Note>
  CPF documents are masked for privacy (e.g., `***.456.789-**`), while CNPJ documents are shown in full.
</Note>

## Next steps

<CardGroup cols={2}>
  <Card title="rinne-js SDK" icon="js" href="/rinne-js">
    Accept Apple Pay & Google Pay on the web
  </Card>

  <Card title="PIX Payments" icon="qrcode" href="/guides/pix-payments">
    Learn how to process PIX transactions
  </Card>

  <Card title="Webhooks" icon="webhook" href="/guides/webhooks">
    Receive transaction status updates
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/introduction">
    Explore transaction endpoints
  </Card>
</CardGroup>
