> For the complete documentation index, see [llms.txt](https://plexo.gitbook.io/rest-api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://plexo.gitbook.io/rest-api/payments/pix-qr-pos.md).

# PIX QR POS

Use this guide when you want to create a PIX payment through the public Payments API, show a QR code at the point of sale, and confirm the result from your backend.

In this guide you will:

* create a PIX POS payment with `POST /v1/payments`
* display the QR code returned in the payment response
* confirm the final result through `callbackUrl` or by polling the payment

**Time to complete:** 15 minutes

## Before you start

Make sure you have:

* HTTP Basic API credentials
* a merchant ID with PIX enabled in **PayFac** mode
* the PIX payment method identifier configured for that merchant, commonly `pix`
* a backend endpoint that can receive payment callbacks, or a process that can poll payment status

{% hint style="warning" %}
The current PIX POS provider flow expects `amount.currency = "USD"`. If you send another currency, the payment request can fail with a currency-not-supported error.
{% endhint %}

{% hint style="info" %}
PIX is available in the merchant setup guide only for PayFac mode. If PIX is not configured for your merchant, the payment creation request can fail with a payment method or merchant payment method error.
{% endhint %}

## Flow overview

```
Create PIX POS payment
    ↓
Receive pending payment with QR payload in payment.code
    ↓
Show QR to the payer
    ↓
Wait for callback or poll GET /v1/payments/{paymentId}
    ↓
Handle approved, denied, expired, cancelled, or failed result
```

## Step 1: Create the PIX POS payment

Use the standard payment creation route:

```
POST /v1/payments
```

For the POS flow, set `flow` to `pos` and pass the merchant's PIX payment method identifier in `paymentMethod.id`.

Example request body:

```json
{
  "merchantId": 12345,
  "flow": "pos",
  "referenceId": "pix-pos-1001",
  "invoiceNumber": "POS-1001",
  "amount": {
    "total": 20.00,
    "currency": "USD",
    "details": {
      "tax": {
        "type": "17934",
        "amount": 2.20,
        "rate": 0.22
      },
      "taxedAmount": 10.00
    }
  },
  "paymentMethod": {
    "id": "pix",
    "source": "bank-transfer"
  },
  "callbackUrl": "https://merchant.example.com/callbacks/payments",
  "metadata": {
    "terminalId": "store-01-pos-03",
    "cashierId": "cashier-17"
  }
}
```

Request notes:

* `invoiceNumber` should be treated as required for this flow
* `paymentMethod.id` must match the PIX method configured for your merchant
* `paymentMethod.source = "bank-transfer"` makes the alternative-payment intent explicit in the current API shape
* `amount.details` groups optional amount-breakdown data such as taxes, tips, discounts, and shipping
* `amount.details.tax.type` identifies the tax regime and is limited to `17934`, `19210`, or `none`
* `amount.details.tax.amount` is the tax amount included in the payment breakdown
* `amount.details.tax.rate` is an optional decimal tax rate, for example `0.22` for 22%
* `amount.details.taxedAmount` is the taxable portion of the payment amount and must not be greater than `amount.total`
* `callbackUrl` is optional but recommended for faster status updates
* `referenceId` must stay unique per payment attempt

Example cURL request:

```bash
AUTH=$(printf '%s:%s' "$CLIENT_ID" "$API_KEY" | base64)

curl --request POST \
  --url https://api.testing.plexo.com.uy/v1/payments \
  --header "Authorization: Basic $AUTH" \
  --header "Content-Type: application/json" \
  --data '{
    "merchantId": 12345,
    "flow": "pos",
    "referenceId": "pix-pos-1001",
    "invoiceNumber": "POS-1001",
    "amount": {
      "total": 20.00,
      "currency": "USD",
      "details": {
        "tax": {
          "type": "17934",
          "amount": 2.20,
          "rate": 0.22
        },
        "taxedAmount": 10.00
      }
    },
    "paymentMethod": {
      "id": "pix",
      "source": "bank-transfer"
    },
    "callbackUrl": "https://merchant.example.com/callbacks/payments",
    "metadata": {
      "terminalId": "store-01-pos-03"
    }
  }'
```

## Step 2: Read the pending payment response

On success, Plexo returns `200 OK` with a `PaymentDto`. For PIX POS, the initial response is typically `pending` and includes the QR payload in `payment.code`.

Example response:

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "referenceId": "pix-pos-1001",
  "invoiceNumber": "POS-1001",
  "status": "pending",
  "flow": "pos",
  "processingMethod": "api",
  "createdAt": "2026-03-27T12:00:00Z",
  "processedAt": "2026-03-27T12:00:01Z",
  "expiresAt": "2026-03-27T12:30:00Z",
  "amount": {
    "total": 20.00,
    "currency": "USD"
  },
  "paymentMethod": {
    "id": "pix",
    "name": "PIX",
    "type": "bank-transfer"
  },
  "code": {
    "type": "qrcode",
    "url": "https://payment.example.com/qr/abc123",
    "value": "00020101021226580014BR.GOV.BCB.PIX...",
    "base64Image": "iVBORw0KGgoAAAANSUhEUgAA..."
  },
  "transactions": [
    {
      "referenceId": "pix-pos-1001",
      "type": "purchase",
      "status": "pending",
      "resultCode": "pending",
      "resultMessage": "Pendiente",
      "ticket": "TICKET123"
    }
  ]
}
```

Focus on these fields:

* `id`: Plexo payment identifier you use for later lookups or cancellations
* `status`: current payment state
* `expiresAt`: when the QR should no longer be presented
* `code.value`: raw PIX payload string
* `code.base64Image`: ready-to-render QR image
* `transactions`: processor-side attempt and ticket details

## Step 3: Show the QR code at the POS

You can present the PIX QR in either of these ways:

* Render `payment.code.base64Image` directly in your POS UI
* Persist `payment.code.value` and regenerate the QR later with `GET /v1/codes?paymentMethod=pix&value=...`

Example HTML image source:

```html
<img src="data:image/png;base64,{{payment.code.base64Image}}" alt="PIX QR code" />
```

If your POS app is not browser-based, use `code.value` or `code.base64Image` in the native UI that displays the payment QR to the payer.

## Step 4: Confirm the final payment result

There are two supported confirmation patterns.

### Option A: Receive asynchronous updates

Provide `callbackUrl` in the original request. Plexo sends payment updates to that URL as the PIX payment changes state.

### Option B: Poll the payment

Retrieve the payment by ID until `status` is no longer `pending`.

```bash
curl --request GET \
  --url https://api.testing.plexo.com.uy/v1/payments/550e8400-e29b-41d4-a716-446655440000 \
  --header "Authorization: Basic $AUTH"
```

Recommended handling:

* treat `approved` as a successful paid PIX transaction
* keep the QR visible while the payment remains `pending`
* stop accepting the QR when the payment becomes `expired`, `cancelled`, `denied`, or `failed`

## Step 5: Handle abandoned or expired QR payments

If the payer does not complete the PIX payment before expiration:

* stop showing the old QR
* create a new payment with a new `referenceId`

If you need to stop a still-pending PIX payment before it expires, use:

```
POST /v1/payments/{paymentId}/cancellations
```

The current backend cancellation rules allow cancellation for non-card payments, including PIX, while the payment is `pending` or `approved`.

## Common errors

| Status | What it usually means                                                                                   |
| ------ | ------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid merchant, missing `invoiceNumber`, unsupported currency, or PIX not configured for the merchant |
| `401`  | Invalid API credentials                                                                                 |
| `403`  | The authenticated client cannot use the merchant                                                        |
| `409`  | Duplicate `referenceId`                                                                                 |
| `422`  | Processor-side rejection or business-rule failure                                                       |

## Related guides

* [Payment Processing Guide](/rest-api/payments/payment-processing.md)
* [Payment Methods Setup Guide](/rest-api/merchant-configuration/payment-methods-setup.md)
* [Testing](/rest-api/operations/testing.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://plexo.gitbook.io/rest-api/payments/pix-qr-pos.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
