> ## Documentation Index
> Fetch the complete documentation index at: https://yn-c9bb3266.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# PIX

> Accept instant PIX payments in Brazil

## Overview

PIX is Brazil's instant payment system, created and regulated by the Central Bank of Brazil (BACEN). It enables real-time fund transfers 24/7, including weekends and holidays. PIX has become the most popular payment method in Brazil, processing billions of transactions monthly.

Key characteristics:

* **Instant settlement**: Funds arrive in seconds, not days
* **24/7 availability**: Works around the clock, every day
* **Low cost**: Significantly cheaper than card payments for merchants
* **QR code based**: Customers scan a QR code or copy-paste a code in their banking app

## Requirements

| Field                               | Value                               | Description                  |
| ----------------------------------- | ----------------------------------- | ---------------------------- |
| `country`                           | `BR`                                | Brazil only                  |
| `amount.currency`                   | `BRL`                               | Brazilian Real only          |
| `customer.document.document_type`   | `CPF` or `CNPJ`                     | Required by BACEN regulation |
| `customer.document.document_number` | 11 digits (CPF) or 14 digits (CNPJ) | Digits only, no formatting   |

<Warning>
  PIX requires a valid customer tax identification number. CPF (Cadastro de Pessoas Fisicas) is for individuals (11 digits). CNPJ (Cadastro Nacional da Pessoa Juridica) is for businesses (14 digits). Invalid documents will be rejected by the provider.
</Warning>

## Creating a PIX Payment

<CodeGroup>
  ```javascript Node.js theme={"theme":{"light":"github-dark","dark":"github-dark"}}
  const response = await fetch('https://api-sandbox.y.uno/v1/payments', {
    method: 'POST',
    headers: {
      'public-api-key': process.env.YUNO_PUBLIC_KEY,
      'private-secret-key': process.env.YUNO_PRIVATE_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      checkout_session: 'session-id',
      payment_method: { type: 'PIX' },
      amount: { currency: 'BRL', value: 150.00 },
      country: 'BR',
      customer: {
        email: 'cliente@example.com',
        first_name: 'Maria',
        last_name: 'Silva',
        document: {
          document_type: 'CPF',
          document_number: '12345678901',
        },
      },
      description: 'Pedido #456',
    }),
  });
  const payment = await response.json();
  ```

  ```python Python theme={"theme":{"light":"github-dark","dark":"github-dark"}}
  import requests

  response = requests.post(
      'https://api-sandbox.y.uno/v1/payments',
      headers={
          'public-api-key': YUNO_PUBLIC_KEY,
          'private-secret-key': YUNO_PRIVATE_KEY,
          'Content-Type': 'application/json',
      },
      json={
          'checkout_session': 'session-id',
          'payment_method': {'type': 'PIX'},
          'amount': {'currency': 'BRL', 'value': 150.00},
          'country': 'BR',
          'customer': {
              'email': 'cliente@example.com',
              'first_name': 'Maria',
              'last_name': 'Silva',
              'document': {
                  'document_type': 'CPF',
                  'document_number': '12345678901',
              },
          },
          'description': 'Pedido #456',
      },
  )
  payment = response.json()
  ```

  ```go Go theme={"theme":{"light":"github-dark","dark":"github-dark"}}
  payload := map[string]interface{}{
      "checkout_session": "session-id",
      "payment_method":   map[string]interface{}{"type": "PIX"},
      "amount":           map[string]interface{}{"currency": "BRL", "value": 150.00},
      "country":          "BR",
      "customer": map[string]interface{}{
          "email":      "cliente@example.com",
          "first_name": "Maria",
          "last_name":  "Silva",
          "document": map[string]interface{}{
              "document_type":   "CPF",
              "document_number": "12345678901",
          },
      },
      "description": "Pedido #456",
  }

  body, _ := json.Marshal(payload)
  req, _ := http.NewRequest("POST",
      "https://api-sandbox.y.uno/v1/payments",
      bytes.NewBuffer(body),
  )

  req.Header.Set("public-api-key", os.Getenv("YUNO_PUBLIC_KEY"))
  req.Header.Set("private-secret-key", os.Getenv("YUNO_PRIVATE_KEY"))
  req.Header.Set("Content-Type", "application/json")

  resp, err := http.DefaultClient.Do(req)
  ```
</CodeGroup>

## Handling the Response

A successful PIX payment creation returns status `PENDING` with QR code data:

```json theme={"theme":{"light":"github-dark","dark":"github-dark"}}
{
  "id": "pay_pix_abc123",
  "status": "PENDING",
  "amount": { "currency": "BRL", "value": 150.00 },
  "payment_method": {
    "type": "PIX",
    "pix": {
      "qr_code": "data:image/png;base64,iVBORw0KGgo...",
      "qr_code_url": "00020126580014br.gov.bcb.pix0136..."
    }
  },
  "expiration_date": "2026-03-01T10:30:00Z",
  "created_at": "2026-03-01T10:00:00Z"
}
```

| Field             | Description                               |
| ----------------- | ----------------------------------------- |
| `pix.qr_code`     | Base64-encoded PNG image of the QR code   |
| `pix.qr_code_url` | PIX Copia e Cola string (copy-paste code) |
| `expiration_date` | When the PIX code expires                 |

## Displaying the QR Code

Present both options to the customer:

1. **QR Code Image**: Render the base64 image for scanning with a banking app
2. **Copia e Cola**: Show the `qr_code_url` string with a copy button for pasting into a banking app

```html theme={"theme":{"light":"github-dark","dark":"github-dark"}}
<!-- QR Code display -->
<img src="{payment.payment_method.pix.qr_code}" alt="PIX QR Code" />

<!-- Copy-paste code -->
<div>
  <p>Or copy and paste this code in your banking app:</p>
  <input readonly value="{payment.payment_method.pix.qr_code_url}" />
  <button onclick="copyToClipboard()">Copy</button>
</div>
```

<Note>
  Show a countdown timer alongside the QR code so the customer knows how long they have to complete the payment.
</Note>

## PIX Expiration

PIX codes have a configurable expiration period. The default is 30 minutes from creation. You can set a custom expiration using the `expiration_date` field in the payment request:

```json theme={"theme":{"light":"github-dark","dark":"github-dark"}}
{
  "payment_method": { "type": "PIX" },
  "expiration_date": "2026-03-01T12:00:00Z"
}
```

After expiration:

* The QR code and Copia e Cola code become invalid
* The payment status transitions to `EXPIRED`
* A `payment.expired` webhook event is sent

## PIX Refunds

PIX supports instant full and partial refunds. Refunds are processed in real-time and the customer receives funds immediately.

```bash theme={"theme":{"light":"github-dark","dark":"github-dark"}}
curl -X POST https://api-sandbox.y.uno/v1/payments/{payment_id}/refund \
  -H "public-api-key: your-public-api-key" \
  -H "private-secret-key: your-private-secret-key" \
  -H "Content-Type: application/json" \
  -d '{"amount": {"currency": "BRL", "value": 50.00}}'
```

<Note>
  PIX refunds can be issued up to 90 days after the original payment, per BACEN regulation. The refund amount cannot exceed the original payment amount.
</Note>

## PIX Copia e Cola

PIX Copia e Cola is the text-based representation of the PIX payment code. Customers copy this string and paste it into their banking app instead of scanning a QR code. This is especially useful for:

* Desktop/laptop purchases where the customer pays from a mobile device
* Accessibility scenarios
* Situations where QR code scanning is not available

The Copia e Cola string is returned in `payment_method.pix.qr_code_url` and follows the EMV standard format defined by BACEN.

## Webhook Events

Subscribe to these webhook events for PIX payment status updates:

| Event               | Description                    | When                                   |
| ------------------- | ------------------------------ | -------------------------------------- |
| `payment.pending`   | PIX code generated             | Payment created, waiting for customer  |
| `payment.succeeded` | Customer completed PIX payment | Funds received (typically seconds)     |
| `payment.expired`   | PIX code expired               | Customer did not pay before expiration |
| `payment.refunded`  | Refund processed               | Refund completed (instant)             |

```json theme={"theme":{"light":"github-dark","dark":"github-dark"}}
{
  "event": "payment.succeeded",
  "data": {
    "id": "pay_pix_abc123",
    "status": "SUCCEEDED",
    "amount": { "currency": "BRL", "value": 150.00 },
    "payment_method": { "type": "PIX" },
    "paid_at": "2026-03-01T10:02:30Z"
  }
}
```

<Warning>
  Always verify payment status server-side via webhooks before fulfilling orders. Do not rely on client-side callbacks alone, as PIX payments are asynchronous.
</Warning>

## Testing PIX in Sandbox

In the sandbox environment, PIX payments can be tested without real funds:

1. Create a PIX payment using the sandbox API endpoint (`api-sandbox.y.uno`)
2. The response returns a test QR code and Copia e Cola code
3. Use the Yuno Dashboard sandbox tools to simulate payment completion
4. Verify your webhook handler receives the `payment.succeeded` event

<Note>
  Sandbox PIX payments are automatically approved after a short delay (typically 5-10 seconds) or can be manually approved via the Dashboard. Check **Dashboard > Sandbox > Payments** to manage test transactions.
</Note>

## Common Issues

| Issue                                | Cause                                | Resolution                                                               |
| ------------------------------------ | ------------------------------------ | ------------------------------------------------------------------------ |
| 400: `customer.document is required` | Missing CPF/CNPJ                     | Add `customer.document` with valid `document_type` and `document_number` |
| 400: `invalid document_number`       | Wrong format or invalid check digits | Validate CPF (11 digits) or CNPJ (14 digits) before submission           |
| 403: `payment method not available`  | PIX not enabled for merchant         | Enable PIX in **Dashboard > Settings > Payment Methods > Brazil**        |
| `EXPIRED` status                     | Customer did not pay in time         | Create a new payment with a fresh PIX code                               |

## Response Handling

### Synchronous Response

PIX payments return `PENDING` status with QR code data:

```json theme={"theme":{"light":"github-dark","dark":"github-dark"}}
{
  "id": "pay_abc123",
  "status": "PENDING",
  "payment_method": {
    "type": "PIX",
    "pix": {
      "qr_code": "base64-encoded-qr-image",
      "qr_code_url": "00020126580014br.gov.bcb.pix..."
    }
  },
  "expiration": "2026-03-10T12:00:00Z"
}
```

Display either the QR code image (decode base64) or the `qr_code_url` (copy-paste code) to the customer.

### Webhook Events

| Event               | Status      | Action                                                 |
| ------------------- | ----------- | ------------------------------------------------------ |
| `payment.succeeded` | `SUCCEEDED` | Customer paid. Fulfill the order                       |
| `payment.expired`   | `EXPIRED`   | QR code expired. Notify customer or create new payment |
| `payment.refunded`  | `REFUNDED`  | Refund processed. Update order status                  |

<Note>
  PIX payments typically expire in 30 minutes to 24 hours depending on your configuration. Set appropriate expiration times based on your use case.
</Note>
