> ## 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, and `retries` defaults to `0` (no retries) unless you set it explicitly. 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. 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

# Start

> Bramka płatnicza Paymove — jak działa przepływ płatności i czego potrzebujesz do integracji.

Z bramką płatniczą Paymove przyjmowanie płatności online jest proste. Jako sprzedawca inicjujesz transakcję przez nasze API lub SDK, a Twój klient opłaca ją na bezpiecznej, gotowej stronie płatności.

Gdy tylko pieniądze zostaną wpłacone, Twój system natychmiast otrzyma automatyczne powiadomienie.

<Info>
  Gotową integrację możesz przetestować w [demo sklepie Paymove](https://demo.checkout.paymove.io/).
</Info>

## Jak działa płatność?

```mermaid theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
sequenceDiagram
    participant M as Twój serwer
    participant P as Paymove API
    participant C as Checkout Paymove
    participant K as Klient

    M->>P: Utwórz płatność (kwota, orderId, returnUrl)
    P->>M: { redirectUrl }
    M->>K: Przekieruj na redirectUrl
    K->>C: Klient finalizuje płatność
    C->>P: Płatność zakończona
    P->>M: Webhook + nagłówek X-Paymove-Signature
    M->>M: Weryfikacja podpisu
    M->>P: { "status": "ok" }
    C->>K: Klient klika „Wróć do sklepu" (opcjonalnie)
```

| Krok | Kto         | Co się dzieje                                                                                  |
| ---- | ----------- | ---------------------------------------------------------------------------------------------- |
| 1    | Twój serwer | Wywołuje API Paymove z kwotą, `externalId` i `returnUrl`                                       |
| 2    | Paymove     | Zwraca `redirectUrl` -  adres strony checkoutu                                                 |
| 3    | Klient      | Zostaje przekierowany na checkout i podaje dane płatności                                      |
| 4    | Paymove     | Wysyła podpisany webhook na zarejestrowany URL -  domyślnie tylko dla statusu `COMPLETED`      |
| 5    | Twój serwer | [Weryfikuje podpis](/webhook-signature), odpowiada `{ "status": "ok" }` i realizuje zamówienie |
| 6    | Klient      | Widzi ekran potwierdzenia i **może** kliknąć „Wróć do sklepu", co przenosi go na `returnUrl`   |

<Warning>
  Zamówienie realizuj wyłącznie po zweryfikowanym webhooku (krok 5), nigdy po powrocie klienta na `returnUrl` (krok 6). Krok 6 wymaga kliknięcia i może nie nastąpić wcale, a sam `returnUrl` można otworzyć bez opłacenia zamówienia.
</Warning>

## Co potrzebujesz do integracji

| Dane        | Format                                                | Opis                                                                                                |
| ----------- | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `apiKey`    | `sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` | Klucz autoryzacyjny przekazywany w nagłówku `X-API-KEY`. Sandbox: `sk_test_`, produkcja: `sk_live_` |
| `productId` | `2f6c19e8-84a7-4f50-b950-8d5a05e0bbf2`                | UUID identyfikujący Twój sklep w systemie Paymove                                                   |

`Klucz API` i `productId` wygenerujesz w [Panelu Paymove](https://panel.paymove.io).
