Common pitfalls

Assumptions that look safe and are not. The rule column points to Integration rules.

Assumption Actual behaviour Rule
One key for payins and payouts A key belongs to one shop of one type R1
A production key works in the sandbox Sandbox and production keys work only on their own host R2
Passing the method in the body The endpoint selects the method R3
A method in the contract is enabled for you It may not be: 403 method_not_enabled R3
A retry needs a new reference "to be safe" It creates a second transaction. Resend the same reference and body R4, R6
Changing the amount and resending with the same reference 409 merchant_reference_conflict R4
HTTP 201 means paid It means recorded. Read data.status R8
A decline comes back as an error The request succeeds; the transaction ends failed R9
A voided hold is canceled It is failed with canceled_by_merchant R9
The payer returning to return_urls.success means paid It means the browser came back R8, R18
Treating authorized as paid It is a hold. Call capture or void R11
A failed capture or void is final The payin returns to authorized R11
Treating a refunded payin as unpaid It was charged; refunded_amount says how much came back. The refund is its own transaction R12
The enum lists in the contract are complete Values are added without a new version R13
A webhook on every status Only on requires_action (Google Pay, BLIK), authorized, capture_failed, void_failed and final statuses —
One secret for every shop's webhooks Each shop signs with its own secret; route by URL or shop_id R15
Marking an event as seen before processing it A failure after that loses the event for good R17
Polling the status instead of waiting for webhooks Loads the API and gets 429 rate_limited; poll only after a minute without a webhook R20
Syncing with created_from or newest-first pages Misses later status changes; use order=updated_asc and updated_from R19
Signing the webhook body alone, or a re-serialized body The signature covers <t>.<raw body> as received R15
BLIK refunds work Not supported yet: 501 not_supported_yet —
Sending raw card numbers is fine from any backend It puts you in PCI DSS scope. Wallets, BLIK and the payment form do not —