> ## 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

# Building with AI agents

> How to point Cursor, Claude Code, Windsurf or Lovable at the Paymove docs so they can implement the integration themselves.

The Paymove documentation is built to be usable not only by people but also by AI agents writing code. Here is how to take advantage of that.

## Before you start the agent

The agent writes the code, but it will not open an account or invent keys for you - these have to come from your side:

| Value                               | Where it comes from                                                                                                                                                                      |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| API key (`sk_test_…` / `sk_live_…`) | [Paymove panel](https://panel.paymove.io)                                                                                                                                                |
| `productId`                         | UUID of your product (store) - from the panel, or from the request that created the product                                                                                              |
| `signingSecret` (`whsec_…`)         | The response to the webhook registration - used to verify `X-Paymove-Signature`                                                                                                          |
| `partnerId`                         | Assigned by Paymove. Needed only to create a product and register a webhook, never to create a payment. Do not have it? Write to [integration@paymove.io](mailto:integration@paymove.io) |

Plus the one-time setup - product, webhook and **assigning the webhook to the product** - described in [Setup](/en/webhooks). Skipping that last step is the most common slip: payments work, notifications never arrive.

<Info>
  An agent given `skill.md` asks for these values and stops until you provide them - instead of putting made-up keys into the code.
</Info>

## The fastest route

Paste this URL to your agent:

```
https://docs.paymove.io/skill.md
```

That is all - no explanatory sentence needed. That address holds the complete integration procedure: what to collect from you, how to create a payment, how to verify the webhook and what to avoid. The agent fetches the file and carries out the integration.

<Info>
  Works in Cursor, Claude Code, Windsurf, Lovable and anywhere else an agent can fetch a URL.
</Info>

## Persistent project configuration

If you want your agent to remember the Paymove rules for every task, add them to your repository once. Copy the contents of:

```
https://docs.paymove.io/agents.md
```

into an `AGENTS.md`, `CLAUDE.md` or `.cursor/rules/paymove.md` file in your project. From then on a prompt like "add payments" is enough - the agent picks up the right rules by itself.

## Every page as Markdown

Append `.md` to any URL in these docs to get clean Markdown with no interface chrome:

```
https://docs.paymove.io/en/rest-api.md
https://docs.paymove.io/en/webhook-signature.md
```

The contextual menu in the top-right corner of every page does the same - it offers copying the page and opening it directly in Claude, ChatGPT, Cursor or VS Code.

## Documentation map for models

| URL                                                       | Contents                                                                                                                           |
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| [`/llms.txt`](https://docs.paymove.io/llms.txt)           | Index of every page with descriptions, plus the integration rules. A good starting point when the agent should decide what to read |
| [`/llms-full.txt`](https://docs.paymove.io/llms-full.txt) | The entire documentation in a single file                                                                                          |
| [`/openapi.yaml`](https://docs.paymove.io/openapi.yaml)   | OpenAPI specification for the payment gateway                                                                                      |
| [`/skill.md`](https://docs.paymove.io/skill.md)           | A ready-made step-by-step integration procedure                                                                                    |
| [`/agents.md`](https://docs.paymove.io/agents.md)         | A short rule set to paste into your repository                                                                                     |

## The rules agents get wrong most often

Whether you are writing the integration yourself or reviewing code an agent produced, check these points:

1. **Amounts are integers in grosze.** `12.99` is silently truncated to 12 grosze and the API returns `200`. Convert with `Math.round(amount * 100)`.
2. **Authenticate with `X-API-KEY`**, not `Authorization: Bearer`.
3. **Server-side only.** The key must not reach the frontend, and a browser call fails CORS anyway.
4. **Always verify `X-Paymove-Signature`** before fulfilling an order.
5. **Never fulfil an order on `returnUrl`** - that is only a browser redirect.
6. **Unknown fields are ignored and the response is `200`** - a malformed request looks like success.
7. **There is no rate limiting, no `429`, no `422` and no `Idempotency-Key`** - code handling those cases is dead weight.

The reasoning behind each is in [Error codes](/en/errors) and [Signature verification](/en/webhook-signature).

## Report a problem

If your agent produced a broken integration despite using the material above, write to [integration@paymove.io](mailto:integration@paymove.io) and include the prompt you used. We treat that as a documentation bug.
