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

> ## Agent Instructions
> ## paymove integration rules for AI agents
>
> These rules are verified against the live API. Follow them exactly.
>
> 1. Amounts are INTEGERS in grosze (minor units). `1000` means 10.00 PLN. PLN is the only supported currency and there is no currency field in the API.
> 2. A float `price` (e.g. `12.99`) is SILENTLY TRUNCATED to 12 grosze and still returns HTTP 200. Always send an integer: `Math.round(pln * 100)`.
> 3. Authenticate with the `X-API-KEY` header. Never `Authorization: Bearer`. Sandbox keys start with `sk_test_`, production keys with `sk_live_`.
> 4. Server-side only. A call from a merchant page is rejected. Never put the key in frontend code.
> 5. Unknown request fields are silently ignored and still return HTTP 200 - a wrong body shape looks like success. Match the documented shape exactly.
> 6. A missing `externalId` returns HTTP 500 `Something went wrong`, not 400. A missing `price` or `details.returnUrl` returns HTTP 200 and a usable `redirectUrl` - no error at all. Validate the body yourself before sending it.
> 7. Always verify the `X-Paymove-Signature` header on incoming webhooks before trusting them: https://docs.paymove.io/en/webhook-signature.md
> 8. Errors are `{"status": <int>, "message": "<text>"}`. Branch on the HTTP status only - never on `message`, which is unstable and leaks internal class names.
> 9. There is no rate limiting, no HTTP 429, no HTTP 422, no `Idempotency-Key` header and no API versioning. Do not write code that handles them.
> 10. Re-POSTing an `externalId` that already exists returns HTTP 200 with the ORIGINAL `redirectUrl` and silently discards EVERY field you send - the new price, description and details are all ignored. Use `PATCH /api/pay/product/{productId}/subproduct/{externalId}` to change a price.
> 11. Webhooks fire only on `COMPLETED` by default. Registering a webhook requires both `retries` and `expectedCode` - omitting either returns HTTP 500, and `retries: 0` means no retry at all. Delivery counts as successful when the HTTP status equals `expectedCode` - the response body is never inspected.
> 12. Never fulfil an order on the `returnUrl` redirect. The checkout does not redirect there by itself: the customer has to click "back to shop", and inside the widget modal that redirect never happens. Fulfil only in the webhook handler, after verifying the signature.
> 13. Do not pin a version of `@paymove-io/sdk` - install the latest.
> 14. If the merchant has no `productId` yet, do not stop at a placeholder: ask for the API key, the `partnerId` and the shop name, propose defaults for `location` and `timezone` (`Europe/Warsaw`), offer the optional fields once, then create the product for them with `POST /api/product/pay` and take `productId` from `id` in the response. Do the same for the webhook: register it, then assign it to the product. Guided procedure: https://docs.paymove.io/skill.md (Steps 1-2).
> 15. Full documentation index: https://docs.paymove.io/llms.txt · Copy-paste quickstart: https://docs.paymove.io/en/quickstart.md · Agent skill: https://docs.paymove.io/skill.md

# Pobierz zwroty płatności

> Zwraca wszystkie zwroty danej płatności - w tym **nieudane próby**, ponieważ każdy zwrot
zapisujemy przed skierowaniem go do rozliczenia. Płatność bez zwrotów zwraca pustą tablicę.

To właściwy endpoint do odpytywania o stan zwrotu: wywołuj go co kilka sekund, aż `status`
będzie końcowy (`COMPLETED`, `CANCELED` albo `ERROR`). Klucz API musi mieć uprawnienie
do odczytu, a zwroty przez API muszą być włączone dla konta.




## OpenAPI

````yaml /openapi.yaml get /api/pay/payment/{orderId}/refund
openapi: 3.1.0
info:
  title: Paymove Payment Gateway API
  version: 1.0.0
  description: >
    API bramki płatniczej Paymove umożliwia merchantom tworzenie płatności
    online

    oraz zarządzanie webhookami i produktami.


    ## Zanim zaczniesz - sześć rzeczy, które trzeba wiedzieć


    1. **Kwoty to liczby całkowite w groszach.** `1000` = 10,00 PLN. Wartość z
    częścią
       dziesiętną (np. `12.99`) zostanie po cichu obcięta do `12` groszy, a API zwróci `200`.
       Przeliczaj przez `Math.round(kwota * 100)`.
    2. **Bramka rozlicza wyłącznie w PLN.** W żądaniu nie ma pola waluty.

    3. **Autoryzacja nagłówkiem `X-API-KEY`**, nigdy `Authorization: Bearer`.
    Wywołuj API
       wyłącznie po stronie serwera - żądanie z przeglądarki zostanie odrzucone.
    4. **Nieznane pola w body są po cichu ignorowane**, a API zwraca `200`. Zły
    kształt
       żądania wygląda więc jak sukces - trzymaj się dokładnie udokumentowanej struktury.
    5. **Brak `externalId` kończy się kodem `500`**, a nie `400`. Brak `price`
    albo
       `details.returnUrl` nie zgłasza natomiast żadnego błędu - dostajesz `200`.
    6. **Błędy mają kształt `{"status": <int>, "message": "<tekst>"}`.**
    Rozgałęziaj logikę
       po statusie HTTP - treść `message` bywa niestabilna i nie należy jej parsować.

    Nie istnieją: limity zapytań, kod `429`, kod `422`, nagłówek
    `Idempotency-Key`

    ani wersjonowanie API.
  contact:
    name: Paymove Integration Team
    email: integration@paymove.io
    url: https://paymove.io
servers:
  - url: https://gateway-api.sandbox.paymove.io
    description: Środowisko Sandbox (testowe)
  - url: https://api.paymove.io
    description: Środowisko produkcyjne
security:
  - ApiKeyAuth: []
tags:
  - name: Płatności
    description: Tworzenie płatności
  - name: Zwroty
    description: Zwrot płatności i lista zwrotów
  - name: Produkty
    description: Zarządzanie produktami (merchantami)
  - name: Webhooki
    description: Rejestracja i przypisywanie webhooków
paths:
  /api/pay/payment/{orderId}/refund:
    get:
      tags:
        - Zwroty
      summary: Pobierz zwroty płatności
      description: >
        Zwraca wszystkie zwroty danej płatności - w tym **nieudane próby**,
        ponieważ każdy zwrot

        zapisujemy przed skierowaniem go do rozliczenia. Płatność bez zwrotów
        zwraca pustą tablicę.


        To właściwy endpoint do odpytywania o stan zwrotu: wywołuj go co kilka
        sekund, aż `status`

        będzie końcowy (`COMPLETED`, `CANCELED` albo `ERROR`). Klucz API musi
        mieć uprawnienie

        do odczytu, a zwroty przez API muszą być włączone dla konta.
      operationId: listRefunds
      parameters:
        - name: orderId
          in: path
          required: true
          description: Wewnętrzny identyfikator zamówienia nadany przez Paymove
          schema:
            type: string
            example: PAY1784798914400
      responses:
        '200':
          description: Lista zwrotów płatności
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Refund'
              example:
                - id: 9f2c1b44-6d2f-4f0e-9a71-2b8c5d3e1a90
                  type: REFUND
                  orderId: PAY1784798914400-r1
                  parentOrderId: PAY1784798914400
                  amountMinor: 15000
                  status: COMPLETED
                  paymentMethod: BLIK
                  comment: Klient zrezygnował z zamówienia
                  createdAt: '2026-10-06T11:42:03Z'
                  updatedAt: '2026-10-06T11:42:31Z'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: >-
            Zwroty przez API nie są włączone dla konta, płatność należy do
            innego partnera albo nie istnieje
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
              example:
                status: 403
                message: Access denied
        '500':
          $ref: '#/components/responses/ServerError'
      x-codeSamples:
        - lang: Shell
          label: curl
          source: |
            curl --request GET \
              --url https://gateway-api.sandbox.paymove.io/api/pay/payment/PAY1784798914400/refund \
              --header 'X-API-KEY: sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
components:
  schemas:
    Refund:
      type: object
      description: >-
        Obiekt zwrotu. POST zwraca jeden taki obiekt, GET tablicę obiektów tego
        samego typu.
      properties:
        id:
          type: string
          format: uuid
          description: Identyfikator zwrotu w Paymove
          example: 9f2c1b44-6d2f-4f0e-9a71-2b8c5d3e1a90
        type:
          type: string
          enum:
            - REFUND
          description: Zawsze REFUND
        orderId:
          type: string
          description: >-
            Identyfikator SAMEGO ZWROTU w postaci {orderId płatności}-rN.
            Identyfikator płatności znajdziesz w parentOrderId.
          example: PAY1784798914400-r1
        parentOrderId:
          type: string
          description: orderId zwracanej płatności - ten sam, który podałeś w ścieżce
          example: PAY1784798914400
        amountMinor:
          type: integer
          format: int64
          description: >-
            Zwrócona kwota w groszach. Przy tworzeniu płatności to samo pole
            nazywa się price
          example: 15000
        status:
          type: string
          enum:
            - INITIALIZED
            - PENDING
            - WAITING_FOR_EXTERNAL_ACTION
            - COMPLETED
            - CANCELED
            - ERROR
          description: >-
            Status zwrotu. Jedyny status oznaczający sukces to COMPLETED;
            CANCELED pisane przez jedno l. Zwrot osiąga stan końcowy zwykle w
            ciągu kilkudziesięciu sekund.
          example: PENDING
        paymentMethod:
          type: string
          description: Metoda płatności, którą zapłacono zwracaną płatność
          example: BLIK
        partnerId:
          type: string
          format: uuid
          description: Identyfikator partnera, do którego należy płatność
          example: 3a7d1f52-8b64-4c19-9e03-7d2a5f8c1b44
        productId:
          type: string
          format: uuid
          description: UUID produktu, w ramach którego powstała płatność
          example: 891412c8-8717-4449-9543-e34112bec470
        locale:
          type: string
          description: Locale płatności
          example: pl
        comment:
          type: string
          description: Tekst przekazany w polu reason żądania
          example: Klient zrezygnował z zamówienia
        createdAt:
          type: string
          format: date-time
          description: Czas utworzenia zwrotu (ISO 8601, UTC)
          example: '2026-10-06T11:42:03Z'
        updatedAt:
          type: string
          format: date-time
          description: Czas ostatniej zmiany statusu zwrotu (ISO 8601, UTC)
          example: '2026-10-06T11:42:04Z'
    ApiErrorResponse:
      type: object
      description: >-
        Jednolity kształt odpowiedzi błędu. Rozgałęziaj logikę po statusie HTTP
        - treść pola message bywa niestabilna i może zawierać wewnętrzne nazwy
        klas.
      properties:
        status:
          type: integer
          description: Kod statusu HTTP, powielony w treści odpowiedzi
          example: 401
        message:
          type: string
          description: Opis błędu przeznaczony dla człowieka - nie parsuj go w kodzie
          example: Invalid API key
  responses:
    Unauthorized:
      description: Brak klucza API lub klucz nieprawidłowy, wygasły albo odwołany.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          examples:
            missingCredentials:
              summary: Brak nagłówka X-API-KEY
              value:
                status: 401
                message: Missing credentials
            invalidApiKey:
              summary: Klucz nieprawidłowy
              value:
                status: 401
                message: Invalid API key
    ServerError:
      description: >-
        Błąd po stronie Paymove. Uwaga: ten kod zwracany jest także wtedy, gdy w
        żądaniu zabrakło `externalId` albo gdy identyfikator w ścieżce nie jest
        poprawnym UUID - zanim ponowisz wywołanie, sprawdź kompletność body i
        poprawność ścieżki.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          example:
            status: 500
            message: Something went wrong
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY
      description: >
        Klucz API generowany w [Panelu Paymove](https://panel.paymove.io).


        Format: 51 znaków z prefiksem środowiska - `sk_test_` w sandboxie,

        `sk_live_` na produkcji.

        Przykład: `sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`


        Klucz przekazuj wyłącznie z serwera. Żądanie wysłane ze strony sklepu
        zostanie

        odrzucone - a klucz i tak nigdy nie może trafić do kodu frontendowego.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.