Przejdź do treści
Oplac

Podstawy API

Stronicowanie

Każda lista wraca w tej samej kopercie z elementami od najnowszego i polem has_more. Kolejne strony pobierasz kursorem: starting_after z identyfikatorem ostatniego obiektu daje starsze, ending_before nowsze. Kursor jest stabilny nawet wtedy, gdy w międzyczasie dochodzą nowe obiekty, czego nie da się powiedzieć o numerach stron.

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

Koperta listy#

PoleZnaczenie
object zawsze list
url ścieżka listy, np. /v1/payments
has_more true, gdy w tym kierunku są kolejne obiekty
data tablica obiektów od najnowszego
JSON
{
  "object": "list",
  "url": "/v1/payments",
  "has_more": true,
  "data": [
    {"id": "pay_Cd34Ef56Gh78Ij", "object": "payment", "created": 1760000200},
    {"id": "pay_Bc23De45Fg67Hi", "object": "payment", "created": 1760000100},
    {"id": "pay_Ab12Cd34Ef56Gh", "object": "payment", "created": 1760000000}
  ]
}

Parametry stronicowania#

ParametrZnaczenie
limit liczba obiektów na stronie, od 1 do 100, domyślnie 10
starting_after identyfikator obiektu; zwraca starsze od niego (następna strona)
ending_before identyfikator obiektu; zwraca nowsze od niego (poprzednia strona); nie łączyć ze starting_after
created[gt], created[gte], created[lt], created[lte] filtr po chwili utworzenia (znacznik Unix)

Listy mają też filtry po polach zasobu: status, customer, payment_link, subscription, invoice dla płatności; payment dla zwrotów; email dla klientów; active dla planów i linków; type i delivered dla zdarzeń. Komplet jest przy każdej operacji listy w referencji.

Pobranie całej historii#

Pętla: pobierz stronę, zapamiętaj id ostatniego elementu, wyślij je jako starting_after, powtarzaj aż has_more będzie false. Przy regularnej synchronizacji zawęź zakres filtrem created[gte] z czasu ostatniego przebiegu.

curl "https://oplac.pl/api/v1/payments?limit=100&status=succeeded&created[gte]=1759276800" \
  -H "Authorization: Bearer sk_test_TWOJ_KLUCZ"

# następna strona: id ostatniego obiektu z poprzedniej
curl "https://oplac.pl/api/v1/payments?limit=100&status=succeeded&created[gte]=1759276800&starting_after=pay_Ab12Cd34Ef56Gh" \
  -H "Authorization: Bearer sk_test_TWOJ_KLUCZ"
function wszystkiePlatnosci(array $filtry): Generator
{
    $ostatni = null;
    do {
        $zapytanie = http_build_query($filtry + ['limit' => 100] + ($ostatni ? ['starting_after' => $ostatni] : []));
        $ch = curl_init('https://oplac.pl/api/v1/payments?' . $zapytanie);
        curl_setopt_array($ch, [
            CURLOPT_HTTPHEADER => ['Authorization: Bearer sk_test_TWOJ_KLUCZ'],
            CURLOPT_RETURNTRANSFER => true,
        ]);
        $strona = json_decode(curl_exec($ch), true);
        foreach ($strona['data'] as $p) {
            yield $p;
            $ostatni = $p['id'];
        }
    } while ($strona['has_more']);
}

foreach (wszystkiePlatnosci(['status' => 'succeeded', 'created[gte]' => 1759276800]) as $payment) {
    // ...
}
async function* wszystkiePlatnosci(filtry) {
  let ostatni = null;
  let strona;
  do {
    const q = new URLSearchParams({ ...filtry, limit: '100', ...(ostatni ? { starting_after: ostatni } : {}) });
    const res = await fetch(`https://oplac.pl/api/v1/payments?${q}`, {
      headers: { Authorization: 'Bearer sk_test_TWOJ_KLUCZ' },
    });
    strona = await res.json();
    for (const p of strona.data) {
      yield p;
      ostatni = p.id;
    }
  } while (strona.has_more);
}

for await (const payment of wszystkiePlatnosci({ status: 'succeeded', 'created[gte]': '1759276800' })) {
  // ...
}
import requests

def wszystkie_platnosci(**filtry):
    ostatni = None
    while True:
        params = {**filtry, "limit": 100}
        if ostatni:
            params["starting_after"] = ostatni
        strona = requests.get(
            "https://oplac.pl/api/v1/payments",
            headers={"Authorization": "Bearer sk_test_TWOJ_KLUCZ"},
            params=params,
        ).json()
        for p in strona["data"]:
            yield p
            ostatni = p["id"]
        if not strona["has_more"]:
            return

for payment in wszystkie_platnosci(status="succeeded", **{"created[gte]": 1759276800}):
    ...
Odpowiedź
HTTP/1.1 200 OK
{
  "object": "list",
  "url": "/v1/payments",
  "has_more": false,
  "data": [
    {
      "id": "pay_Ab12Cd34Ef56Gh",
      "object": "payment",
      "amount": 12900,
      "currency": "PLN",
      "status": "succeeded",
      "created": 1760000000
    }
  ]
}

Na co uważać#

  • starting_after i ending_before przyjmują identyfikator obiektu z tej samej listy. Identyfikator z innego trybu albo zasobu daje 400 parameter_invalid.
  • Kursor nie wymaga, żeby obiekt dalej istniał w wyniku filtrów; stronicowanie liczy się po chwili utworzenia i identyfikatorze.
  • Listy zdarzeń (GET /v1/events) stronicują się tak samo, z filtrami type i delivered; to wygodna droga do nadrobienia zdarzeń po awarii odbiorcy webhooków.
  • expand[] na liście działa na każdy element: expand[]=data.customer (samo customer też jest przyjmowane). Rozwinięte listy są cięższe, więc używaj mniejszego limit.

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.