Przejdź do treści
Oplac

Podstawy API

Błędy

Każda odpowiedź 4xx i 5xx, także 404 nieznanej trasy, 405, 429 i 500, ma tę samą postać: obiekt error z klasą, stałym kodem, komunikatem po polsku, nazwą pola i adresem opisu w tej dokumentacji. Obsługę buduj na polu code, komunikat pokazuj ludziom w logach, a request_id podawaj w zgłoszeniach.

Klucz testowy w przykładach

Wklej klucz sk_test_ z panelu (zakładka Deweloperzy), a każdy przykład będzie gotowy do uruchomienia. Klucz zostaje w tej karcie przeglądarki, nie wysyłamy go nigdzie.

Przykłady używają Twojego klucza testowego. Produkcyjnego klucza nie przyjmujemy.

Tryb testowy

Obiekt błędu#

PoleZnaczenie
type klasa błędu: invalid_request_error, authentication_error, idempotency_error, rate_limit_error, api_error
code stały kod do obsługi w kodzie integracji, z katalogu niżej
message komunikat po polsku, mówi co poprawić; może się zmieniać, nie porównuj go w kodzie
param nazwa pola żądania, którego dotyczy błąd (kropka dla pól zagnieżdżonych: customer.email), albo null
doc_url adres opisu kodu: https://oplac.pl/docs/bledy#<code>
request_id identyfikator żądania req_, ten sam co w nagłówku X-Request-Id
HTTP
HTTP/1.1 400 Bad Request
X-Request-Id: req_7mK2pQ9rT4vX1bN8cD3fG6hJ
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_missing",
    "message": "Podaj kwotę w groszach w polu amount, np. 12900 dla 129,00 zł.",
    "param": "amount",
    "doc_url": "https://oplac.pl/docs/bledy#parameter_missing",
    "request_id": "req_7mK2pQ9rT4vX1bN8cD3fG6hJ"
  }
}

Klasy błędów i kody HTTP#

invalid_request_error

HTTP
400, 402, 403, 404, 405, 422
Co oznacza i co zrobić
żądanie do poprawy albo stan obiektu nie pozwala na operację; popraw i wyślij ponownie, bez automatycznych powtórek

authentication_error

HTTP
401
Co oznacza i co zrobić
brak albo nieważny klucz; sprawdź nagłówek Authorization i tryb klucza

idempotency_error

HTTP
400, 409
Co oznacza i co zrobić
zły albo ponownie użyty Idempotency-Key, albo pierwsze żądanie z tym kluczem jeszcze trwa

rate_limit_error

HTTP
429
Co oznacza i co zrobić
limit zapytań; odczekaj Retry-After sekund i ponów

api_error

HTTP
500, 502
Co oznacza i co zrobić
błąd po stronie Oplac albo operatora płatności; ponów z tym samym Idempotency-Key, przy powtórce podaj request_id

Wzorzec obsługi w kodzie#

  1. 01Sprawdź kod HTTP. 2xx to sukces; wszystko inne ma obiekt error.
  2. 02Rozgałęź po error.code, nie po message. Nieznany kod traktuj według error.type.
  3. 03Błędy invalid_request_error i authentication_error to błędy programu albo konfiguracji: zaloguj request_id, code, param i nie ponawiaj automatycznie.
  4. 04rate_limit_error i api_error ponawiaj z odstępem (Retry-After albo wykładniczo) i tym samym Idempotency-Key. Te odpowiedzi nie są zapamiętywane w idempotencji, więc ponowienie wykona żądanie normalnie.
  5. 05idempotency_key_in_use (409) to wyścig dwóch równoległych żądań: odczekaj chwilę i ponów, dostaniesz wynik pierwszego.
# -f kończy curl błędem przy 4xx i 5xx, -s wycisza pasek postępu, -S pokazuje komunikat
curl -fsS https://oplac.pl/api/v1/payments \
  -H "Authorization: Bearer sk_test_TWOJ_KLUCZ" \
  -H "Content-Type: application/json" \
  -d '{"currency": "PLN"}'
$kod = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$dane = json_decode($odpowiedz, true);

if ($kod >= 400) {
    $blad = $dane['error'];
    match ($blad['code']) {
        'parameter_missing', 'parameter_invalid' => throw new InvalidArgumentException($blad['param'] . ': ' . $blad['message']),
        'rate_limited', 'api_error', 'provider_error' => ponowPozniej($blad['request_id']),
        'resource_missing' => null,   // obiekt nie istnieje w tym trybie
        default => throw new RuntimeException($blad['code'] . ' (' . $blad['request_id'] . ')'),
    };
}
const res = await fetch(url, opcje);
const dane = await res.json();

if (!res.ok) {
  const { code, message, param, request_id: requestId } = dane.error;
  switch (code) {
    case 'parameter_missing':
    case 'parameter_invalid':
      throw new Error(`${param}: ${message}`);
    case 'rate_limited':
    case 'api_error':
    case 'provider_error':
      return ponowPozniej(requestId);
    case 'resource_missing':
      return null; // obiekt nie istnieje w tym trybie
    default:
      throw new Error(`${code} (${requestId})`);
  }
}
res = requests.post(url, headers=headers, json=dane)
body = res.json()

if res.status_code >= 400:
    err = body["error"]
    if err["code"] in ("parameter_missing", "parameter_invalid"):
        raise ValueError(f"{err['param']}: {err['message']}")
    if err["code"] in ("rate_limited", "api_error", "provider_error"):
        ponow_pozniej(err["request_id"])
    elif err["code"] == "resource_missing":
        pass  # obiekt nie istnieje w tym trybie
    else:
        raise RuntimeError(f"{err['code']} ({err['request_id']})")

Błędy walidacji i pole param#

Przy złym żądaniu API zwraca pierwszy napotkany błąd z nazwą pola w param i komunikatem, jak go poprawić: parameter_missing (brak pola), parameter_invalid (zła wartość albo typ), parameter_unknown (pole, którego zasób nie przyjmuje), metadata_invalid, expand_invalid. Popraw pole i wyślij żądanie jeszcze raz; możesz użyć tego samego Idempotency-Key, bo odpowiedzi 400 nie są zapamiętywane.

Katalog kodów#

41 kodów w 5 klasach. Kod jest stały i to na nim opieraj obsługę w kodzie integracji; komunikat w polu message może się zmieniać. Pole doc_url każdej odpowiedzi prowadzi do wiersza poniżej.

invalid_request_error żądanie do poprawy

KodHTTPZnaczenie i co zrobić
parameter_missing 400 Brakuje wymaganego pola. Pole param mówi którego.
parameter_invalid 400 Pole ma złą wartość albo zły typ. Pole param mówi które, message jak poprawić.
parameter_unknown 400 Żądanie zawiera pole, którego ten zasób nie przyjmuje.
parameter_unsupported 400 Pole istnieje, ale nie jest obsługiwane w tym planie albo trybie.
metadata_invalid 400 Metadata to do 50 kluczy, klucz do 40 znaków, wartość tekstowa do 500 znaków.
expand_invalid 400 Pole w expand[] nie jest rozwijalne w tym zasobie.
api_version_invalid 400 Nagłówek Oplac-Version wskazuje nieznaną wersję API.
url_not_found 404 Nie ma takiej trasy API. Sprawdź ścieżkę i wersję (/v1).
method_not_allowed 405 Ta trasa nie obsługuje tej metody HTTP. Nagłówek Allow wymienia dozwolone.
resource_missing 404 Nie ma obiektu o tym identyfikatorze w tym koncie i trybie (sk_test_ widzi tylko obiekty testowe).
resource_deleted 400 Obiekt został usunięty i nie można go zmieniać.
module_not_in_plan 403 Moduł (Bill, Invoices) jest w wyższym planie konta.
currency_not_in_plan 403 Waluty EUR i USD są od planu Skala.
connect_not_in_plan 403 Podział płatności (Connect) jest w planie Platforma.
sandbox_limit_reached 403 Piaskownica demo mieści kilka linków testowych. Więcej po wyborze planu.
test_helpers_live_mode 403 Pomocnicy testowi działają wyłącznie z kluczem sk_test_.
provider_not_connected 402 Konto nie ma podpiętego dostawcy płatności. Podepnij go w panelu, w zakładce Dostawca.
payment_not_cancelable 422 Anulować można tylko płatność w statusie pending albo requires_confirmation.
payment_not_confirmable 422 Potwierdzić w piaskownicy można tylko płatność otwartą (pending, requires_confirmation).
payment_not_refundable 422 Zwrot dotyczy tylko płatności w statusie succeeded.
refund_exceeds_amount 422 Suma zwrotów przekroczyłaby kwotę płatności.
coupon_invalid 400 Kupon nie istnieje, jest wyłączony, wyczerpany albo ma inną walutę niż plan.
subscription_not_active 422 Operacja wymaga żywej subskrypcji (trialing, active, past_due).
currency_mismatch 400 Waluta nowego planu różni się od waluty subskrypcji.
connected_account_invalid 400 Konto sprzedawcy platformy nie należy do tego konta albo nie istnieje.
connected_account_not_ready 400 Sprzedawca platformy nie przeszedł jeszcze weryfikacji u dostawcy.
application_fee_invalid 400 Prowizja platformy musi być od 0 do kwoty płatności.
amount_too_large 400 Suma faktury przekracza 999 999 999,99.
seller_details_missing 400 Dane firmy sprzedawcy (nazwa, NIP, adres) są puste. Uzupełnij je w panelu, w Ustawieniach.
webhook_not_configured 400 Konto nie ma adresu webhooka trybu testowego. Zapisz go w panelu, w zakładce Deweloperzy.
product_inactive 422 Produkt jest wyłączony (active: false), więc nie można dla niego utworzyć strony sprzedaży.
checkout_page_inactive 422 Strona sprzedaży jest wyłączona albo jej produkt nie przyjmuje zakupów.
portal_disabled 400 Portal klienta jest wyłączony w panelu, więc sesji portalu nie da się utworzyć.

authentication_error klucz API

KodHTTPZnaczenie i co zrobić
api_key_invalid 401 Brak nagłówka Authorization albo klucz jest nieważny, odwołany lub konto nie ma aktywnego planu.

api_error błąd po stronie Oplac albo dostawcy

KodHTTPZnaczenie i co zrobić
provider_error 502 Dostawca płatności nie odpowiedział albo odrzucił operację. Ponów żądanie za chwilę.
api_error 500 Błąd po stronie Oplac. Ponów żądanie; jeśli się powtarza, podaj request_id w zgłoszeniu.

idempotency_error nagłówek Idempotency-Key

KodHTTPZnaczenie i co zrobić
idempotency_key_invalid 400 Nagłówek Idempotency-Key ma od 1 do 255 znaków.
idempotency_key_reused 400 Ten Idempotency-Key był już użyty z inną treścią albo na innej trasie. Nowy zamiar to nowy klucz.
idempotency_key_in_use 409 Żądanie z tym Idempotency-Key jest właśnie przetwarzane. Ponów za chwilę, dostaniesz jego wynik.

rate_limit_error limit zapytań

KodHTTPZnaczenie i co zrobić
rate_limited 429 Przekroczony limit zapytań konta. Odczekaj tyle sekund, ile podaje Retry-After.

Powiązane

Klucz testowy dostajesz od razu po zapisie

Adres e-mail, kod z maila i piaskownica z kodami BLIK. Produkcję włączasz sam w panelu: plan, dostawca płatności, klucz sk_live_. Wolisz, żeby wdrożenie w sklepie zrobił nasz zespół? To też jest za darmo.

Zamów integrację za darmo

BLIK, karty, subskrypcje i KSeF w jednym panelu.